Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
Map.h
Go to the documentation of this file.
1/*******************************************************************************************[Map.h]
2Copyright (c) 2006-2010, Niklas Sorensson
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5associated documentation files (the "Software"), to deal in the Software without restriction,
6including without limitation the rights to use, copy, modify, merge, publish, distribute,
7sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in all copies or
11substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18**************************************************************************************************/
19
20#pragma once
21
24
25namespace Minisat {
26namespace Internal {
27
28//=================================================================================================
29// Default hash/equals functions
30//
31
32template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
33template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
34
35template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
36template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
37
38static inline uint32_t hash(uint32_t x){ return x; }
39static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
40static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
41static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
42
43
44//=================================================================================================
45// Some primes
46//
47
48static const int nprimes = 25;
49static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
50
51//=================================================================================================
52// Hash table implementation of Maps
53//
54
55template<class K, class D, class H = Hash<K>, class E = Equal<K> >
56class Map {
57 public:
58 struct Pair { K key; D data; };
59
60 private:
63
65 int cap;
66 int size;
67
68 // Don't allow copying (error prone):
71
72 bool checkCap(int new_size) const { return new_size > cap; }
73
74 int32_t index (const K& k) const { return hash(k) % cap; }
75 void _insert (const K& k, const D& d) {
76 vec<Pair>& ps = table[index(k)];
77 ps.push(); ps.last().key = k; ps.last().data = d; }
78
79 void rehash () {
80 const vec<Pair>* old = table;
81
82 int old_cap = cap;
83 int newsize = primes[0];
84 for (int i = 1; newsize <= cap && i < nprimes; i++)
85 newsize = primes[i];
86
87 table = new vec<Pair>[newsize];
88 cap = newsize;
89
90 for (int i = 0; i < old_cap; i++){
91 for (int j = 0; j < old[i].size(); j++){
92 _insert(old[i][j].key, old[i][j].data); }}
93
94 delete [] old;
95
96#if 0
97 printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
98#endif
99 }
100
101
102 public:
103
104 Map() : table(nullptr), cap(0), size(0) {}
105 Map(const H& h, const E& e) : hash(h), equals(e), table(nullptr), cap(0), size(0){}
106 ~Map () { delete [] table; }
107
108 // PRECONDITION: the key must already exist in the map.
109 const D& operator [] (const K& k) const
110 {
111 assert(size != 0);
112 const D* res = nullptr;
113 const vec<Pair>& ps = table[index(k)];
114 for (int i = 0; i < ps.size(); i++)
115 if (equals(ps[i].key, k))
116 res = &ps[i].data;
117 assert(res != nullptr);
118 return *res;
119 }
120
121 // PRECONDITION: the key must already exist in the map.
122 D& operator [] (const K& k)
123 {
124 assert(size != 0);
125 D* res = nullptr;
126 vec<Pair>& ps = table[index(k)];
127 for (int i = 0; i < ps.size(); i++)
128 if (equals(ps[i].key, k))
129 res = &ps[i].data;
130 assert(res != nullptr);
131 return *res;
132 }
133
134 // PRECONDITION: the key must *NOT* exist in the map.
135 void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
136 bool peek (const K& k, D& d) const {
137 if (size == 0) return false;
138 const vec<Pair>& ps = table[index(k)];
139 for (int i = 0; i < ps.size(); i++)
140 if (equals(ps[i].key, k)){
141 d = ps[i].data;
142 return true; }
143 return false;
144 }
145
146 bool has (const K& k) const {
147 if (size == 0) return false;
148 const vec<Pair>& ps = table[index(k)];
149 for (int i = 0; i < ps.size(); i++)
150 if (equals(ps[i].key, k))
151 return true;
152 return false;
153 }
154
155 // PRECONDITION: the key must exist in the map.
156 void remove(const K& k) {
157 assert(table != nullptr);
158 vec<Pair>& ps = table[index(k)];
159 int j = 0;
160 for (; j < ps.size() && !equals(ps[j].key, k); j++);
161 assert(j < ps.size());
162 ps[j] = ps.last();
163 ps.pop();
164 size--;
165 }
166
167 void clear () {
168 cap = size = 0;
169 delete [] table;
170 table = nullptr;
171 }
172
173 int elems() const { return size; }
174 int bucket_count() const { return cap; }
175
176 // NOTE: the hash and equality objects are not moved by this method:
178 delete [] other.table;
179
180 other.table = table;
181 other.cap = cap;
182 other.size = size;
183
184 table = nullptr;
185 size = cap = 0;
186 }
187
188 // NOTE: given a bit more time, I could make a more C++-style iterator out of this:
189 const vec<Pair>& bucket(int i) const { return table[i]; }
190};
191
192//=================================================================================================
193} // namespace Internal
194} // namespace Minisat
bool checkCap(int new_size) const
Definition Map.h:72
bool peek(const K &k, D &d) const
Definition Map.h:136
vec< Pair > * table
Definition Map.h:64
void insert(const K &k, const D &d)
Definition Map.h:135
Map< K, D, H, E > & operator=(Map< K, D, H, E > &other)
Definition Map.h:69
void _insert(const K &k, const D &d)
Definition Map.h:75
int32_t index(const K &k) const
Definition Map.h:74
int elems() const
Definition Map.h:173
int bucket_count() const
Definition Map.h:174
bool has(const K &k) const
Definition Map.h:146
const vec< Pair > & bucket(int i) const
Definition Map.h:189
Map(Map< K, D, H, E > &other)
Definition Map.h:70
Map(const H &h, const E &e)
Definition Map.h:105
void moveTo(Map &other)
Definition Map.h:177
void remove(const K &k)
Definition Map.h:156
const D & operator[](const K &k) const
Definition Map.h:109
void push(void)
Definition Vec.h:73
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
static const int primes[nprimes]
Definition Map.h:49
static const int nprimes
Definition Map.h:48
static uint32_t hash(uint32_t x)
Definition Map.h:38
bool operator()(const K *k1, const K *k2) const
Definition Map.h:36
uint32_t operator()(const K *k) const
Definition Map.h:35
bool operator()(const K &k1, const K &k2) const
Definition Map.h:33
uint32_t operator()(const K &k) const
Definition Map.h:32