summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2013-04-03 12:44:36 +0200
committerDavid Kalnischkies <kalnischkies@gmail.com>2013-04-03 12:44:36 +0200
commitaa0fe657e46b87cc692895a36df12e8b74bb27bb (patch)
tree121245993ef7b765471dd48fc80e5ae5269bed75
parentd9682cf8268d6c69e41adb6be9f03d68ba066a12 (diff)
downloadapt-aa0fe657e46b87cc692895a36df12e8b74bb27bb.tar.gz
- sort group and package names in the hashtable on insert
* apt-pkg/pkgcache.cc: - assume sorted hashtable entries for groups/packages
-rw-r--r--apt-pkg/pkgcache.cc31
-rw-r--r--apt-pkg/pkgcachegen.cc16
-rw-r--r--debian/changelog3
3 files changed, 34 insertions, 16 deletions
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 1378876f..879f3409 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 b11ddcf9..8437dc68 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 d9183db9..d4f0e4bb 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