diff --git a/octa/internal/hashtable.h b/octa/internal/hashtable.h index 348f5d8..022da92 100644 --- a/octa/internal/hashtable.h +++ b/octa/internal/hashtable.h @@ -143,6 +143,7 @@ namespace detail { typename A, /* allocator */ bool Multihash > struct Hashtable { +private: static constexpr octa::Size CHUNKSIZE = 64; using Chain = octa::detail::HashChain; @@ -176,6 +177,7 @@ namespace detail { float p_maxlf; +public: const H &get_hash() const { return p_data.second().second().first(); } const C &get_eq() const { return p_data.second().second().second(); } @@ -329,6 +331,22 @@ namespace detail { return B::get_data(c->value); } + T &access_or_insert(const K &key) { + octa::Size h; + T *v = access_base(key, h); + if (v) return *v; + rehash_ahead(1); + return insert(h, key); + } + + T &access_or_insert(K &&key) { + octa::Size h; + T *v = access_base(key, h); + if (v) return *v; + rehash_ahead(1); + return insert(h, octa::move(key)); + } + octa::Size remove(const K &key) { if (!p_len) return 0; octa::Size olen = p_len; @@ -389,16 +407,9 @@ namespace detail { return NULL; } - T *access(const K &key) const { + T &access(const K &key) const { octa::Size h; - return access_base(key, h); - } - - T &access(const K &key, const T &val) { - octa::Size h; - T *found = access_base(key, h); - if (found) return *found; - return (insert(h, key) = val); + return *access_base(key, h); } template diff --git a/octa/map.h b/octa/map.h index 5922754..4b4fb21 100644 --- a/octa/map.h +++ b/octa/map.h @@ -171,25 +171,17 @@ public: } T &at(const K &key) { - return *p_table.access(key); + return p_table.access(key); } const T &at(const K &key) const { - return *p_table.access(key); + return p_table.access(key); } T &operator[](const K &key) { - octa::Size h; - T *v = p_table.access_base(key, h); - if (v) return *v; - p_table.rehash_ahead(1); - return p_table.insert(h, key); + return p_table.access_or_insert(key); } T &operator[](K &&key) { - octa::Size h; - T *v = p_table.access_base(key, h); - if (v) return *v; - p_table.rehash_ahead(1); - return p_table.insert(h, octa::move(key)); + return p_table.access_or_insert(octa::move(key)); } template