]> git.saurik.com Git - apt.git/commitdiff
pkgCacheGenerator::StoreString: Get rid of std::string
authorJulian Andres Klode <jak@debian.org>
Fri, 8 Jan 2016 00:27:01 +0000 (01:27 +0100)
committerJulian Andres Klode <jak@debian.org>
Fri, 8 Jan 2016 00:30:18 +0000 (01:30 +0100)
Instead of storing a string -> map_stringitem_t mapping, create
our own data type that can point to either a normal string or
a string inside the cache.

This avoids the creation of any string and improves performance
slightly (about 4%).

apt-pkg/pkgcachegen.cc
apt-pkg/pkgcachegen.h

index 577a6e47422e1e112903893f0b7b2fc4c0b71ece..79d633cb72d7eb4ec77a1379142c068b7e09eb3b 100644 (file)
@@ -1257,23 +1257,21 @@ bool pkgCacheGenerator::SelectFile(std::string const &File,
 map_stringitem_t pkgCacheGenerator::StoreString(enum StringType const type, const char *S,
                                                 unsigned int Size)
 {
-   std::string key(S, Size);
-
-   std::unordered_map<std::string,map_stringitem_t> * strings;
+   auto strings = &strMixed;
    switch(type) {
       case MIXED: strings = &strMixed; break;
       case PKGNAME: strings = &strPkgNames; break;
       case VERSIONNUMBER: strings = &strVersions; break;
       case SECTION: strings = &strSections; break;
-      default: _error->Fatal("Unknown enum type used for string storage of '%s'", key.c_str()); return 0;
+      default: _error->Fatal("Unknown enum type used for string storage of '%.*s'", Size, S); return 0;
    }
 
-   std::unordered_map<std::string,map_stringitem_t>::const_iterator const item = strings->find(key);
+   auto const item = strings->find({S, Size, nullptr, 0});
    if (item != strings->end())
-      return item->second;
+      return item->item;
 
    map_stringitem_t const idxString = WriteStringInMap(S,Size);
-   strings->insert(std::make_pair(std::move(key), idxString));
+   strings->insert({nullptr, Size, this, idxString});
    return idxString;
 }
                                                                        /*}}}*/
index e4760d44d74f53b2d20edc50cb3e9591d5e691cf..d83ea6a25e3df4d020bcf2e8f63fca8b07002be4 100644 (file)
@@ -27,7 +27,7 @@
 #include <vector>
 #include <string>
 #if __cplusplus >= 201103L
-#include <unordered_map>
+#include <unordered_set>
 #endif
 #ifdef APT_PKG_EXPOSE_STRING_VIEW
 #include <apt-pkg/string_view.h>
@@ -48,10 +48,34 @@ class APT_HIDDEN pkgCacheGenerator                                  /*{{{*/
 
    // Dirty hack for public users that do not use C++11 yet
 #if __cplusplus >= 201103L
-   std::unordered_map<std::string,map_stringitem_t> strMixed;
-   std::unordered_map<std::string,map_stringitem_t> strSections;
-   std::unordered_map<std::string,map_stringitem_t> strPkgNames;
-   std::unordered_map<std::string,map_stringitem_t> strVersions;
+   struct string_pointer {
+      const char *data_;
+      size_t size;
+      pkgCacheGenerator *generator;
+      map_stringitem_t item;
+
+      const char *data() const {
+        return data_ != nullptr ? data_ : static_cast<char*>(generator->Map.Data()) + item;
+      }
+
+      bool operator ==(string_pointer const &other) const {
+        return size == other.size && memcmp(data(), other.data(), size) == 0;
+      }
+   };
+   struct hash {
+      uint32_t operator()(string_pointer const &that) const {
+        uint32_t Hash = 5381;
+        const char * const end = that.data() + that.size;
+        for (const char *I = that.data(); I != end; ++I)
+           Hash = 33 * Hash + tolower_ascii((signed char)*I);
+        return Hash;
+      }
+   };
+
+   std::unordered_set<string_pointer, hash> strMixed;
+   std::unordered_set<string_pointer, hash> strPkgNames;
+   std::unordered_set<string_pointer, hash> strVersions;
+   std::unordered_set<string_pointer, hash> strSections;
 #endif
 
    friend class pkgCacheListParser;