1#pragma once
2
3#include <Common/HashTable/TwoLevelHashTable.h>
4#include <Common/HashTable/HashMap.h>
5
6
7template
8<
9 typename Key,
10 typename Cell,
11 typename Hash = DefaultHash<Key>,
12 typename Grower = TwoLevelHashTableGrower<>,
13 typename Allocator = HashTableAllocator,
14 template <typename ...> typename ImplTable = HashMapTable
15>
16class TwoLevelHashMapTable : public TwoLevelHashTable<Key, Cell, Hash, Grower, Allocator, ImplTable<Key, Cell, Hash, Grower, Allocator>>
17{
18public:
19 using Impl = ImplTable<Key, Cell, Hash, Grower, Allocator>;
20 using LookupResult = typename Impl::LookupResult;
21
22 using TwoLevelHashTable<Key, Cell, Hash, Grower, Allocator, ImplTable<Key, Cell, Hash, Grower, Allocator>>::TwoLevelHashTable;
23
24 template <typename Func>
25 void ALWAYS_INLINE forEachMapped(Func && func)
26 {
27 for (auto i = 0u; i < this->NUM_BUCKETS; ++i)
28 this->impls[i].forEachMapped(func);
29 }
30
31 typename Cell::Mapped & ALWAYS_INLINE operator[](const Key & x)
32 {
33 LookupResult it;
34 bool inserted;
35 this->emplace(x, it, inserted);
36
37 if (inserted)
38 new (&it->getMapped()) typename Cell::Mapped();
39
40 return it->getMapped();
41 }
42};
43
44
45template
46<
47 typename Key,
48 typename Mapped,
49 typename Hash = DefaultHash<Key>,
50 typename Grower = TwoLevelHashTableGrower<>,
51 typename Allocator = HashTableAllocator,
52 template <typename ...> typename ImplTable = HashMapTable
53>
54using TwoLevelHashMap = TwoLevelHashMapTable<Key, HashMapCell<Key, Mapped, Hash>, Hash, Grower, Allocator, ImplTable>;
55
56
57template
58<
59 typename Key,
60 typename Mapped,
61 typename Hash = DefaultHash<Key>,
62 typename Grower = TwoLevelHashTableGrower<>,
63 typename Allocator = HashTableAllocator,
64 template <typename ...> typename ImplTable = HashMapTable
65>
66using TwoLevelHashMapWithSavedHash = TwoLevelHashMapTable<Key, HashMapCellWithSavedHash<Key, Mapped, Hash>, Hash, Grower, Allocator, ImplTable>;
67