HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED > Class Template Reference

#include <hashmap.h>

Inheritance diagram for HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >:

Detailed Description

template<typename K, typename V, typename HASH = DefaultCompare, typename ENTRY_HANDLER = HashMapKeyValuePair, typename ALLOCATOR = DefaultAllocator, Bool SYNCHRONIZED = false>
class maxon::HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >

A HashMap maps keys to values with the help of hash codes for the keys. It expects a function static UInt HASH::GetHashCode(const K&) in the class HASH (given as template argument) to compute a hash code for a key, and then it uses the lower bits of the hash code as an index into a table of buckets. Each bucket contains a singly linked list of entries (key-value-pairs) having the same lower bits, and the function static Bool HASH::IsEqual(const K&, const K&) is used to find the entry with matching key, if any. By default, DefaultCompare is used for HASH, this handles keys of integral type, pointers and objects which have a GetHashCode member function themselves as well as the == operator. For other keys, you have to define your own class for HASH, see CStringCompare as an example.

This example uses a HashMap to store String values addressed by Int keys:

using IntStringMap = HashMap<Int, String>;
IntStringMap map;
...
// now store "Hello World" at key 42
Bool created = false;
String& s = map.InsertKey(42, created) iferr_return;
if (created) // if created is false, there already exists an entry for 42 in the map
{
// initialize the new value
s = "Hello World"_s;
}
...
// now check if there is an entry at key 42
String* s = map.FindValue(42);
if (s)
{
DiagnosticOutput("Found value @", *s);
}

Instead of InsertKey(), you can also use Insert() if you don't need to differentiate between the cases whether the entry existed before or not:

IntStringMap::Entry& e = map.Insert(42, "Hello World"_s) iferr_return;

A HashMap can also be used as a multi-map, which means that there can be more than one value per key. You have to use InsertMultiEntry() to add entries for a key, this function won't overwrite or remove existing entries for that key. To get all entries for a key, you have to iterate over them in the following way:

for (IntStringMap::Entry* e = map.Find(42); e; e = e->GetNextWithSameKey())
{
...
}

You can also use the foreach iterator returned by FindAll():

for (const IntStringMap::Entry& e : map.FindAll(42))
{
...
}

The larger the table of buckets, the less is the chance of several entries within a single bucket. The HashMap uses a load factor to automatically double the size of the table if the number of entries exceeds the table size multiplied by the load factor (re-hashing). So with a load factor of 0.5 there are at most half as many entries as there are buckets, and then with evenly distributed hash codes there is only a negligible number of buckets with more than one entry. The default load factor is 0.65. If you use a load factor <= 0, the automatic increase of table size is switched off, thus the HashMap will keep the initial size of the table.

Performance characteristics: A HashMap performs the map operations in constant time if the hash function computes evenly distributed hash codes for the keys. All operations (insertion, erasure, lookup) are typically performed in constant time O(1) (i.e., independent of the total number of entries).

There are applications of the HashMap where the values already contain the keys (e.g., think of a map from names to objects, and the objects know their names). Then it might be wasteful to store the keys again in the HashMap entries. In such a case, you have to specify a class as argument for the template parameter ENTRY_HANDLER which contains the function static const K& ENTRY_HANDLER::GetKey(const V&). This function will be used to extract keys from values. You also have to make sure that each HashMap entry has a valid value. I.e., when you have added a new entry with Insert(), then you have to initialize it with a value whose key is the same key as the one used for Insert().

If you want to iterate over the entries of a HashMap, you can either use Iterator, ConstIterator or a ranged-based for loop, or you can use GetNonEmptyBucketCount() and GetNonEmptyBucket() to loop over the non-empty buckets, and then HashMap::Entry::GetNextInBucket() to run through the entries of a bucket.

for (IntStringMap::ConstIterator i = map.Begin(); i != map.End(); ++i)
{
DiagnosticOutput("@ -> @", i->GetKey(), i->GetValue());
}
for (const IntStringMap::Entry& entry : map)
{
DiagnosticOutput("@ -> @", entry.GetKey(), entry.GetValue());
}

When the template parameter SYNCHRONIZED is set to true, the HashMap (partially) behaves as a thread-safe, lock-free map. But note that this only holds if the only modification is the addition of new entries. You must not erase entries unless you make sure that this only happens when no other thread accesses the HashMap, and that a proper synchronization happens afterwards. Also you have to set the load factor to zero to disable re-hashing and set a sufficiently large capacity at the beginning using SetCapacityHint(). Iterators are generally less efficient when SYNCHRONIZED is true as they have to loop over all buckets and not just over the non-empty buckets.

