summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2013-04-03 19:43:03 +0200
committerDavid Kalnischkies <kalnischkies@gmail.com>2013-04-03 19:43:03 +0200
commit885594fc8831d1be5a254557385e3dbefb564fbf (patch)
treeeb13cda9db652c8ddae0783354d4382bc3a20b35
parent887c6940d2afc9e3110f226e4d95fc72640e3ad6 (diff)
share version strings between same versions (of different architectures)
to save some space and allow quick comparisions later on
-rw-r--r--apt-pkg/deb/debversion.cc12
-rw-r--r--apt-pkg/pkgcachegen.cc37
-rw-r--r--apt-pkg/pkgcachegen.h6
-rw-r--r--debian/changelog2
4 files changed, 42 insertions, 15 deletions
diff --git a/apt-pkg/deb/debversion.cc b/apt-pkg/deb/debversion.cc
index 94d357846..140561262 100644
--- a/apt-pkg/deb/debversion.cc
+++ b/apt-pkg/deb/debversion.cc
@@ -217,16 +217,12 @@ bool debVersioningSystem::CheckDep(const char *PkgVer,
return false;
Op &= 0x0F;
- size_t const lenPkgVer = strlen(PkgVer);
- size_t const lenDepVer = strlen(DepVer);
-
- // take a shortcut for equals which are string-equal as well
- if (Op == pkgCache::Dep::Equals && lenPkgVer == lenDepVer &&
- memcmp(PkgVer, DepVer, lenPkgVer) == 0)
- return true;
+ // fast track for (equal) strings [by location] which are by definition equal versions
+ if (PkgVer == DepVer)
+ return Op == pkgCache::Dep::Equals || Op == pkgCache::Dep::LessEq || Op == pkgCache::Dep::GreaterEq;
// Perform the actual comparision.
- int const Res = DoCmpVersion(PkgVer, PkgVer + lenPkgVer, DepVer, DepVer + lenDepVer);
+ int const Res = CmpVersion(PkgVer, DepVer);
switch (Op)
{
case pkgCache::Dep::LessEq:
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 8437dc68f..3f10b6c40 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -390,7 +390,7 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
}
// Add a new version
- map_ptrloc const verindex = NewVersion(Ver,Version,*LastVer);
+ map_ptrloc const verindex = NewVersion(Ver, Version, Pkg.Index(), Hash, *LastVer);
if (verindex == 0 && _error->PendingError())
return _error->Error(_("Error occurred while processing %s (%s%d)"),
Pkg.Name(), "NewVersion", 1);
@@ -398,8 +398,6 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
if (oldMap != Map.Data())
LastVer += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
*LastVer = verindex;
- Ver->ParentPkg = Pkg.Index();
- Ver->Hash = Hash;
if (unlikely(List.NewVersion(Ver) == false))
return _error->Error(_("Error occurred while processing %s (%s%d)"),
@@ -557,7 +555,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List)
Dynamic<pkgCache::VerIterator> DynVer(Ver);
for (; Ver.end() == false; ++Ver)
{
- if (Ver->Hash == Hash && Version.c_str() == Ver.VerStr())
+ if (Ver->Hash == Hash && Version == Ver.VerStr())
{
if (List.CollectFileProvides(Cache,Ver) == false)
return _error->Error(_("Error occurred while processing %s (%s%d)"),
@@ -768,6 +766,8 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver,
/* This puts a version structure in the linked list */
unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
const string &VerStr,
+ map_ptrloc const ParentPkg,
+ unsigned long const Hash,
unsigned long Next)
{
// Get a structure
@@ -779,12 +779,37 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version);
//Dynamic<pkgCache::VerIterator> DynV(Ver); // caller MergeListVersion already takes care of it
Ver->NextVer = Next;
+ Ver->ParentPkg = ParentPkg;
+ Ver->Hash = Hash;
Ver->ID = Cache.HeaderP->VersionCount++;
+
+ // try to find the version string in the group for reuse
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ if (Pkg.end() == false && Grp.end() == false)
+ {
+ for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
+ {
+ if (Pkg == P)
+ continue;
+ for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
+ {
+ int const cmp = strcmp(V.VerStr(), VerStr.c_str());
+ if (cmp == 0)
+ {
+ Ver->VerStr = V->VerStr;
+ return Version;
+ }
+ else if (cmp < 0)
+ break;
+ }
+ }
+ }
+ // haven't found the version string, so create
map_ptrloc const idxVerStr = WriteStringInMap(VerStr);
if (unlikely(idxVerStr == 0))
return 0;
Ver->VerStr = idxVerStr;
-
return Version;
}
/*}}}*/
@@ -881,7 +906,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
index = WriteStringInMap(Version);
if (unlikely(index == 0))
return false;
- if (oldMap != Map.Data())
+ if (OldDepLast != 0 && oldMap != Map.Data())
OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
}
}
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index e759cbd3e..428e8459b 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -80,7 +80,11 @@ class pkgCacheGenerator /*{{{*/
bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver,
map_ptrloc const Version, unsigned int const &Op,
unsigned int const &Type, map_ptrloc* &OldDepLast);
- unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,unsigned long Next);
+ __deprecated unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,unsigned long Next)
+ { return NewVersion(Ver, VerStr, 0, 0, Next); }
+ unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,
+ map_ptrloc const ParentPkg, unsigned long const Hash,
+ unsigned long Next);
map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const std::string &Lang,const MD5SumValue &md5sum,map_ptrloc Next);
public:
diff --git a/debian/changelog b/debian/changelog
index 7070c5fc9..9fce4b14e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,6 +11,8 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low
- 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
+ - share version strings between same versions (of different architectures)
+ to save some space and allow quick comparisions later on
* apt-pkg/pkgcache.cc:
- assume sorted hashtable entries for groups/packages
* apt-pkg/cacheiterators.h: