summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2011-09-12 18:44:12 (GMT)
committerEvan Martin <martine@danga.com>2011-09-12 18:46:18 (GMT)
commit3fbb25b2cc66f236a39b728d20e5d44da23612ac (patch)
treed6eb7c1bc63ef3d4d4d1056750756dc581da5ef0 /src
parentf1139aff5deddacd899be064fad9ed5a185e7444 (diff)
downloadNinja-3fbb25b2cc66f236a39b728d20e5d44da23612ac.zip
Ninja-3fbb25b2cc66f236a39b728d20e5d44da23612ac.tar.gz
Ninja-3fbb25b2cc66f236a39b728d20e5d44da23612ac.tar.bz2
generalize the pattern of hash_map<const char*, ...>, use in BuildLog
Refactor the code in StatCache for use in BuildLog. Now both use hash tables where the keys are const char*. Removes another 30ms from Chrome no-op builds.
Diffstat (limited to 'src')
-rw-r--r--src/build_log.cc14
-rw-r--r--src/build_log.h4
-rw-r--r--src/hash_map.h29
-rw-r--r--src/stat_cache.cc5
-rw-r--r--src/stat_cache.h22
5 files changed, 42 insertions, 32 deletions
diff --git a/src/build_log.cc b/src/build_log.cc
index b21a755..79143bf 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -91,15 +91,15 @@ 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)->file_->path_;
- Log::iterator i = log_.find(path);
+ Log::iterator i = log_.find(path.c_str());
LogEntry* log_entry;
if (i != log_.end()) {
log_entry = i->second;
} else {
log_entry = new LogEntry;
- log_.insert(make_pair(path, log_entry));
+ log_entry->output = path;
+ log_.insert(make_pair(log_entry->output.c_str(), log_entry));
}
- log_entry->output = path;
log_entry->command = command;
log_entry->start_time = start_time;
log_entry->end_time = end_time;
@@ -171,17 +171,17 @@ bool BuildLog::Load(const string& path, string* err) {
continue;
LogEntry* entry;
- Log::iterator i = log_.find(output);
+ Log::iterator i = log_.find(output.c_str());
if (i != log_.end()) {
entry = i->second;
} else {
entry = new LogEntry;
- log_.insert(make_pair(output, entry));
+ entry->output = output;
+ log_.insert(make_pair(entry->output.c_str(), entry));
++unique_entry_count;
}
++total_entry_count;
- entry->output = output;
entry->start_time = start_time;
entry->end_time = end_time;
entry->command = string(start, end - start);
@@ -205,7 +205,7 @@ bool BuildLog::Load(const string& path, string* err) {
}
BuildLog::LogEntry* BuildLog::LookupByOutput(const string& path) {
- Log::iterator i = log_.find(path);
+ Log::iterator i = log_.find(path.c_str());
if (i != log_.end())
return i->second;
return NULL;
diff --git a/src/build_log.h b/src/build_log.h
index f45cbde..4a11c1a 100644
--- a/src/build_log.h
+++ b/src/build_log.h
@@ -19,6 +19,8 @@
#include <string>
using namespace std;
+#include "hash_map.h"
+
struct BuildConfig;
struct Edge;
@@ -64,7 +66,7 @@ struct BuildLog {
/// Rewrite the known log entries, throwing away old data.
bool Recompact(const string& path, string* err);
- typedef map<string, LogEntry*> Log;
+ typedef ExternalStringHashMap<LogEntry*>::Type Log;
Log log_;
FILE* log_file_;
BuildConfig* config_;
diff --git a/src/hash_map.h b/src/hash_map.h
index 346a34e..1025f71 100644
--- a/src/hash_map.h
+++ b/src/hash_map.h
@@ -15,6 +15,8 @@
#ifndef NINJA_MAP_H_
#define NINJA_MAP_H_
+#include <string.h>
+
#ifdef _MSC_VER
#include <hash_map>
@@ -37,4 +39,31 @@ struct hash<std::string> {
#endif
+/// 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*.
+struct ExternalStringHash {
+ size_t operator()(const char* key) const {
+#ifdef _MSC_VER
+ return stdext::hash<const char*>()(key);
+#else
+ return __gnu_cxx::hash<const char*>()(key);
+#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*.
+template<typename V>
+struct ExternalStringHashMap {
+ typedef hash_map<const char*, V, ExternalStringHash, ExternalStringEq> Type;
+};
+
#endif // NINJA_MAP_H_
diff --git a/src/stat_cache.cc b/src/stat_cache.cc
index 487afd1..75248be 100644
--- a/src/stat_cache.cc
+++ b/src/stat_cache.cc
@@ -19,12 +19,11 @@
#include "graph.h"
FileStat* StatCache::GetFile(const std::string& path) {
- Key key(path.c_str());
- Paths::iterator i = paths_.find(key);
+ Paths::iterator i = paths_.find(path.c_str());
if (i != paths_.end())
return i->second;
FileStat* file = new FileStat(path);
- paths_[Key(file->path_.c_str())] = file;
+ paths_[file->path_.c_str()] = file;
return file;
}
diff --git a/src/stat_cache.h b/src/stat_cache.h
index 1b9a8ff..9cb3eff 100644
--- a/src/stat_cache.h
+++ b/src/stat_cache.h
@@ -31,27 +31,7 @@ struct StatCache {
void Dump();
void Reload();
- struct Key {
- Key() : path(NULL) {}
- Key(const char* p) : path(p) {}
-
- const char* path;
- bool operator==(const Key& other) const {
- return strcmp(path, other.path) == 0;
- }
- };
-
- struct KeyHash {
- size_t operator()(const StatCache::Key& key) const {
-#ifdef _MSC_VER
- return stdext::hash<const char*>()(key.path);
-#else
- return __gnu_cxx::hash<const char*>()(key.path);
-#endif
- }
- };
-
- typedef hash_map<Key, FileStat*, KeyHash> Paths;
+ typedef ExternalStringHashMap<FileStat*>::Type Paths;
Paths paths_;
};