diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 4144d701d..52ff96028 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -451,16 +451,21 @@ class dict { return 1; } - int do_lookup(const K &key, Hasher::hash_t &hash) const + int do_lookup(const K &key, Hasher::hash_t &hash) { if (hashtable.empty()) return -1; if (entries.size() * hashtable_size_trigger > hashtable.size()) { - ((dict*)this)->do_rehash(); + do_rehash(); hash = do_hash(key); } + return do_lookup_internal(key, hash); + } + + int do_lookup_internal(const K &key, Hasher::hash_t hash) const + { int index = hashtable[hash]; while (index >= 0 && !ops.cmp(entries[index].udata.first, key)) { @@ -471,6 +476,14 @@ class dict { return index; } + int do_lookup_no_rehash(const K &key, Hasher::hash_t hash) const + { + if (hashtable.empty()) + return -1; + + return do_lookup_internal(key, hash); + } + int do_insert(const K &key, Hasher::hash_t &hash) { if (hashtable.empty()) { @@ -694,14 +707,14 @@ public: int count(const K &key) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); return i < 0 ? 0 : 1; } int count(const K &key, const_iterator it) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); return i < 0 || i > it.index ? 0 : 1; } @@ -717,7 +730,7 @@ public: const_iterator find(const K &key) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); if (i < 0) return end(); return const_iterator(this, i); @@ -735,7 +748,7 @@ public: const T& at(const K &key) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); if (i < 0) throw std::out_of_range("dict::at()"); return entries[i].udata.second; @@ -744,7 +757,7 @@ public: const T& at(const K &key, const T &defval) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); if (i < 0) return defval; return entries[i].udata.second; @@ -906,16 +919,21 @@ protected: return 1; } - int do_lookup(const K &key, Hasher::hash_t &hash) const + int do_lookup(const K &key, Hasher::hash_t &hash) { if (hashtable.empty()) return -1; if (entries.size() * hashtable_size_trigger > hashtable.size()) { - ((pool*)this)->do_rehash(); + do_rehash(); hash = do_hash(key); } + return do_lookup_internal(key, hash); + } + + int do_lookup_internal(const K &key, Hasher::hash_t hash) const + { int index = hashtable[hash]; while (index >= 0 && !ops.cmp(entries[index].udata, key)) { @@ -926,6 +944,14 @@ protected: return index; } + int do_lookup_no_rehash(const K &key, Hasher::hash_t hash) const + { + if (hashtable.empty()) + return -1; + + return do_lookup_internal(key, hash); + } + int do_insert(const K &value, Hasher::hash_t &hash) { if (hashtable.empty()) { @@ -1087,14 +1113,14 @@ public: int count(const K &key) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); return i < 0 ? 0 : 1; } int count(const K &key, const_iterator it) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); return i < 0 || i > it.index ? 0 : 1; } @@ -1110,7 +1136,7 @@ public: const_iterator find(const K &key) const { Hasher::hash_t hash = do_hash(key); - int i = do_lookup(key, hash); + int i = do_lookup_no_rehash(key, hash); if (i < 0) return end(); return const_iterator(this, i); @@ -1222,7 +1248,7 @@ public: int at(const K &key) const { Hasher::hash_t hash = database.do_hash(key); - int i = database.do_lookup(key, hash); + int i = database.do_lookup_no_rehash(key, hash); if (i < 0) throw std::out_of_range("idict::at()"); return i + offset; @@ -1231,7 +1257,7 @@ public: int at(const K &key, int defval) const { Hasher::hash_t hash = database.do_hash(key); - int i = database.do_lookup(key, hash); + int i = database.do_lookup_no_rehash(key, hash); if (i < 0) return defval; return i + offset; @@ -1240,7 +1266,7 @@ public: int count(const K &key) const { Hasher::hash_t hash = database.do_hash(key); - int i = database.do_lookup(key, hash); + int i = database.do_lookup_no_rehash(key, hash); return i < 0 ? 0 : 1; }