Template Parameters
KType of keys.
VType of values.
HASHClass to be used to compute the hash code of keys, and to compare keys for equality (DefaultCompare by default)
ENTRY_HANDLERUse this class if the keys shall be extracted from values, rather than being stored separately. With the default argument HashMapKeyValuePair, keys and values are stored separately in the entries as key-value-pairs.
ALLOCATORClass for memory allocation.
SYNCHRONIZEDUse atomic access to implement a lock-free hash map.
See also
$ref maps

Classes

struct  Bucket
 
class  ConstIteratorTemplate
 
class  Entry
 
class  EntryIteratorBase
 
class  Hash
 
class  IteratorTemplate
 
class  IteratorTemplateBase
 
class  KeyIteratorBase
 
struct  LambdaEntryConstructor
 
struct  LambdaEntryConstructor< KEY &, LAMBDA, true >
 
class  MultiEntryIterator
 
class  ValueIteratorBase
 

Public Types

using Super = MapBase< HashMap, K, V, EmptyClass, HASH >
 
using HashType = HASH
 
using IsHashMap = std::true_type
 
using Iterator = IteratorTemplate< EntryIteratorBase >
 
using ConstIterator = ConstIteratorTemplate< EntryIteratorBase >
 
using KeyIterator = IteratorTemplate< KeyIteratorBase >
 
using ConstKeyIterator = ConstIteratorTemplate< KeyIteratorBase >
 
using ValueIterator = IteratorTemplate< ValueIteratorBase >
 
using ConstValueIterator = ConstIteratorTemplate< ValueIteratorBase >
 
- Public Types inherited from MapBase0< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, K, V, EmptyClass, HASH >
using MapType = HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >
 
using Super = BaseCollection< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, EmptyClass >
 
using KeyType = K
 
using ValueType = V
 
- Public Types inherited from BaseCollection< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, EmptyClass >
using IsCollection = std::true_type
 

Public Member Functions

 HashMap (Float loadFactor=Float(SYNCHRONIZED ? 0 :0.65))
 
 HashMap (const ALLOCATOR &alloc, Float loadFactor=Float(SYNCHRONIZED ? 0 :0.65))
 
 ~HashMap ()
 
 HashMap (HashMap &&src)
 
 MAXON_OPERATOR_MOVE_ASSIGNMENT (HashMap)
 
ResultMem SetCapacityHint (Int capacity, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::ON_GROW_RESERVE_CAPACITY)
 
ResultMem ResizeTable (Int capacity)
 
void Reset ()
 
void Flush ()
 
Int GetCount () const
 
Int GetTableSize () const
 
Int GetMemorySize () const
 
Int GetNonEmptyBucketCount () const
 
EntryGetNonEmptyBucket (Int i)
 
const EntryGetNonEmptyBucket (Int i) const
 
Int GetOperationCountForSearch () const
 
template<typename MAP , typename COMPARE >
SFINAEHelper< Bool, typename MAP::IsHashMap >::type IsEqualImpl (const MAP &other, COMPARE &&cmp, OverloadRank1) const
 
template<typename KEYHASH = HASH, typename KEY >
EntryFind (const KEY &key)
 
template<typename KEYHASH = HASH, typename KEY >
const EntryFind (const KEY &key) const
 
template<typename KEYHASH = HASH, typename KEY >
V * FindValue (const KEY &key)
 
template<typename KEYHASH = HASH, typename KEY >
const V * FindValue (const KEY &key) const
 
template<typename KEYHASH = HASH, typename KEY , typename C >
Result< Entry * > InsertCtor (KEY &&key, C &&constructor, Bool &created=BoolLValue())
 
ResultRef< EntryInsertEntry (const K &key, Bool &created=BoolLValue())
 
ResultRef< EntryInsertEntry (K &&key, Bool &created=BoolLValue())
 
template<typename KEYHASH = HASH, typename KEY >
ResultRef< EntryInsertEntry (KEY &&key, Bool &created=BoolLValue())
 
ResultRef< V > InsertKey (const K &key, Bool &created=BoolLValue())
 
ResultRef< V > InsertKey (K &&key, Bool &created=BoolLValue())
 
template<typename KEYHASH = HASH, typename KEY >
ResultRef< V > InsertKey (KEY &&key, Bool &created=BoolLValue())
 
template<typename KEYHASH = HASH, typename KEY , typename LAMBDA >
Result< Entry * > InsertLambda (KEY &&key, LAMBDA &&lambda)
 
template<typename KEYHASH = HASH, typename KEY >
ResultRef< EntryInsert (KEY &&key, const V &value, Bool &created=BoolLValue())
 
template<typename KEYHASH = HASH, typename KEY >
ResultRef< EntryInsert (KEY &&key, V &&value, Bool &created=BoolLValue())
 
template<typename KEYHASH = HASH, typename KEY >
ResultRef< EntryInsertMultiEntry (KEY &&key)
 
