#include <unistd.h>
#include <errno.h>
#include <stdio.h>
+
+#include <apt-pkg/deblistparser.h>
/*}}}*/
typedef vector<pkgIndexFile *>::iterator FileIterator;
-uint32_t hashlittle( const void *key, size_t length, uint32_t initval);
// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
// ---------------------------------------------------------------------
pkgCache::VerIterator *OutVer)
{
List.Owner = this;
+ debListParser *debian(dynamic_cast<debListParser *>(&List));
unsigned int Counter = 0;
+ step:
while (List.Step() == true)
{
// Get a pointer to the package structure
- string PackageName = List.Package();
+ srkString PackageName;
+ if (debian != NULL)
+ PackageName = debian->Find("Package");
+ else
+ PackageName = List.Package();
if (PackageName.empty() == true)
return false;
pkgCache::PkgIterator Pkg;
- if (NewPackage(Pkg,PackageName) == false)
- return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str());
+ if (NewPackage(Pkg,PackageName) == false) {
+ _error->Warning(_("Error occurred while processing %s (NewPackage)"),std::string(PackageName).c_str());
+ goto step;
+ }
+
Counter++;
if (Counter % 100 == 0 && Progress != 0)
Progress->Progress(List.Offset());
+ string language(List.DescriptionLanguage());
+
/* Get a pointer to the version structure. We know the list is sorted
so we use that fact in the search. Insertion of new versions is
done with correct sorting */
- string Version = List.Version();
+ srkString Version;
+ if (debian != NULL)
+ Version = debian->Find("Version");
+ else
+ Version = List.Version();
if (Version.empty() == true)
{
// we first process the package, then the descriptions
// (this has the bonus that we get MMap error when we run out
// of MMap space)
- if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false)
- return _error->Error(_("Error occurred while processing %s (UsePackage1)"),
- PackageName.c_str());
+ if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false) {
+ _error->Warning(_("Error occurred while processing %s (UsePackage1)"),
+ std::string(PackageName).c_str());
+ goto step;
+ }
// Find the right version to write the description
MD5SumValue CurMd5 = List.Description_md5();
// md5 && language
for ( ; Desc.end() == false; Desc++)
if (MD5SumValue(Desc.md5()) == CurMd5 &&
- Desc.LanguageCode() == List.DescriptionLanguage())
+ Desc.LanguageCode() == language)
duplicate=true;
if(duplicate)
continue;
if (MD5SumValue(Desc.md5()) == CurMd5)
{
// Add new description
- *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
+ *LastDesc = NewDescription(Desc, language, CurMd5, *LastDesc);
Desc->ParentPkg = Pkg.Index();
- if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
- return _error->Error(_("Error occurred while processing %s (NewFileDesc1)"),PackageName.c_str());
+ if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) {
+ _error->Warning(_("Error occurred while processing %s (NewFileDesc1)"),std::string(PackageName).c_str());
+ goto step;
+ }
break;
}
}
unsigned long Hash = List.VersionHash();
if (Res == 0 && Ver->Hash == Hash)
{
- if (List.UsePackage(Pkg,Ver) == false)
- return _error->Error(_("Error occurred while processing %s (UsePackage2)"),
- PackageName.c_str());
+ if (List.UsePackage(Pkg,Ver) == false) {
+ _error->Warning(_("Error occurred while processing %s (UsePackage2)"),
+ std::string(PackageName).c_str());
+ goto step;
+ }
- if (NewFileVer(Ver,List) == false)
- return _error->Error(_("Error occurred while processing %s (NewFileVer1)"),
- PackageName.c_str());
+ if (NewFileVer(Ver,List) == false) {
+ _error->Warning(_("Error occurred while processing %s (NewFileVer1)"),
+ std::string(PackageName).c_str());
+ goto step;
+ }
// Read only a single record and return
if (OutVer != 0)
Ver->ParentPkg = Pkg.Index();
Ver->Hash = Hash;
- if ((*LastVer == 0 && _error->PendingError()) || List.NewVersion(Ver) == false)
- return _error->Error(_("Error occurred while processing %s (NewVersion1)"),
- PackageName.c_str());
+ if ((*LastVer == 0 && _error->PendingError()) || List.NewVersion(Ver) == false) {
+ _error->Warning(_("Error occurred while processing %s (NewVersion1)"),
+ std::string(PackageName).c_str());
+ goto step;
+ }
- if (List.UsePackage(Pkg,Ver) == false)
- return _error->Error(_("Error occurred while processing %s (UsePackage3)"),
- PackageName.c_str());
+ if (List.UsePackage(Pkg,Ver) == false) {
+ _error->Warning(_("Error occurred while processing %s (UsePackage3)"),
+ std::string(PackageName).c_str());
+ goto step;
+ }
- if (NewFileVer(Ver,List) == false)
- return _error->Error(_("Error occurred while processing %s (NewVersion2)"),
- PackageName.c_str());
+ if (NewFileVer(Ver,List) == false) {
+ _error->Warning(_("Error occurred while processing %s (NewVersion2)"),
+ std::string(PackageName).c_str());
+ goto step;
+ }
// Read only a single record and return
if (OutVer != 0)
for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++);
// Add new description
- *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
+ *LastDesc = NewDescription(Desc, language, List.Description_md5(), *LastDesc);
Desc->ParentPkg = Pkg.Index();
- if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
- return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str());
+ if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) {
+ _error->Warning(_("Error occurred while processing %s (NewFileDesc2)"),std::string(PackageName).c_str());
+ goto step;
+ }
}
FoundFileDeps |= List.HasFileDeps();
// ---------------------------------------------------------------------
/* This creates a new package structure and adds it to the hash table */
bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name)
+{
+ return NewPackage(Pkg, srkString(Name));
+}
+
+bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const srkString &Name)
{
Pkg = Cache.FindPkg(Name);
if (Pkg.end() == false)
Cache.HeaderP->HashTable[Hash] = Package;
// Set the name and the ID
- Pkg->Name = Map.WriteString(Name);
+ Pkg->Name = Map.WriteString(Name.Start,Name.Size);
if (Pkg->Name == 0)
return false;
Pkg->ID = Cache.HeaderP->PackageCount++;
unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
const string &VerStr,
unsigned long Next)
+{
+ return NewVersion(Ver, srkString(VerStr), Next);
+}
+
+unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
+ const srkString &VerStr,
+ unsigned long Next)
{
// Get a structure
unsigned long Version = Map.Allocate(sizeof(pkgCache::Version));
Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version);
Ver->NextVer = Next;
Ver->ID = Cache.HeaderP->VersionCount++;
- Ver->VerStr = Map.WriteString(VerStr);
+ Ver->VerStr = Map.WriteString(VerStr.Start, VerStr.Size);
if (Ver->VerStr == 0)
return 0;
const string &Version,
unsigned int Op,
unsigned int Type)
+{
+ return NewDepends(Ver, srkString(PackageName), srkString(Version), Op, Type);
+}
+
+bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
+ const srkString &PackageName,
+ const srkString &Version,
+ unsigned int Op,
+ unsigned int Type)
{
pkgCache &Cache = Owner->Cache;
bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
const string &PackageName,
const string &Version)
+{
+ return NewProvides(Ver, srkString(PackageName), srkString(Version));
+}
+
+bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
+ const srkString &PackageName,
+ const srkString &Version)
{
pkgCache &Cache = Owner->Cache;
unsigned long pkgCacheGenerator::WriteUniqString(const char *S,
unsigned int Size)
{
- uint32_t hash = hashlittle(S, Size, 0xdeadbeef);
-
- /* We use a VERY LARGE INTRANSIENT hash table here, this speeds up generation
- by AN INSANE amount on ALL machines */
- pkgCache::StringItem **Bucket2;
- while (true) {
- Bucket2 = &UniqHash[hash % _count(UniqHash)];
- if (*Bucket2 == NULL)
- break;
- if (stringcmp(S,S+Size,Cache.StrP + (*Bucket2)->String) == 0)
- return (*Bucket2)->String;
- hash += 7;
- }
+ /* We use a very small transient hash table here, this speeds up generation
+ by a fair amount on slower machines */
+ pkgCache::StringItem *&Bucket = UniqHash[(S[0]*5 + S[1]) % _count(UniqHash)];
+ if (Bucket != 0 &&
+ stringcmp(S,S+Size,Cache.StrP + Bucket->String) == 0)
+ return Bucket->String;
- pkgCache::StringItem *&Bucket = *Bucket2;
+ // Search for an insertion point
pkgCache::StringItem *I = Cache.StringItemP + Cache.HeaderP->StringList;
+ int Res = 1;
map_ptrloc *Last = &Cache.HeaderP->StringList;
+ for (; I != Cache.StringItemP; Last = &I->NextItem,
+ I = Cache.StringItemP + I->NextItem)
+ {
+ Res = stringcmp(S,S+Size,Cache.StrP + I->String);
+ if (Res >= 0)
+ break;
+ }
+
+ // Match
+ if (Res == 0)
+ {
+ Bucket = I;
+ return I->String;
+ }
// Get a structure
unsigned long Item = Map.Allocate(sizeof(pkgCache::StringItem));