Просмотр исходного кода

guard pkg/grp hashtable creation changes

The change itself is no problem ABI wise, but the remove of the old
undynamic hashtables is, so we bring it back for older abis and happily
use the now available free space to backport more recent additions like
the dynamic hashtable itself.

Git-Dch: Ignore
David Kalnischkies лет назад: 11
Родитель
Сommit
32ab4bd05c
4 измененных файлов с 118 добавлено и 45 удалено
  1. 22 17
      apt-pkg/pkgcache.cc
  2. 79 14
      apt-pkg/pkgcache.h
  3. 9 9
      apt-pkg/pkgcachegen.cc
  4. 8 5
      cmdline/apt-cache.cc

+ 22 - 17
apt-pkg/pkgcache.cc

@@ -82,10 +82,13 @@ pkgCache::Header::Header()
    MaxDescFileSize = 0;
    MaxDescFileSize = 0;
    
    
    FileList = 0;
    FileList = 0;
+#if APT_PKG_ABI < 413
+   APT_IGNORE_DEPRECATED(StringList = 0;)
+#endif
    VerSysName = 0;
    VerSysName = 0;
    Architecture = 0;
    Architecture = 0;
-   Architectures = 0;
-   HashTableSize = _config->FindI("APT::Cache-HashTableSize", 10 * 1048);
+   SetArchitectures(0);
+   SetHashTableSize(_config->FindI("APT::Cache-HashTableSize", 10 * 1048));
    memset(Pools,0,sizeof(Pools));
    memset(Pools,0,sizeof(Pools));
 
 
    CacheFileSize = 0;
    CacheFileSize = 0;
@@ -114,6 +117,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const
 // Cache::pkgCache - Constructor					/*{{{*/
 // Cache::pkgCache - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
+APT_IGNORE_DEPRECATED_PUSH
 pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
 pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
 {
 {
    // call getArchitectures() with cached=false to ensure that the 
    // call getArchitectures() with cached=false to ensure that the 
@@ -123,6 +127,7 @@ pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
    if (DoMap == true)
    if (DoMap == true)
       ReMap();
       ReMap();
 }
 }
+APT_IGNORE_DEPRECATED_POP
 									/*}}}*/
 									/*}}}*/
 // Cache::ReMap - Reopen the cache file					/*{{{*/
 // Cache::ReMap - Reopen the cache file					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -162,7 +167,7 @@ bool pkgCache::ReMap(bool const &Errorchecks)
    if (Map.Size() < HeaderP->CacheFileSize)
    if (Map.Size() < HeaderP->CacheFileSize)
       return _error->Error(_("The package cache file is corrupted, it is too small"));
       return _error->Error(_("The package cache file is corrupted, it is too small"));
 
 
-   if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->Architectures == 0)
+   if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->GetArchitectures() == 0)
       return _error->Error(_("The package cache file is corrupted"));
       return _error->Error(_("The package cache file is corrupted"));
 
 
    // Locate our VS..
    // Locate our VS..
@@ -176,8 +181,8 @@ bool pkgCache::ReMap(bool const &Errorchecks)
    for (++a; a != archs.end(); ++a)
    for (++a; a != archs.end(); ++a)
       list.append(",").append(*a);
       list.append(",").append(*a);
    if (_config->Find("APT::Architecture") != StrP + HeaderP->Architecture ||
    if (_config->Find("APT::Architecture") != StrP + HeaderP->Architecture ||
-	 list != StrP + HeaderP->Architectures)
-      return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->Architectures, list.c_str());
+	 list != StrP + HeaderP->GetArchitectures())
+      return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->GetArchitectures(), list.c_str());
 
 
    return true;
    return true;
 }
 }
@@ -192,7 +197,7 @@ map_id_t pkgCache::sHash(const string &Str) const
    unsigned long Hash = 0;
    unsigned long Hash = 0;
    for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
    for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
       Hash = 41 * Hash + tolower_ascii(*I);
       Hash = 41 * Hash + tolower_ascii(*I);
-   return Hash % HeaderP->HashTableSize;
+   return Hash % HeaderP->GetHashTableSize();
 }
 }
 
 
 map_id_t pkgCache::sHash(const char *Str) const
 map_id_t pkgCache::sHash(const char *Str) const
@@ -200,7 +205,7 @@ map_id_t pkgCache::sHash(const char *Str) const
    unsigned long Hash = tolower_ascii(*Str);
    unsigned long Hash = tolower_ascii(*Str);
    for (const char *I = Str + 1; *I != 0; ++I)
    for (const char *I = Str + 1; *I != 0; ++I)
       Hash = 41 * Hash + tolower_ascii(*I);
       Hash = 41 * Hash + tolower_ascii(*I);
-   return Hash % HeaderP->HashTableSize;
+   return Hash % HeaderP->GetHashTableSize();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Cache::SingleArchFindPkg - Locate a package by name			/*{{{*/
 // Cache::SingleArchFindPkg - Locate a package by name			/*{{{*/
@@ -211,8 +216,8 @@ map_id_t pkgCache::sHash(const char *Str) const
 pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
 pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
 {
 {
    // Look at the hash bucket
    // Look at the hash bucket
-   Package *Pkg = PkgP + HeaderP->PkgHashTable()[Hash(Name)];
-   for (; Pkg != PkgP; Pkg = PkgP + Pkg->Next)
+   Package *Pkg = PkgP + HeaderP->PkgHashTableP()[Hash(Name)];
+   for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
    {
    {
       int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name);
       int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name);
       if (cmp == 0)
       if (cmp == 0)
@@ -273,7 +278,7 @@ pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) {
 		return GrpIterator(*this,0);
 		return GrpIterator(*this,0);
 
 
 	// Look at the hash bucket for the group
 	// Look at the hash bucket for the group
-	Group *Grp = GrpP + HeaderP->GrpHashTable()[sHash(Name)];
+	Group *Grp = GrpP + HeaderP->GrpHashTableP()[sHash(Name)];
 	for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
 	for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
 		int const cmp = strcmp(Name.c_str(), StrP + Grp->Name);
 		int const cmp = strcmp(Name.c_str(), StrP + Grp->Name);
 		if (cmp == 0)
 		if (cmp == 0)
@@ -359,7 +364,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
 
 
 	// Iterate over the list to find the matching arch
 	// Iterate over the list to find the matching arch
 	for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
 	for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
-	     Pkg = Owner->PkgP + Pkg->Next) {
+	     Pkg = Owner->PkgP + Pkg->NextPackage) {
 		if (stringcmp(Arch, Owner->StrP + Pkg->Arch) == 0)
 		if (stringcmp(Arch, Owner->StrP + Pkg->Arch) == 0)
 			return PkgIterator(*Owner, Pkg);
 			return PkgIterator(*Owner, Pkg);
 		if ((Owner->PkgP + S->LastPackage) == Pkg)
 		if ((Owner->PkgP + S->LastPackage) == Pkg)
@@ -407,7 +412,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const
 	if (S->LastPackage == LastPkg.Index())
 	if (S->LastPackage == LastPkg.Index())
 		return PkgIterator(*Owner, 0);
 		return PkgIterator(*Owner, 0);
 
 
-	return PkgIterator(*Owner, Owner->PkgP + LastPkg->Next);
+	return PkgIterator(*Owner, Owner->PkgP + LastPkg->NextPackage);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // GrpIterator::operator ++ - Postfix incr				/*{{{*/
 // GrpIterator::operator ++ - Postfix incr				/*{{{*/
@@ -420,10 +425,10 @@ void pkgCache::GrpIterator::operator ++(int)
       S = Owner->GrpP + S->Next;
       S = Owner->GrpP + S->Next;
 
 
    // Follow the hash table
    // Follow the hash table
-   while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize)
+   while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->GetHashTableSize())
    {
    {
       HashIndex++;
       HashIndex++;
-      S = Owner->GrpP + Owner->HeaderP->GrpHashTable()[HashIndex];
+      S = Owner->GrpP + Owner->HeaderP->GrpHashTableP()[HashIndex];
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -434,13 +439,13 @@ void pkgCache::PkgIterator::operator ++(int)
 {
 {
    // Follow the current links
    // Follow the current links
    if (S != Owner->PkgP)
    if (S != Owner->PkgP)
-      S = Owner->PkgP + S->Next;
+      S = Owner->PkgP + S->NextPackage;
 
 
    // Follow the hash table
    // Follow the hash table
-   while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize)
+   while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->GetHashTableSize())
    {
    {
       HashIndex++;
       HashIndex++;
-      S = Owner->PkgP + Owner->HeaderP->PkgHashTable()[HashIndex];
+      S = Owner->PkgP + Owner->HeaderP->PkgHashTableP()[HashIndex];
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 79 - 14
apt-pkg/pkgcache.h

@@ -85,16 +85,45 @@
 using std::string;
 using std::string;
 #endif
 #endif
 
 
+#if APT_PKG_ABI >= 413
 // storing file sizes of indexes, which are way below 4 GB for now
 // storing file sizes of indexes, which are way below 4 GB for now
 typedef uint32_t map_filesize_t;
 typedef uint32_t map_filesize_t;
+typedef map_filesize_t should_be_map_filesize_t;
+#else
+typedef unsigned long map_filesize_t;
+typedef unsigned int should_be_map_filesize_t;
+#endif
+#if APT_PKG_ABI >= 413
 // each package/group/dependency gets an id
 // each package/group/dependency gets an id
 typedef uint32_t map_id_t;
 typedef uint32_t map_id_t;
+typedef map_id_t should_be_map_id_t;
+#else
+typedef unsigned long map_id_t;
+typedef unsigned int should_be_map_id_t;
+#endif
+#if APT_PKG_ABI >= 413
 // some files get an id, too, but in far less absolute numbers
 // some files get an id, too, but in far less absolute numbers
 typedef uint16_t map_fileid_t;
 typedef uint16_t map_fileid_t;
+typedef map_fileid_t should_be_map_fileid_t;
+#else
+typedef unsigned long map_fileid_t;
+typedef unsigned int should_be_map_fileid_t;
+#endif
+#if APT_PKG_ABI >= 413
 // relative pointer from cache start
 // relative pointer from cache start
 typedef uint32_t map_pointer_t;
 typedef uint32_t map_pointer_t;
+#else
+typedef unsigned int map_pointer_t;
+#endif
 // same as the previous, but documented to be to a string item
 // same as the previous, but documented to be to a string item
 typedef map_pointer_t map_stringitem_t;
 typedef map_pointer_t map_stringitem_t;
+#if APT_PKG_ABI >= 413
+typedef uint64_t should_be_uint64_t;
+typedef uint64_t should_be_uint64_small_t;
+#else
+typedef unsigned long long should_be_uint64_t;
+typedef unsigned long should_be_uint64_small_t;
+#endif
 
 
 class pkgVersioningSystem;
 class pkgVersioningSystem;
 class pkgCache								/*{{{*/
 class pkgCache								/*{{{*/
@@ -109,6 +138,7 @@ class pkgCache								/*{{{*/
    struct Description;
    struct Description;
    struct Provides;
    struct Provides;
    struct Dependency;
    struct Dependency;
+   struct StringItem;
    struct VerFile;
    struct VerFile;
    struct DescFile;
    struct DescFile;
    
    
@@ -185,6 +215,7 @@ class pkgCache								/*{{{*/
    Description *DescP;
    Description *DescP;
    Provides *ProvideP;
    Provides *ProvideP;
    Dependency *DepP;
    Dependency *DepP;
+   APT_DEPRECATED StringItem *StringItemP;
    char *StrP;
    char *StrP;
 
 
    virtual bool ReMap(bool const &Errorchecks = true);
    virtual bool ReMap(bool const &Errorchecks = true);
@@ -288,12 +319,17 @@ struct pkgCache::Header
        The PackageFile structures are singly linked lists that represent
        The PackageFile structures are singly linked lists that represent
        all package files that have been merged into the cache. */
        all package files that have been merged into the cache. */
    map_pointer_t FileList;
    map_pointer_t FileList;
+#if APT_PKG_ABI < 413
+   APT_DEPRECATED map_pointer_t StringList;
+#endif
    /** \brief String representing the version system used */
    /** \brief String representing the version system used */
    map_pointer_t VerSysName;
    map_pointer_t VerSysName;
    /** \brief native architecture the cache was built against */
    /** \brief native architecture the cache was built against */
    map_pointer_t Architecture;
    map_pointer_t Architecture;
+#if APT_PKG_ABI >= 413
    /** \brief all architectures the cache was built against */
    /** \brief all architectures the cache was built against */
    map_pointer_t Architectures;
    map_pointer_t Architectures;
+#endif
    /** \brief The maximum size of a raw entry from the original Package file */
    /** \brief The maximum size of a raw entry from the original Package file */
    map_filesize_t MaxVerFileSize;
    map_filesize_t MaxVerFileSize;
    /** \brief The maximum size of a raw entry from the original Translation file */
    /** \brief The maximum size of a raw entry from the original Translation file */
@@ -319,12 +355,26 @@ struct pkgCache::Header
        In the PkgHashTable is it possible that multiple packages have the same name -
        In the PkgHashTable is it possible that multiple packages have the same name -
        these packages are stored as a sequence in the list.
        these packages are stored as a sequence in the list.
        The size of both tables is the same. */
        The size of both tables is the same. */
+#if APT_PKG_ABI >= 413
    unsigned int HashTableSize;
    unsigned int HashTableSize;
-   map_pointer_t * PkgHashTable() const { return (map_pointer_t*) (this + 1); }
-   map_pointer_t * GrpHashTable() const { return PkgHashTable() + HashTableSize; }
+   unsigned int GetHashTableSize() const { return HashTableSize; }
+   void SetHashTableSize(unsigned int const sz) { HashTableSize = sz; }
+   map_pointer_t GetArchitectures() const { return Architectures; }
+   void SetArchitectures(map_pointer_t const idx) { Architectures = idx; }
+#else
+   // BEWARE: these tables are pretty much empty and just here for abi compat
+   map_ptrloc PkgHashTable[2*1048];
+   map_ptrloc GrpHashTable[2*1048];
+   unsigned int GetHashTableSize() const { return PkgHashTable[0]; }
+   void SetHashTableSize(unsigned int const sz) { PkgHashTable[0] = sz; }
+   map_pointer_t GetArchitectures() const { return PkgHashTable[1]; }
+   void SetArchitectures(map_pointer_t const idx) { PkgHashTable[1] = idx; }
+#endif
+   map_pointer_t * PkgHashTableP() const { return (map_pointer_t*) (this + 1); }
+   map_pointer_t * GrpHashTableP() const { return PkgHashTableP() + GetHashTableSize(); }
 
 
    /** \brief Size of the complete cache file */
    /** \brief Size of the complete cache file */
-   unsigned long long CacheFileSize;
+   should_be_uint64_small_t CacheFileSize;
 
 
    bool CheckSizes(Header &Against) const APT_PURE;
    bool CheckSizes(Header &Against) const APT_PURE;
    Header();
    Header();
@@ -350,7 +400,7 @@ struct pkgCache::Group
    /** \brief Link to the next Group */
    /** \brief Link to the next Group */
    map_pointer_t Next;		// Group
    map_pointer_t Next;		// Group
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
 
 
 };
 };
 									/*}}}*/
 									/*}}}*/
@@ -387,12 +437,18 @@ struct pkgCache::Package
    map_pointer_t VersionList;       // Version
    map_pointer_t VersionList;       // Version
    /** \brief index to the installed version */
    /** \brief index to the installed version */
    map_pointer_t CurrentVer;        // Version
    map_pointer_t CurrentVer;        // Version
+   /** \brief indicates nothing (consistently)
+       This field used to contain ONE section the package belongs to,
+       if those differs between versions it is a RANDOM one.
+       The Section() method tries to reproduce it, but the only sane
+       thing to do is use the Section field from the version! */
+   APT_DEPRECATED map_ptrloc Section; // StringItem
    /** \brief index of the group this package belongs to */
    /** \brief index of the group this package belongs to */
    map_pointer_t Group;             // Group the Package belongs to
    map_pointer_t Group;             // Group the Package belongs to
 
 
    // Linked list
    // Linked list
    /** \brief Link to the next package in the same bucket */
    /** \brief Link to the next package in the same bucket */
-   map_pointer_t Next;       // Package
+   map_pointer_t NextPackage;       // Package
    /** \brief List of all dependencies on this package */
    /** \brief List of all dependencies on this package */
    map_pointer_t RevDepends;        // Dependency
    map_pointer_t RevDepends;        // Dependency
    /** \brief List of all "packages" this package provide */
    /** \brief List of all "packages" this package provide */
@@ -416,7 +472,7 @@ struct pkgCache::Package
        This allows clients to create an array of size PackageCount and use it to store
        This allows clients to create an array of size PackageCount and use it to store
        state information for the package map. For instance the status file emitter uses
        state information for the package map. For instance the status file emitter uses
        this to track which packages have been emitted already. */
        this to track which packages have been emitted already. */
-   map_id_t ID;
+   should_be_map_id_t ID;
    /** \brief some useful indicators of the package's state */
    /** \brief some useful indicators of the package's state */
    unsigned long Flags;
    unsigned long Flags;
 };
 };
@@ -464,7 +520,7 @@ struct pkgCache::PackageFile
    /** \brief Link to the next PackageFile in the Cache */
    /** \brief Link to the next PackageFile in the Cache */
    map_pointer_t NextFile;        // PackageFile
    map_pointer_t NextFile;        // PackageFile
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_fileid_t ID;
+   should_be_map_fileid_t ID;
 };
 };
 									/*}}}*/
 									/*}}}*/
 // VerFile structure							/*{{{*/
 // VerFile structure							/*{{{*/
@@ -479,7 +535,7 @@ struct pkgCache::VerFile
    /** \brief next step in the linked list */
    /** \brief next step in the linked list */
    map_pointer_t NextFile;       // PkgVerFile
    map_pointer_t NextFile;       // PkgVerFile
    /** \brief position in the package file */
    /** \brief position in the package file */
-   map_filesize_t Offset;         // File offset
+   should_be_map_filesize_t Offset;         // File offset
    /** @TODO document pkgCache::VerFile::Size */
    /** @TODO document pkgCache::VerFile::Size */
    map_filesize_t Size;
    map_filesize_t Size;
 };
 };
@@ -493,7 +549,7 @@ struct pkgCache::DescFile
    /** \brief next step in the linked list */
    /** \brief next step in the linked list */
    map_pointer_t NextFile;       // PkgVerFile
    map_pointer_t NextFile;       // PkgVerFile
    /** \brief position in the file */
    /** \brief position in the file */
-   map_filesize_t Offset;         // File offset
+   should_be_map_filesize_t Offset;         // File offset
    /** @TODO document pkgCache::DescFile::Size */
    /** @TODO document pkgCache::DescFile::Size */
    map_filesize_t Size;
    map_filesize_t Size;
 };
 };
@@ -556,16 +612,16 @@ struct pkgCache::Version
    /** \brief archive size for this version
    /** \brief archive size for this version
 
 
        For Debian this is the size of the .deb file. */
        For Debian this is the size of the .deb file. */
-   uint64_t Size; // These are the .deb size
+   should_be_uint64_t Size; // These are the .deb size
    /** \brief uncompressed size for this version */
    /** \brief uncompressed size for this version */
-   uint64_t InstalledSize;
+   should_be_uint64_t InstalledSize;
    /** \brief characteristic value representing this version
    /** \brief characteristic value representing this version
 
 
        No two packages in existence should have the same VerStr
        No two packages in existence should have the same VerStr
        and Hash with different contents. */
        and Hash with different contents. */
    unsigned short Hash;
    unsigned short Hash;
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
    /** \brief parsed priority value */
    /** \brief parsed priority value */
    unsigned char Priority;
    unsigned char Priority;
 };
 };
@@ -593,7 +649,7 @@ struct pkgCache::Description
    map_pointer_t ParentPkg;         // Package
    map_pointer_t ParentPkg;         // Package
 
 
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
 };
 };
 									/*}}}*/
 									/*}}}*/
 // Dependency structure							/*{{{*/
 // Dependency structure							/*{{{*/
@@ -620,7 +676,7 @@ struct pkgCache::Dependency
    map_pointer_t ParentVer;       // Version
    map_pointer_t ParentVer;       // Version
 
 
    /** \brief unique sequel ID */
    /** \brief unique sequel ID */
-   map_id_t ID;
+   should_be_map_id_t ID;
    /** \brief Dependency type - Depends, Recommends, Conflicts, etc */
    /** \brief Dependency type - Depends, Recommends, Conflicts, etc */
    unsigned char Type;
    unsigned char Type;
    /** \brief comparison operator specified on the depends line
    /** \brief comparison operator specified on the depends line
@@ -656,6 +712,15 @@ struct pkgCache::Provides
    map_pointer_t NextPkgProv;      // Provides
    map_pointer_t NextPkgProv;      // Provides
 };
 };
 									/*}}}*/
 									/*}}}*/
+// UNUSED StringItem structure						/*{{{*/
+struct APT_DEPRECATED  pkgCache::StringItem
+{
+   /** \brief string this refers to */
+   map_ptrloc String;        // StringItem
+   /** \brief Next link in the chain */
+   map_ptrloc NextItem;      // StringItem
+};
+									/*}}}*/
 
 
 inline char const * pkgCache::NativeArch()
 inline char const * pkgCache::NativeArch()
 	{ return StrP + HeaderP->Architecture; }
 	{ return StrP + HeaderP->Architecture; }