ResultMem InsertMultiEntry (Entry *e, UInt hash)
 
ResultOk< void > Erase (const Entry *entry, Bool deleteEntry=true)
 
ResultOk< void > Erase (Entry *entry, Bool deleteEntry=true)
 
ResultOk< void > Erase (const Entry &entry, Bool deleteEntry=true)
 
ResultOk< void > Erase (Entry &entry, Bool deleteEntry=true)
 
void DeleteEntry (const Entry *e)
 
template<typename KEYHASH = HASH, typename KEY >
ResultOk< BoolErase (const KEY &key)
 
template<typename SET >
Result< void > IntersectImpl (SET &&set, OverloadRank0)
 
template<typename S >
SFINAEHelper< Result< void >, typename std::remove_reference< S >::type::MapType >::type AppendAllImpl (S &&src, COLLECTION_RESIZE_FLAGS resizeFlags, Bool overwrite, OverloadRank1)
 
MultiEntryIterator< false > FindAll (const K &key)
 
MultiEntryIterator< true > FindAll (const K &key) const
 
KeyIterator GetKeys ()
 
ConstKeyIterator GetKeys () const
 
ValueIterator GetValues ()
 
ConstValueIterator GetValues () const
 
Iterator Begin ()
 
Iterator End ()
 
ConstIterator Begin () const
 
ConstIterator End () const
 
template<template< Bool > class SUPER>
IteratorTemplate< SUPER > Erase (const IteratorTemplate< SUPER > &it, Bool deleteEntry=true)
 
Iterator GetIterator (const Entry *e)
 
ConstIterator GetIterator (const Entry *e) const
 
SFINAEHelper< String, V >::type ToString (const FormatStatement *formatStatement) const
 
template<typename KEY , typename KEYHASH >
const EntryFindEntryImpl (UInt hash, const KEY &key) const
 
template<typename KEY , typename KEYHASH >
EntryFindEntryImpl (UInt hash, const KEY &key)
 
- Public Member Functions inherited from MapBase< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, K, V, EmptyClass, HASH >
MAXON_ATTRIBUTE_FORCE_INLINE MapBase (ARGS &&... args)
 
MapImpl< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED > &> ToMap ()
 
MapImpl< const HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED > &> ToMap () const
 
MAXON_ATTRIBUTE_FORCE_INLINE operator MapImpl< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED > &> ()
 
MAXON_ATTRIBUTE_FORCE_INLINE operator MapImpl< const HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED > &> () const
 
- Public Member Functions inherited from MapBase0< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, K, V, EmptyClass, HASH >
MAXON_ATTRIBUTE_FORCE_INLINE MapBase0 (ARGS &&... args)
 
MAXON_ATTRIBUTE_FORCE_INLINE Bool Contains (typename ByValueParam< K >::type key) const
 
MAXON_ATTRIBUTE_FORCE_INLINE SFINAEHelper< Bool, typename PAIR::KeyType >::type Contains (const PAIR &pair) const
 
ResultRef< V > Append (const K &key)
 
SFINAEHelper< ResultRef< V >, typename PAIR::KeyType >::type Append (const PAIR &pair)
 
Result< void > Add (COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::ON_GROW_RESERVE_CAPACITY)
 
Result< void > AppendAll (COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::ON_GROW_RESERVE_CAPACITY)
 
Result< void > AppendAllInverse (COLLECTION2 &&other)
 
Bool ContainsAllImpl (COLLECTION2 &&other, OverloadRank0) const
 
Result< void > SubtractImpl (COLLECTION2 &&other, OverloadRank0)
 
Bool IsEqualImpl (const COLLECTION2 &other, COMPARE &&cmp, OverloadRank0) const
 
UInt GetHashCode () const
 
- Public Member Functions inherited from BaseCollection< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, EmptyClass >
MAXON_ATTRIBUTE_FORCE_INLINE BaseCollection (ARGS &&... args)
 
MAXON_ATTRIBUTE_FORCE_INLINE std::enable_if< maxon::IsCollection< COLLECTION2 >::value, Bool >::type operator== (const COLLECTION2 &other) const
 
MAXON_ATTRIBUTE_FORCE_INLINE std::enable_if< maxon::IsCollection< COLLECTION2 >::value, Bool >::type operator!= (const COLLECTION2 &other) const
 
MAXON_ATTRIBUTE_FORCE_INLINE std::enable_if< maxon::IsCollection< COLLECTION2 >::value &&!std::is_same< typename std::decay< COMPARE >::type, EQUALITY >::value, Bool >::type IsEqual (const COLLECTION2 &other, COMPARE &&cmp=COMPARE()) const
 
