diff options
author | Julian Andres Klode <jak@debian.org> | 2016-01-08 01:27:01 +0100 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2016-01-08 01:30:18 +0100 |
commit | 869700d839a1695fe00734592bd504d59386e4b9 (patch) | |
tree | 3ad6f069d50aa4d44cc733c11b1231d04df4856b /apt-pkg | |
parent | 57590d3c6e6b055402c938c3baebf1d872c58f7e (diff) |
pkgCacheGenerator::StoreString: Get rid of std::string
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%).
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 12 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.h | 34 |
2 files changed, 34 insertions, 12 deletions
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 577a6e474..79d633cb7 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -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; } /*}}}*/ diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index e4760d44d..d83ea6a25 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -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; |