]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/pkgcachegen.cc
split-up Dependency struct
[apt.git] / apt-pkg / pkgcachegen.cc
index 9db4ef41f1dc154226ec11075adcb0cef74ea9ad..d5b2820070d5d8439eba661ecfcb57dff8efe25c 100644 (file)
@@ -54,7 +54,7 @@ using std::string;
 /* We set the dirty flag and make sure that is written to the disk */
 pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
                    Map(*pMap), Cache(pMap,false), Progress(Prog),
-                    CurrentRlsFile(NULL), CurrentFile(NULL), FoundFileDeps(0)
+                    CurrentRlsFile(NULL), CurrentFile(NULL), FoundFileDeps(0), d(NULL)
 {
    if (_error->PendingError() == true)
       return;
@@ -950,19 +950,75 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
    if (unlikely(Dependency == 0))
       return false;
 
-   // Fill it in
-   pkgCache::DepIterator Dep(Cache,Cache.DepP + Dependency);
-   Dynamic<pkgCache::DepIterator> DynDep(Dep);
-   Dep->ParentVer = Ver.Index();
-   Dep->Type = Type;
-   Dep->CompareOp = Op;
-   Dep->Version = Version;
-   Dep->ID = Cache.HeaderP->DependsCount++;
+   bool isDuplicate = false;
+   map_pointer_t DependencyData = 0;
+   map_pointer_t * PkgRevDepends = &Pkg->RevDepends;
+   map_pointer_t previous_id = 0;
 
-   // Link it to the package
-   Dep->Package = Pkg.Index();
-   Dep->NextRevDepends = Pkg->RevDepends;
-   Pkg->RevDepends = Dep.Index();
+   while (*PkgRevDepends != 0)
+   {
+      pkgCache::Dependency * const L = Cache.DepP + *PkgRevDepends;
+      PkgRevDepends = &L->NextRevDepends;
+      if (L->DependencyData == previous_id)
+        break;
+      previous_id = L->DependencyData;
+      pkgCache::DependencyData const * const D = Cache.DepDataP + previous_id;
+      if (D->Type == Type && D->CompareOp == Op && D->Version == Version)
+      {
+        DependencyData = previous_id;
+        isDuplicate = true;
+        break;
+      }
+   }
+
+   if (isDuplicate == false)
+   {
+      void const * const oldMap2 = Map.Data();
+      DependencyData = AllocateInMap(sizeof(pkgCache::DependencyData));
+      if (unlikely(DependencyData == 0))
+        return false;
+      if (oldMap2 != Map.Data())
+        PkgRevDepends += (map_pointer_t const * const) Map.Data() - (map_pointer_t const * const) oldMap2;
+   }
+
+   pkgCache::Dependency * Link = Cache.DepP + Dependency;
+   Link->ParentVer = Ver.Index();
+   Link->DependencyData = DependencyData;
+   Link->ID = Cache.HeaderP->DependsCount++;
+
+   pkgCache::DepIterator Dep(Cache, Link);
+   Dynamic<pkgCache::DepIterator> DynDep(Dep);
+   if (isDuplicate == false)
+   {
+      Dep->Type = Type;
+      Dep->CompareOp = Op;
+      Dep->Version = Version;
+      Dep->Package = Pkg.Index();
+      ++Cache.HeaderP->DependsDataCount;
+      Link->NextRevDepends = Pkg->RevDepends;
+      Pkg->RevDepends = Dependency;
+   }
+   else
+   {
+      // dependency data is already fine, we just set the reverse link
+      // and in such a way that the loop above can finish fast, so we keep
+      // non-duplicates at the front and for the duplicates we:
+      // a) move to the end of the list, b) insert before another own duplicate
+      // or c) find two duplicates behind each other.
+      map_pointer_t const own_id = Link->DependencyData;
+      while (*PkgRevDepends != 0)
+      {
+        pkgCache::Dependency * const L = Cache.DepP + *PkgRevDepends;
+        PkgRevDepends = &L->NextRevDepends;
+        if (L->DependencyData == own_id || L->DependencyData == previous_id)
+        {
+           Link->NextRevDepends = L->NextRevDepends;
+           break;
+        }
+        previous_id = L->DependencyData;
+      }
+      *PkgRevDepends = Dependency;
+   }
 
    // Do we know where to link the Dependency to?
    if (OldDepLast == NULL)
@@ -974,9 +1030,8 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
       OldDepLast += (map_pointer_t const * const) Map.Data() - (map_pointer_t const * const) oldMap;
 
    Dep->NextDepends = *OldDepLast;
-   *OldDepLast = Dep.Index();
+   *OldDepLast = Dependency;
    OldDepLast = &Dep->NextDepends;
-
    return true;
 }
                                                                        /*}}}*/
@@ -1113,6 +1168,7 @@ bool pkgCacheGenerator::SelectReleaseFile(const string &File,const string &Site,
    added versions. The caller is responsible for setting the IMS fields. */
 bool pkgCacheGenerator::SelectFile(std::string const &File,
                                   pkgIndexFile const &Index,
+                                  std::string const &Architecture,
                                   std::string const &Component,
                                   unsigned long const Flags)
 {
@@ -1133,6 +1189,15 @@ bool pkgCacheGenerator::SelectFile(std::string const &File,
    if (unlikely(idxIndexType == 0))
       return false;
    CurrentFile->IndexType = idxIndexType;
+   if (Architecture.empty())
+      CurrentFile->Architecture = 0;
+   else
+   {
+      map_stringitem_t const arch = StoreString(pkgCacheGenerator::MIXED, Architecture);
+      if (unlikely(arch == 0))
+        return false;
+      CurrentFile->Architecture = arch;
+   }
    map_stringitem_t const component = StoreString(pkgCacheGenerator::MIXED, Component);
    if (unlikely(component == 0))
       return false;
@@ -1710,3 +1775,6 @@ bool pkgCacheGenerator::FinishCache(OpProgress * /*Progress*/)
    return true;
 }
                                                                        /*}}}*/
+
+pkgCacheGenerator::ListParser::ListParser() : Owner(NULL), OldDepLast(NULL), FoundFileDeps(false), d(NULL) {}
+pkgCacheGenerator::ListParser::~ListParser() {}