MAXON_ATTRIBUTE_FORCE_INLINE Result< void > AppendAll (COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::ON_GROW_RESERVE_CAPACITY)
 
MAXON_ATTRIBUTE_FORCE_INLINE Result< void > CopyFrom (COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::FIT_TO_SIZE)
 
MAXON_ATTRIBUTE_FORCE_INLINE Result< void > Subtract (COLLECTION2 &&other)
 
MAXON_ATTRIBUTE_FORCE_INLINE Result< void > Intersect (const COLLECTION2 &other)
 
Bool Intersects (const COLLECTION2 &other) const
 
MAXON_ATTRIBUTE_FORCE_INLINE Result< void > CopyFromImpl (COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags, OverloadRank0)
 
Result< void > AppendAllImpl (COLLECTION2 &&other, COLLECTION_RESIZE_FLAGS resizeFlags, Bool overwrite, OverloadRank0)
 
Result< void > IntersectImpl (COLLECTION2 &&other, OverloadRank0)
 
MAXON_ATTRIBUTE_FORCE_INLINE Bool IsEmpty () const
 
MAXON_ATTRIBUTE_FORCE_INLINE Bool IsPopulated () const
 
String ToString (const FormatStatement *formatStatement) const
 
MAXON_ATTRIBUTE_FORCE_INLINE Bool ContainsAll (COLLECTION2 &&other) const
 
Bool ContainsAllImpl (COLLECTION2 &&other, OverloadRank0) const
 

Protected Member Functions

Bool ResizeTableImpl (Int length)
 
EntryAddEntryImpl (Entry *e, Entry *prev, Bool &created, Bool multi, void *)
 
EntryAddEntryImpl (Entry *e, Entry *prev, Bool &created, Bool multi, Char *)
 
 MAXON_DISALLOW_COPY_AND_ASSIGN (HashMap)
 
const CharGetSignature (void *) const
 
const CharGetSignature (Char *) const
 

Static Protected Member Functions

static EntryLoadRelaxed (AtomicPtr< Entry > &e)
 
static EntryLoadAcquire (AtomicPtr< Entry > &e)
 
static void StoreRelaxed (AtomicPtr< Entry > &e, Entry *newValue)
 
static Bool TryCompareAndSwap (AtomicPtr< Entry > &e, Entry *newValue, Entry *compare)
 
static EntryLoadRelaxed (Entry *e)
 
static EntryLoadAcquire (Entry *e)
 
static void StoreRelaxed (Entry *&e, Entry *newValue)
 
static Bool TryCompareAndSwap (Entry *&e, Entry *newValue, Entry *compare)
 

Protected Attributes

ALLOCATOR _allocator
 
Bucket_table
 
Int _tableLengthM1
 
Bucket ** _nonemptyBuckets
 
Int _nonemptyBucketCount
 
Int _size
 
Int _resizeThreshold
 
const Float _loadFactor
 

Additional Inherited Members

- Static Public Member Functions inherited from MapBase0< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, K, V, EmptyClass, HASH >
static const K & GetMapKey (const K &key)
 
static const K & GetMapKey (const PAIR &pair)
 
- Static Public Attributes inherited from MapBase0< HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >, K, V, EmptyClass, HASH >
static const COLLECTION_KIND KIND
 

Member Typedef Documentation

◆ Super

using Super = MapBase<HashMap, K, V, EmptyClass, HASH>

◆ HashType

using HashType = HASH

◆ IsHashMap

using IsHashMap = std::true_type

◆ Iterator

◆ ConstIterator

◆ KeyIterator

◆ ConstKeyIterator

◆ ValueIterator

◆ ConstValueIterator

Constructor & Destructor Documentation

◆ HashMap() [1/3]

HashMap ( Float  loadFactor = Float(SYNCHRONIZED ? 0 : 0.65))
explicit

Constructs a new HashMap with an optional load factor. This will not allocate any memory. Memory allocation can be done explicitly by SetCapacityHint(), or it will be done implicitly when needed.

Parameters
[in]loadFactorThe load factor of the HashMap.

◆ HashMap() [2/3]

HashMap ( const ALLOCATOR &  alloc,
Float  loadFactor = Float(SYNCHRONIZED ? 0 : 0.65) 
)
explicit

Initializes the underlying allocator and constructs a new HashMap with an optional load factor. This will not allocate any memory. Memory allocation can be done explicitly by SetCapacityHint(), or it will be done implicitly when needed.

Parameters
[in]allocUsed to initialize the underlying allocator by its copy constructor.
[in]loadFactorThe load factor of the HashMap.

◆ ~HashMap()

~HashMap ( )

Destructs all entries and frees any allocated memory.

◆ HashMap() [3/3]

HashMap ( HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED > &&  src)

