Initializes a new table with a certain preallocated capacity.
Adds an element to the hash set; may rehash.
Can be used to iterate over this table's entries (but iteration order is unspecified).
Removes all elements from the hash table, without changing its capacity.
Clears and frees the table's internal storage.
Creates an independent copy of a hash table.
Looks up an entry in the table's internal storage.
Returns a pointer to a matching KEY in the table, or null
Structural equality comparison.
Returns (a ref to) the value associated with a given key.
Upserts an entry in the hash table. May cause a rehash.
Rehashes the table.
Removes a key's entry from the table.
Looks up a key's entry, inserting one if not found (may rehash).
Structural hash of this table.
Looks up a key's entry in the table, then either updates it or creates a new one (may rehash).
Entries the table can hold without being rehashed.
Number of entries currently being used in the hash table.
This type optimizes storage when value types are zero-sized (e.g. for UnsafeHashSet):
alias NonZero = long; alias Zero = void[0]; static assert(UnsafeHashMap!(char, Zero).sizeof < UnsafeHashMap!(char, NonZero).sizeof);
Consider using scope(exit) to ensure hash table memory doesn't leak.
UnsafeHashMap!(char, long) outer; { auto inner = UnsafeHashMap!(char, long)(42); scope(exit) inner.dispose(); outer = inner; // but be careful with shallow copies } // outer.dispose(); // would have caused a double free: `dispose` is unsafe!
Basic usage:
HashMap!(char, long) table; assert(table.length == 0); assert('a' !in table); table['a'] = 0; // inserts assert('a' in table); table['a'] = 1; // updates assert(table.length == 1); assert('a' in table); assert(table.remove('a') == true); assert('a' !in table); assert(table.remove('a') == false); assert(table.length == 0); static immutable reverse = ['a', 'b', 'c', 'd', 'e']; foreach (i, c; reverse) table[c] = i + 1; table.rehash(); // must preserve elements assert(table.length == reverse.length); foreach (key; table.byKey) assert(key == reverse[table[key] - 1]); foreach (val; table.byValue) assert(val == table[reverse[val - 1]]); const cap = table.capacity; table.clear(); // preserves capacity assert(table.length == 0); assert(table.capacity == cap);
Sligthly more advanced example:
import core.stdc.ctype : isalnum; import eris.util : empty; bool isAnagram(const(string) a, const(string) b) { // count letter frequencies in A HashMap!(char, long) letters; foreach (c; a) { if (!c.isalnum) continue; const freq = letters.get(c, () => 0L); letters[c] = freq + 1; } // check if they match B's foreach (c; b) { if (!c.isalnum) continue; const freq = letters.update(c, () => -1L, (long f) => f - 1); if (freq < 0) return false; else if (freq == 0) letters.remove(c); } return letters.empty; } assert( isAnagram("tom marvolo riddle", "i am lord voldemort") ); assert( !isAnagram("aabaa", "bbabb") );
The safer HashMap
Dense hash map acting as a mostly-compatible (even if unsafe) AA replacement.
The mechanism used to override hashing and comparison functions is the same as for standard AAs. Unlike AA's, however, this hash table does NOT guarantee that references to its internal storage will be kept stable between rehashes, which may also be caused by insertion operations.