Sfoglia il codice sorgente

share version strings between same versions (of different architectures)
to save some space and allow quick comparisions later on

David Kalnischkies 13 anni fa
parent
commit
885594fc88
4 ha cambiato i file con 42 aggiunte e 15 eliminazioni
  1. 4 8
      apt-pkg/deb/debversion.cc
  2. 31 6
      apt-pkg/pkgcachegen.cc
  3. 5 1
      apt-pkg/pkgcachegen.h
  4. 2 0
      debian/changelog

+ 4 - 8
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:

+ 31 - 6
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;
       }
    }

+ 5 - 1
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:

+ 2 - 0
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: