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

Store the size of strings in the cache

By storing the size of the string in the cache, we can make use of
it when comparing the names in the hashtable in pkgCache::FindGrp.
Julian Andres Klode лет назад: 10
Родитель
Сommit
60d523e2ae
4 измененных файлов с 24 добавлено и 6 удалено
  1. 9 2
      apt-pkg/contrib/mmap.cc
  2. 3 3
      apt-pkg/pkgcache.cc
  3. 10 0
      apt-pkg/pkgcache.h
  4. 2 1
      apt-pkg/pkgcachegen.cc

+ 9 - 2
apt-pkg/contrib/mmap.cc

@@ -411,7 +411,7 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
 									/*}}}*/
 // DynamicMMap::WriteString - Write a string to the file		/*{{{*/
 // ---------------------------------------------------------------------
-/* Strings are not aligned to anything */
+/* Strings are aligned to 16 bytes */
 unsigned long DynamicMMap::WriteString(const char *String,
 				       unsigned long Len)
 {
@@ -419,13 +419,20 @@ unsigned long DynamicMMap::WriteString(const char *String,
       Len = strlen(String);
 
    _error->PushToStack();
-   unsigned long const Result = RawAllocate(Len+1,0);
+   unsigned long Result = RawAllocate(Len+1+sizeof(uint16_t),sizeof(uint16_t));
    bool const newError = _error->PendingError();
    _error->MergeWithStack();
 
    if (Base == NULL || (Result == 0 && newError))
       return 0;
 
+   if (Len >= std::numeric_limits<uint16_t>::max())
+      abort();
+
+   uint16_t LenToWrite = Len;
+   memcpy((char *)Base + Result, &LenToWrite, sizeof(LenToWrite));
+   Result += + sizeof(LenToWrite);
+
    memcpy((char *)Base + Result,String,Len);
    ((char *)Base)[Result + Len] = 0;
    return Result;

+ 3 - 3
apt-pkg/pkgcache.cc

@@ -59,7 +59,7 @@ pkgCache::Header::Header()
    /* Whenever the structures change the major version should be bumped,
       whenever the generator changes the minor version should be bumped. */
    APT_HEADER_SET(MajorVersion, 10);
-   APT_HEADER_SET(MinorVersion, 3);
+   APT_HEADER_SET(MinorVersion, 4);
    APT_HEADER_SET(Dirty, false);
 
    APT_HEADER_SET(HeaderSz, sizeof(pkgCache::Header));
@@ -307,7 +307,7 @@ pkgCache::GrpIterator pkgCache::FindGrp(StringView Name) {
 	// Look at the hash bucket for the group
 	Group *Grp = GrpP + HeaderP->GrpHashTableP()[sHash(Name)];
 	for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
-		int const cmp = Name.compare(StrP + Grp->Name);
+		int const cmp = Name.compare(ViewString(Grp->Name));
 		if (cmp == 0)
 			return GrpIterator(*this, Grp);
 		else if (cmp < 0)
@@ -389,7 +389,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(StringView Arch) const {
 	// Iterate over the list to find the matching arch
 	for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
 	     Pkg = Owner->PkgP + Pkg->NextPackage) {
-		if (Arch.compare(Owner->StrP + Pkg->Arch) == 0)
+		if (Arch == Owner->ViewString(Pkg->Arch))
 			return PkgIterator(*Owner, Pkg);
 		if ((Owner->PkgP + S->LastPackage) == Pkg)
 			break;

+ 10 - 0
apt-pkg/pkgcache.h

@@ -245,6 +245,16 @@ class pkgCache								/*{{{*/
    APT_HIDDEN PkgIterator FindPkg(APT::StringView Name, APT::StringView Arch);
 #endif
 
+#ifdef APT_PKG_EXPOSE_STRING_VIEW
+   APT::StringView ViewString(map_stringitem_t idx) const
+   {
+      char *name = StrP + idx;
+      uint16_t len = *reinterpret_cast<const uint16_t*>(name - sizeof(uint16_t));
+      return APT::StringView(name, len);
+   }
+#endif
+
+
    GrpIterator FindGrp(const std::string &Name);
    PkgIterator FindPkg(const std::string &Name);
    PkgIterator FindPkg(const std::string &Name, const std::string &Arch);

+ 2 - 1
apt-pkg/pkgcachegen.cc

@@ -518,7 +518,8 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, StringView Name)
    // Insert it into the hash table
    unsigned long const Hash = Cache.Hash(Name);
    map_pointer_t *insertAt = &Cache.HeaderP->GrpHashTableP()[Hash];
-   while (*insertAt != 0 && Name.compare(Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
+
+   while (*insertAt != 0 && Name.compare(Cache.ViewString((Cache.GrpP + *insertAt)->Name)) > 0)
       insertAt = &(Cache.GrpP + *insertAt)->Next;
    Grp->Next = *insertAt;
    *insertAt = Group;