From aa0fe657e46b87cc692895a36df12e8b74bb27bb Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 3 Apr 2013 12:44:36 +0200 Subject: - sort group and package names in the hashtable on insert * apt-pkg/pkgcache.cc: - assume sorted hashtable entries for groups/packages --- apt-pkg/pkgcache.cc | 31 ++++++++++++++++++++----------- apt-pkg/pkgcachegen.cc | 16 +++++++++++----- debian/changelog | 3 +++ 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 1378876fe..879f34099 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -52,7 +52,7 @@ pkgCache::Header::Header() /* Whenever the structures change the major version should be bumped, whenever the generator changes the minor version should be bumped. */ MajorVersion = 8; - MinorVersion = 0; + MinorVersion = 1; Dirty = false; HeaderSz = sizeof(pkgCache::Header); @@ -182,18 +182,17 @@ unsigned long pkgCache::sHash(const string &Str) const { unsigned long Hash = 0; for (string::const_iterator I = Str.begin(); I != Str.end(); ++I) - Hash = 5*Hash + tolower_ascii(*I); + Hash = 41 * Hash + tolower_ascii(*I); return Hash % _count(HeaderP->PkgHashTable); } unsigned long pkgCache::sHash(const char *Str) const { - unsigned long Hash = 0; - for (const char *I = Str; *I != 0; ++I) - Hash = 5*Hash + tolower_ascii(*I); + unsigned long Hash = tolower_ascii(*Str); + for (const char *I = Str + 1; *I != 0; ++I) + Hash = 41 * Hash + tolower_ascii(*I); return Hash % _count(HeaderP->PkgHashTable); } - /*}}}*/ // Cache::SingleArchFindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- @@ -206,9 +205,14 @@ pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name) Package *Pkg = PkgP + HeaderP->PkgHashTable[Hash(Name)]; for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) { - if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && - stringcasecmp(Name,StrP + Pkg->Name) == 0) - return PkgIterator(*this,Pkg); + if (unlikely(Pkg->Name == 0)) + continue; + + int const cmp = strcasecmp(Name.c_str(), StrP + Pkg->Name); + if (cmp == 0) + return PkgIterator(*this, Pkg); + else if (cmp < 0) + break; } return PkgIterator(*this,0); } @@ -265,9 +269,14 @@ pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) { // Look at the hash bucket for the group Group *Grp = GrpP + HeaderP->GrpHashTable[sHash(Name)]; for (; Grp != GrpP; Grp = GrpP + Grp->Next) { - if (Grp->Name != 0 && StrP[Grp->Name] == Name[0] && - stringcasecmp(Name, StrP + Grp->Name) == 0) + if (unlikely(Grp->Name == 0)) + continue; + + int const cmp = strcasecmp(Name.c_str(), StrP + Grp->Name); + if (cmp == 0) return GrpIterator(*this, Grp); + else if (cmp < 0) + break; } return GrpIterator(*this,0); diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index b11ddcf9e..8437dc68f 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -595,8 +595,11 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) // Insert it into the hash table unsigned long const Hash = Cache.Hash(Name); - Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; - Cache.HeaderP->GrpHashTable[Hash] = Group; + map_ptrloc *insertAt = &Cache.HeaderP->GrpHashTable[Hash]; + while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0) + insertAt = &(Cache.GrpP + *insertAt)->Next; + Grp->Next = *insertAt; + *insertAt = Group; Grp->ID = Cache.HeaderP->GroupCount++; return true; @@ -625,11 +628,14 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name // Insert the package into our package list if (Grp->FirstPackage == 0) // the group is new { + Grp->FirstPackage = Package; // Insert it into the hash table unsigned long const Hash = Cache.Hash(Name); - Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash]; - Cache.HeaderP->PkgHashTable[Hash] = Package; - Grp->FirstPackage = Package; + map_ptrloc *insertAt = &Cache.HeaderP->PkgHashTable[Hash]; + while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.PkgP + *insertAt)->Name) > 0) + insertAt = &(Cache.PkgP + *insertAt)->NextPackage; + Pkg->NextPackage = *insertAt; + *insertAt = Package; } else // Group the Packages together { diff --git a/debian/changelog b/debian/changelog index d9183db98..d4f0e4bb3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,9 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low version strings e.g. for implicit multi-arch dependencies - equal comparisions are used mostly in same-source relations, so use this to try to reuse some version strings + - sort group and package names in the hashtable on insert + * apt-pkg/pkgcache.cc: + - assume sorted hashtable entries for groups/packages * apt-pkg/deb/debversion.cc: - add a string-equal shortcut for equal version comparisions -- cgit v1.2.3