+ 9 - 9
apt-pkg/pkgcachegen.cc

@@ -74,7 +74,7 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
       *Cache.HeaderP = pkgCache::Header();
       *Cache.HeaderP = pkgCache::Header();
 
 
       // make room for the hashtables for packages and groups
       // make room for the hashtables for packages and groups
-      if (Map.RawAllocate(2 * (Cache.HeaderP->HashTableSize * sizeof(map_pointer_t))) == 0)
+      if (Map.RawAllocate(2 * (Cache.HeaderP->GetHashTableSize() * sizeof(map_pointer_t))) == 0)
 	 return;
 	 return;
 
 
       map_stringitem_t const idxVerSysName = WriteStringInMap(_system->VS->Label);
       map_stringitem_t const idxVerSysName = WriteStringInMap(_system->VS->Label);
@@ -96,10 +96,10 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
 	 map_stringitem_t const idxArchitectures = WriteStringInMap(list);
 	 map_stringitem_t const idxArchitectures = WriteStringInMap(list);
 	 if (unlikely(idxArchitectures == 0))
 	 if (unlikely(idxArchitectures == 0))
 	    return;
 	    return;
-	 Cache.HeaderP->Architectures = idxArchitectures;
+	 Cache.HeaderP->SetArchitectures(idxArchitectures);
       }
       }
       else
       else
-	 Cache.HeaderP->Architectures = idxArchitecture;
+	 Cache.HeaderP->SetArchitectures(idxArchitecture);
 
 
       Cache.ReMap();
       Cache.ReMap();
    }
    }
@@ -616,7 +616,7 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name)
 
 
    // Insert it into the hash table
    // Insert it into the hash table
    unsigned long const Hash = Cache.Hash(Name);
    unsigned long const Hash = Cache.Hash(Name);
-   map_pointer_t *insertAt = &Cache.HeaderP->GrpHashTable()[Hash];
+   map_pointer_t *insertAt = &Cache.HeaderP->GrpHashTableP()[Hash];
    while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
    while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
       insertAt = &(Cache.GrpP + *insertAt)->Next;
       insertAt = &(Cache.GrpP + *insertAt)->Next;
    Grp->Next = *insertAt;
    Grp->Next = *insertAt;
@@ -652,18 +652,18 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
       Grp->FirstPackage = Package;
       Grp->FirstPackage = Package;
       // Insert it into the hash table
       // Insert it into the hash table
       map_id_t const Hash = Cache.Hash(Name);
       map_id_t const Hash = Cache.Hash(Name);
-      map_pointer_t *insertAt = &Cache.HeaderP->PkgHashTable()[Hash];
+      map_pointer_t *insertAt = &Cache.HeaderP->PkgHashTableP()[Hash];
       while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + (Cache.PkgP + *insertAt)->Group)->Name) > 0)
       while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + (Cache.PkgP + *insertAt)->Group)->Name) > 0)