Member Function Documentation

◆ MAXON_OPERATOR_MOVE_ASSIGNMENT()

MAXON_OPERATOR_MOVE_ASSIGNMENT ( HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >  )

◆ SetCapacityHint()

Ensures that the bucket table is large enough to hold at least capacity entries, taking into account the load factor (see explanation of the class HashMap itself).

Parameters
[in]capacityThe number of entries which can be stored without the need for re-hashing.
[in]resizeFlagsNot used by HashMap.
Returns
True if memory allocations succeeded.

◆ ResizeTable()

ResultMem ResizeTable ( Int  capacity)

Resizes the bucket table of the HashMap. Usually, with a positive load factor, this is done automatically when needed. You can force a resize if you know that a large number of entries will be added, this will eliminate some intermediate resizings. For a non-positive load factor, you have to manually resize the table if advisable. This function can also be used to reduce the table size (it gets never reduced automatically).

Parameters
[in]capacityThe number of entries which can be stored without the need for re-hashing.
Returns
True if memory allocations succeeded. If not, the HashMap will still be in a valid state, but still with the previous table size.

◆ Reset()

void Reset ( void  )

Resets the map. This destructs all entries and frees any memory held by the map, so the map will be in a state as if it had been newly constructed.

See also
Flush()

◆ Flush()

void Flush ( void  )

Flushes the map. This destructs and frees all entries, but does not free the bucket table.

See also
Reset()

◆ GetCount()

Int GetCount ( void  ) const

Returns the number of entries in this map.

Returns
Number of entries.

◆ GetTableSize()

Int GetTableSize ( ) const

Returns the current size of the bucket table.

Returns
Size of bucket table.

◆ GetMemorySize()

Int GetMemorySize ( void  ) const

Calculates the memory usage for this map. Keys and Values must have a public member GetMemorySize that return the element size.

Returns
Memory size in bytes.

◆ GetNonEmptyBucketCount()

Int GetNonEmptyBucketCount ( ) const

Returns the number of non-empty buckets in this map. This can be used together with GetNonEmptyBucket() to iterate over non-empty buckets.

Returns
Number of non-empty buckets.

◆ GetNonEmptyBucket() [1/2]

Entry* GetNonEmptyBucket ( Int  i)

Returns the i-th non-empty bucket of this map.

Parameters
[in]iIndex into the list of non-empty buckets (from 0 to GetNonEmptyBucketCount() - 1)
Returns
I-th non-empty bucket.

◆ GetNonEmptyBucket() [2/2]

const Entry* GetNonEmptyBucket ( Int  i) const

Returns the i-th non-empty bucket of this map.

Parameters
[in]iIndex into the list of non-empty buckets (from 0 to GetNonEmptyBucketCount() - 1)
Returns
I-th non-empty bucket.

◆ GetOperationCountForSearch()

Int GetOperationCountForSearch ( ) const

Returns an estimate of the number of operations needed to locate a given key in this map. This is used when two collections are compared: The iteration goes over the collection which would require more operations for search, and each entry is searched in the other collection.

Returns
Estimate for the number of operations.

◆ IsEqualImpl()

SFINAEHelper<Bool, typename MAP::IsHashMap>::type IsEqualImpl ( const MAP other,
COMPARE &&  cmp,
OverloadRank1   
) const

◆ Find() [1/2]

Entry* Find ( const KEY &  key)

Finds the entry with the given key in this map. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey to search for.
Returns
Entry having the given key, or nullptr if no such entry exists in this map.

◆ Find() [2/2]

const Entry* Find ( const KEY &  key) const

Finds the entry with the given key in this map. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey to search for.
Returns
Entry having the given key, or nullptr if no such entry exists in this map.

◆ FindValue() [1/2]

V* FindValue ( const KEY &  key)

Finds the value associated with the given key in this map. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey to search for.
Returns
Pointer to value for the given key, or nullptr if no entry exists for the key.

◆ FindValue() [2/2]

const V* FindValue ( const KEY &  key) const

Finds the value associated with the given key in this map. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey to search for.
Returns
Pointer to value for the given key, or nullptr if no entry exists for the key.

◆ InsertCtor()

Result<Entry*> InsertCtor ( KEY &&  key,
C &&  constructor,
Bool created = BoolLValue() 
)

Finds the entry with the given key, or creates such an entry if it doesn't exist yet. If a new entry has to be created, it is constructed with the help of the object passed to the constructor parameter: Its class C has to provide a function Int C::GetHashMapEntrySize(const K& key) to compute the size of a new entry for key and a function Result<void> C::ConstructHashMapEntry(void* ptr, UInt hash, const K& key) which uses the memory in ptr to construct a new entry for the key. If the constructor does not initialize the value of the new entry, this has to be done afterwards.

The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
CType of the constructor argument.
Parameters
[in]keyKey of the entry to find or create.
[in]constructorThe functions constructor.GetHashMapEntrySize(ptr, hash, key) and constructor.ConstructHashMapEntry(ptr, hash, key) will be used to construct a new entry from the memory in ptr.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Entry for the given key, or nullptr if the entry didn't exist and allocation of a new entry failed.

◆ InsertEntry() [1/3]

ResultRef<Entry> InsertEntry ( const K &  key,
Bool created = BoolLValue() 
)

Finds the entry with the given key, or creates such an entry if it doesn't exist yet. The value of a new entry has to be initialized afterwards (but its default constructor has already been invoked).

Parameters
[in]keyKey of the entry to find or create.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Entry for the given key, or nullptr if the entry didn't exist and allocation of a new entry failed.

◆ InsertEntry() [2/3]

ResultRef<Entry> InsertEntry ( K &&  key,
Bool created = BoolLValue() 
)

Finds the entry with the given key, or creates such an entry if it doesn't exist yet. The value of a new entry has to be initialized afterwards (but its default constructor has already been invoked).

Parameters
[in]keyKey of the entry to find or create. If a new entry is created, its key will be constructed by move-semantics if possible.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Entry for the given key, or nullptr if the entry didn't exist and allocation of a new entry failed.

◆ InsertEntry() [3/3]

ResultRef<Entry> InsertEntry ( KEY &&  key,
Bool created = BoolLValue() 
)

Finds the entry with the given key, or creates such an entry if it doesn't exist yet. The value of a new entry has to be initialized afterwards (but its default constructor has already been invoked). The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey of the entry to find or create.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Entry for the given key, or nullptr if the entry didn't exist and allocation of a new entry failed.

◆ InsertKey() [1/3]

ResultRef<V> InsertKey ( const K &  key,
Bool created = BoolLValue() 
)

Finds the value associated with the given key, or creates a corresponding entry if it doesn't exist yet. The value of a new entry has to be initialized afterwards (but its default constructor has already been invoked).

Parameters
[in]keyKey of the value to find or create.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Pointer to value for the given key, or nullptr if an entry didn't exist and allocation of a new entry failed.

◆ InsertKey() [2/3]

ResultRef<V> InsertKey ( K &&  key,
Bool created = BoolLValue() 
)

Finds the value associated with the given key, or creates a corresponding entry if it doesn't exist yet. The value of a new entry has to be initialized afterwards (but its default constructor has already been invoked).

Parameters
[in]keyKey of the entry to find or create. If a new entry is created, its key will be constructed by move-semantics if possible.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Pointer to value for the given key, or nullptr if an entry didn't exist and allocation of a new entry failed.

◆ InsertKey() [3/3]

ResultRef<V> InsertKey ( KEY &&  key,
Bool created = BoolLValue() 
)

Finds the value associated with the given key, or creates a corresponding entry if it doesn't exist yet. The value of a new entry has to be initialized afterwards (but its default constructor has already been invoked). The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey of the value to find or create.
[out]createdThis will be set to true if a new entry has been created successfully, otherwise it will be set to false.
Returns
Pointer to value for the given key, or nullptr if an entry didn't exist and allocation of a new entry failed.

◆ InsertLambda()

Result<Entry*> InsertLambda ( KEY &&  key,
LAMBDA &&  lambda 
)

Finds the entry with the given key, or creates such an entry if it doesn't exist yet. If a new entry has to be created, the passed lambda function is invoked with the newly created entry as Entry& argument in order to initialize the value of the entry. The lambda function has to return Result<void>, for example [](MyMap::Entry& e) -> Result<void> { e.SetValue(42); return OK; }.

The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
LAMBDAType of the function.
Parameters
[in]keyKey of the entry to find or create.
[in]lambdaThe function which will be invoked as return lambda(entry); to initialize the value of a newly created entry.
Returns
Entry for the given key, or nullptr if the entry didn't exist and allocation of a new entry failed.

◆ Insert() [1/2]

ResultRef<Entry> Insert ( KEY &&  key,
const V &  value,
Bool created = BoolLValue() 
)

Associates the given value with the given key. This adds a new entry for key if necessary, and then sets its value to the given value, whether the entry existed before or not. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey which shall map to the value.
[in]valueValue to which the key shall map.
[out]createdThis will be set to true if a new entry has been created, otherwise it will be set to false.
Returns
Entry for the key-value-association, or nullptr if such an entry didn't exist before and allocation of a new entry failed.

◆ Insert() [2/2]

ResultRef<Entry> Insert ( KEY &&  key,
V &&  value,
Bool created = BoolLValue() 
)

Associates the given value with the given key. This adds a new entry for key if necessary, and then sets its value to the given value, whether the entry existed before or not. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyKey which shall map to the value.
[in]valueValue to which the key shall map. It will be moved into the HashMap.
[out]createdThis will be set to true if a new entry has been created, otherwise it will be set to false.
Returns
Entry for the key-value-association, or nullptr if such an entry didn't exist before and allocation of a new entry failed.

◆ InsertMultiEntry() [1/2]

ResultRef<Entry> InsertMultiEntry ( KEY &&  key)

Adds an entry for the given key, even if an entry for the key already exists. In the latter case, the HashMap becomes a multi-map with more than one value per key. To iterate over all entries for a key, use FindAll() or Entry::GetNextWithSameKey(). The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key. Default is HASH.
KEYType of key.
Parameters
[in]keyKey of the entry to add.
Returns
Added entry for the given key, or nullptr if the allocation failed.

◆ InsertMultiEntry() [2/2]

ResultMem InsertMultiEntry ( Entry e,
UInt  hash 
)

Adds an entry for the given key, even if an entry for the key already exists. In the latter case, the HashMap becomes a multi-map with more than one value per key. To iterate over all entries for a key, use FindAll() or Entry::GetNextWithSameKey(). The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)) unless the default HASH class is already able to do so.

Parameters
[in]eEntry to add.
[in]hashHash value of the key.
Returns
OK on success.

◆ Erase() [1/6]

ResultOk<void> Erase ( const Entry entry,
Bool  deleteEntry = true 
)

Removes the given entry from this HashMap.

Parameters
[in]entryThe entry to remove.
[in]deleteEntryIf true (the default), the entry is also deleted, i.e., destructed and freed. If false, it won't be deleted, and you have to do this afterwards using DeleteEntry().
Returns
OK

◆ Erase() [2/6]

ResultOk<void> Erase ( Entry entry,
Bool  deleteEntry = true 
)

◆ Erase() [3/6]

ResultOk<void> Erase ( const Entry entry,
Bool  deleteEntry = true 
)

Removes the given entry from this HashMap.

Parameters
[in]entryThe entry to remove.
[in]deleteEntryIf true (the default), the entry is also deleted, i.e., destructed and freed. If false, it won't be deleted, and you have to do this afterwards using DeleteEntry().
Returns
OK

◆ Erase() [4/6]

ResultOk<void> Erase ( Entry entry,
Bool  deleteEntry = true 
)

◆ DeleteEntry()

void DeleteEntry ( const Entry e)

Deletes an entry which has been removed from this HashMap previously. You don't have to invoke this function yourself unless you removed an entry using Erase() with a value of false for the deleteEntry parameter.

Parameters
[in]eAn entry which has been removed from this HashMap previously, but not yet deleted.

◆ Erase() [5/6]

ResultOk<Bool> Erase ( const KEY &  key)

Removes an entry with the given key from this HashMap (if possible). In case of a multi-map, this only removes a single entry. The type KEY of the given key need not be the same as K, but then you have to provide an additional class KEYHASH to compute the hash code of the specified key (function KEYHASH::GetHashCode(const KEY&)), and to compare a key of type KEY with a key of type K for equality (function KEYHASH::IsEqual(const KEY&, const K&)) unless the default HASH class is already able to do so.

Template Parameters
KEYHASHHash class to compute the hash code of key, and to compare key with the map's keys. Default is HASH.
KEYType of key.
Parameters
[in]keyAn entry having this key shall be removed.
Returns
True if an entry was found and removed for #key, otherwise false.

◆ IntersectImpl()

Result<void> IntersectImpl ( SET &&  set,
OverloadRank0   
)

Removes all entries from this map whose keys are not contained in set. A key is in set if set.Contains(key) returns true, or if that is not a valid expression, if set(key) returns true. I.e., you can use a lambda expression as set.

Parameters
[in]setA set with which this map gets intersected. Can be a lambda expression.
Template Parameters
SETType of set.

◆ AppendAllImpl()

SFINAEHelper<Result<void>, typename std::remove_reference<S>::type::MapType>::type AppendAllImpl ( S &&  src,
COLLECTION_RESIZE_FLAGS  resizeFlags,
Bool  overwrite,
OverloadRank1   
)

◆ FindAll() [1/2]

MultiEntryIterator<false> FindAll ( const K &  key)

Returns a foreach iterator to iterate over all entries having the given key. This is only needed for a multi-map.

Parameters
[in]keyKey to search for.
Returns
Iterator which yields all entries having the given key.

◆ FindAll() [2/2]

MultiEntryIterator<true> FindAll ( const K &  key) const

Returns a foreach iterator to iterate over all entries having the given key. This is only needed for a multi-map.

Parameters
[in]keyKey to search for.
Returns
Iterator which yields all entries having the given key.

◆ GetKeys() [1/2]

KeyIterator GetKeys ( )

Returns a foreach iterator to iterate over all keys of this map.

Returns
Foreach iterator over all keys.

◆ GetKeys() [2/2]

ConstKeyIterator GetKeys ( ) const

Returns a foreach iterator to iterate over all keys of this map.

Returns
Foreach iterator over all keys.

◆ GetValues() [1/2]

ValueIterator GetValues ( )

Returns a foreach iterator to iterate over all values of this map.

Returns
Foreach iterator over all values.

◆ GetValues() [2/2]

ConstValueIterator GetValues ( ) const

Returns a foreach iterator to iterate over all values of this map.

Returns
Foreach iterator over all values.

◆ Begin() [1/2]

Iterator Begin ( )

◆ End() [1/2]

Iterator End ( )

◆ Begin() [2/2]

ConstIterator Begin ( ) const

◆ End() [2/2]

ConstIterator End ( ) const

◆ Erase() [6/6]

IteratorTemplate<SUPER> Erase ( const IteratorTemplate< SUPER > &  it,
Bool  deleteEntry = true 
)

◆ GetIterator() [1/2]

Iterator GetIterator ( const Entry e)

◆ GetIterator() [2/2]

ConstIterator GetIterator ( const Entry e) const

◆ ToString()

SFINAEHelper<String, V>::type ToString ( const FormatStatement formatStatement) const

◆ FindEntryImpl() [1/2]

const Entry* FindEntryImpl ( UInt  hash,
const KEY &  key 
) const

◆ FindEntryImpl() [2/2]

Entry* FindEntryImpl ( UInt  hash,
const KEY &  key 
)

◆ ResizeTableImpl()

Bool ResizeTableImpl ( Int  length)
protected

◆ AddEntryImpl() [1/2]

Entry* AddEntryImpl ( Entry e,
Entry prev,
Bool created,
Bool  multi,
void *   
)
protected

◆ AddEntryImpl() [2/2]

Entry* AddEntryImpl ( Entry e,
Entry prev,
Bool created,
Bool  multi,
Char  
)
protected

◆ MAXON_DISALLOW_COPY_AND_ASSIGN()

MAXON_DISALLOW_COPY_AND_ASSIGN ( HashMap< K, V, HASH, ENTRY_HANDLER, ALLOCATOR, SYNCHRONIZED >  )
protected

◆ LoadRelaxed() [1/2]

static Entry* LoadRelaxed ( AtomicPtr< Entry > &  e)
staticprotected

◆ LoadAcquire() [1/2]

static Entry* LoadAcquire ( AtomicPtr< Entry > &  e)
staticprotected

◆ StoreRelaxed() [1/2]

static void StoreRelaxed ( AtomicPtr< Entry > &  e,
Entry newValue 
)
staticprotected

◆ TryCompareAndSwap() [1/2]

static Bool TryCompareAndSwap ( AtomicPtr< Entry > &  e,
Entry newValue,
Entry compare 
)
staticprotected

◆ LoadRelaxed() [2/2]

static Entry* LoadRelaxed ( Entry e)
staticprotected

◆ LoadAcquire() [2/2]

static Entry* LoadAcquire ( Entry e)
staticprotected

◆ StoreRelaxed() [2/2]

static void StoreRelaxed ( Entry *&  e,
Entry newValue 
)
staticprotected

◆ TryCompareAndSwap() [2/2]

static Bool TryCompareAndSwap ( Entry *&  e,
Entry newValue,
Entry compare 
)
staticprotected

◆ GetSignature() [1/2]

const Char* GetSignature ( void *  ) const
protected

◆ GetSignature() [2/2]

const Char* GetSignature ( Char ) const
protected

Member Data Documentation

◆ _allocator

ALLOCATOR _allocator
protected

The allocator to use.

◆ _table

Bucket* _table
protected

Pointer to the bucket table.

◆ _tableLengthM1

Int _tableLengthM1
protected

Length - 1 of the bucket table.

◆ _nonemptyBuckets

Bucket** _nonemptyBuckets
protected

Pointer to the array of pointers to non-empty buckets.

◆ _nonemptyBucketCount

Int _nonemptyBucketCount
protected

Number of non-empty buckets.

◆ _size

Int _size
protected

Number of entries in this HashMap.

◆ _resizeThreshold

Int _resizeThreshold
protected

When _size exceeds this threshold, a re-hashing has to be done to satisfy the load factor setting.

◆ _loadFactor

const Float _loadFactor
protected

Load factor: At most tableLength * loadFactor entries may be in this HashMap, otherwise a re-hashing is done. If non-positive, no automatic re-hashing happens.