diff options
-rw-r--r-- | src/build_log.cc | 8 | ||||
-rw-r--r-- | src/hash_map.h | 60 | ||||
-rw-r--r-- | src/state.cc | 4 |
3 files changed, 50 insertions, 22 deletions
diff --git a/src/build_log.cc b/src/build_log.cc index b564137..f342e83 100644 --- a/src/build_log.cc +++ b/src/build_log.cc @@ -78,7 +78,7 @@ void BuildLog::RecordCommand(Edge* edge, int start_time, int end_time, for (vector<Node*>::iterator out = edge->outputs_.begin(); out != edge->outputs_.end(); ++out) { const string& path = (*out)->path(); - Log::iterator i = log_.find(path.c_str()); + Log::iterator i = log_.find(path); LogEntry* log_entry; if (i != log_.end()) { log_entry = i->second; @@ -163,13 +163,13 @@ bool BuildLog::Load(const string& path, string* err) { continue; LogEntry* entry; - Log::iterator i = log_.find(output.c_str()); + Log::iterator i = log_.find(output); if (i != log_.end()) { entry = i->second; } else { entry = new LogEntry; entry->output = output; - log_.insert(make_pair(entry->output.c_str(), entry)); + log_.insert(make_pair(entry->output, entry)); ++unique_entry_count; } ++total_entry_count; @@ -198,7 +198,7 @@ bool BuildLog::Load(const string& path, string* err) { } BuildLog::LogEntry* BuildLog::LookupByOutput(const string& path) { - Log::iterator i = log_.find(path.c_str()); + Log::iterator i = log_.find(path); if (i != log_.end()) return i->second; return NULL; diff --git a/src/hash_map.h b/src/hash_map.h index 401f690..0aac7d6 100644 --- a/src/hash_map.h +++ b/src/hash_map.h @@ -15,7 +15,42 @@ #ifndef NINJA_MAP_H_ #define NINJA_MAP_H_ -#include <string.h> +#include "string_piece.h" + +static const unsigned int kSeed = 0xDECAFBAD; +// MurmurHash2, by Austin Appleby +static +unsigned int MurmurHash2(const void* key, int len, unsigned int seed) { + const unsigned int m = 0x5bd1e995; + const int r = 24; + unsigned int h = seed ^ len; + const unsigned char * data = (const unsigned char *)key; + while(len >= 4) { + unsigned int k = *(unsigned int *)data; + + k *= m; + k ^= k >> r; + k *= m; + + h *= m; + h ^= k; + + data += 4; + len -= 4; + } + switch(len) { + case 3: h ^= data[2] << 16; + case 2: h ^= data[1] << 8; + case 1: h ^= data[0]; + h *= m; + }; + + h ^= h >> 13; + h *= m; + h ^= h >> 15; + + return h; +} #ifdef _MSC_VER #include <hash_map> @@ -45,31 +80,24 @@ struct hash<std::string> { } -/// Equality binary predicate for const char*. -struct ExternalStringEq { - bool operator()(const char* a, const char* b) { - return strcmp(a, b) == 0; - } -}; - -/// Hash functor for const char*. +/// Hash functor for StringPiece. struct ExternalStringHash { - size_t operator()(const char* key) const { - return __gnu_cxx::hash<const char*>()(key); + size_t operator()(StringPiece key) const { + return MurmurHash2(key.str_, key.len_, kSeed); } }; #endif -/// A template for hash_maps keyed by a const char* that is maintained within -/// the values. Use like: -/// ExternalStringHash<Foo*>::Type foos; -/// to make foos into a hash mapping const char* => Foo*. +/// A template for hash_maps keyed by a StringPiece whose string is +/// owned externally (typically by the values). Use like: +/// ExternalStringHash<Foo*>::Type foos; to make foos into a hash +/// mapping StringPiece => Foo*. template<typename V> struct ExternalStringHashMap { #ifdef _MSC_VER typedef hash_map<const char*, V, hash_compare<const char *,ExternalStringCmp> > Type; #else - typedef hash_map<const char*, V, ExternalStringHash, ExternalStringEq> Type; + typedef hash_map<StringPiece, V, ExternalStringHash> Type; #endif }; diff --git a/src/state.cc b/src/state.cc index 79e2551..238674e 100644 --- a/src/state.cc +++ b/src/state.cc @@ -52,12 +52,12 @@ Node* State::GetNode(const string& path) { if (node) return node; node = new Node(path); - paths_[node->path().c_str()] = node; + paths_[node->path()] = node; return node; } Node* State::LookupNode(const string& path) { - Paths::iterator i = paths_.find(path.c_str()); + Paths::iterator i = paths_.find(path); if (i != paths_.end()) return i->second; return NULL; |