-	 insertAt = &(Cache.PkgP + *insertAt)->Next;
-      Pkg->Next = *insertAt;
+	 insertAt = &(Cache.PkgP + *insertAt)->NextPackage;
+      Pkg->NextPackage = *insertAt;
       *insertAt = Package;
       *insertAt = Package;
    }
    }
    else // Group the Packages together
    else // Group the Packages together
    {
    {
       // this package is the new last package
       // this package is the new last package
       pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
       pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
-      Pkg->Next = LastPkg->Next;
-      LastPkg->Next = Package;
+      Pkg->NextPackage = LastPkg->NextPackage;
+      LastPkg->NextPackage = Package;
    }
    }
    Grp->LastPackage = Package;
    Grp->LastPackage = Package;
 
 

+ 8 - 5
cmdline/apt-cache.cc

@@ -267,11 +267,14 @@ static bool DumpPackage(CommandLine &CmdL)
 // ShowHashTableStats - Show stats about a hashtable			/*{{{*/
 // ShowHashTableStats - Show stats about a hashtable			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
+static map_pointer_t PackageNext(pkgCache::Package const * const P) { return P->NextPackage; }
+static map_pointer_t GroupNext(pkgCache::Group const * const G) { return G->Next; }
 template<class T>
 template<class T>
 static void ShowHashTableStats(std::string Type,
 static void ShowHashTableStats(std::string Type,
                                T *StartP,
                                T *StartP,
                                map_pointer_t *Hashtable,
                                map_pointer_t *Hashtable,
-                               unsigned long Size)
+                               unsigned long Size,
+			       map_pointer_t(*Next)(T const * const))
 {
 {
    // hashtable stats for the HashTable
    // hashtable stats for the HashTable
    unsigned long NumBuckets = Size;
    unsigned long NumBuckets = Size;
@@ -290,7 +293,7 @@ static void ShowHashTableStats(std::string Type,
       }
       }
       ++UsedBuckets;
       ++UsedBuckets;
       unsigned long ThisBucketSize = 0;
       unsigned long ThisBucketSize = 0;
-      for (; P != StartP; P = StartP + P->Next)
+      for (; P != StartP; P = StartP + Next(P))
          ++ThisBucketSize;
          ++ThisBucketSize;
       Entries += ThisBucketSize;
       Entries += ThisBucketSize;
       LongestBucket = std::max(ThisBucketSize, LongestBucket);
       LongestBucket = std::max(ThisBucketSize, LongestBucket);
@@ -447,13 +450,13 @@ static bool Stats(CommandLine &)
       APT_CACHESIZE(VerFileCount, VerFileSz) +
       APT_CACHESIZE(VerFileCount, VerFileSz) +
       APT_CACHESIZE(DescFileCount, DescFileSz) +
       APT_CACHESIZE(DescFileCount, DescFileSz) +
       APT_CACHESIZE(ProvidesCount, ProvidesSz) +
       APT_CACHESIZE(ProvidesCount, ProvidesSz) +
-      (2 * Cache->Head().HashTableSize * sizeof(map_id_t));
+      (2 * Cache->Head().GetHashTableSize() * sizeof(map_id_t));
    cout << _("Total space accounted for: ") << SizeToStr(Total) << endl;
    cout << _("Total space accounted for: ") << SizeToStr(Total) << endl;
 #undef APT_CACHESIZE
 #undef APT_CACHESIZE
 
 
    // hashtable stats
    // hashtable stats
-   ShowHashTableStats<pkgCache::Package>("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTable(), Cache->Head().HashTableSize);
-   ShowHashTableStats<pkgCache::Group>("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTable(), Cache->Head().HashTableSize);
+   ShowHashTableStats<pkgCache::Package>("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTableP(), Cache->Head().GetHashTableSize(), PackageNext);
+   ShowHashTableStats<pkgCache::Group>("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTableP(), Cache->Head().GetHashTableSize(), GroupNext);
 
 
    return true;
    return true;
 }
 }