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
25#pragma GCC visibility push(default)
26namespace Minisat {
27namespace Internal {
28
29//=================================================================================================
30// Default hash/equals functions
31//
32
33template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
34template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
35
36template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
37template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
38
39static inline uint32_t hash(uint32_t x){ return x; }
40static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
41static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
42static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
43
44
45//=================================================================================================
46// Some primes
47//
48
49static const int nprimes = 25;
50static 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 };
51
52//=================================================================================================
53// Hash table implementation of Maps
54//
55
56template<class K, class D, class H = Hash<K>, class E = Equal<K> >
57class Map {
58 public:
59 struct Pair { K key; D data; };
60
61 private:
64
66 int cap;
67 int size;
68
69 // Don't allow copying (error prone):
70 Map<K,D,H,E>& operator = (Map<K,D,H,E>& other) { assert(0); }
71 Map (Map<K,D,H,E>& other) { assert(0); }
72
73 bool checkCap(int new_size) const { return new_size > cap; }
74
75 int32_t index (const K& k) const { return hash(k) % cap; }
76 void _insert (const K& k, const D& d) {
77 vec<Pair>& ps = table[index(k)];
78 ps.push(); ps.last().key = k; ps.last().data = d; }
79
80 void rehash () {
81 const vec<Pair>* old = table;
82
83 int old_cap = cap;
84 int newsize = primes[0];
85 for (int i = 1; newsize <= cap && i < nprimes; i++)
86 newsize = primes[i];
87
88 table = new vec<Pair>[newsize];
89 cap = newsize;
90
91 for (int i = 0; i < old_cap; i++){
92 for (int j = 0; j < old[i].size(); j++){
93 _insert(old[i][j].key, old[i][j].data); }}
94
95 delete [] old;
96
97#if 0
98 printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
99#endif
100 }
101
102
103 public:
104
105 Map() : table(nullptr), cap(0), size(0) {}
106 Map(const H& h, const E& e) : hash(h), equals(e), table(nullptr), cap(0), size(0){}
107 ~Map () { delete [] table; }
108
109 // PRECONDITION: the key must already exist in the map.
110 const D& operator [] (const K& k) const
111 {
112 assert(size != 0);
113 const D* res = nullptr;
114 const vec<Pair>& ps = table[index(k)];
115 for (int i = 0; i < ps.size(); i++)
116 if (equals(ps[i].key, k))
117 res = &ps[i].data;
118 assert(res != nullptr);
119 return *res;
120 }
121
122 // PRECONDITION: the key must already exist in the map.
123 D& operator [] (const K& k)
124 {
125 assert(size != 0);
126 D* res = nullptr;
127 vec<Pair>& ps = table[index(k)];
128 for (int i = 0; i < ps.size(); i++)
129 if (equals(ps[i].key, k))
130 res = &ps[i].data;
131 assert(res != nullptr);
132 return *res;
133 }
134
135 // PRECONDITION: the key must *NOT* exist in the map.
136 void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
137 bool peek (const K& k, D& d) const {
138 if (size == 0) return false;
139 const vec<Pair>& ps = table[index(k)];
140 for (int i = 0; i < ps.size(); i++)
141 if (equals(ps[i].key, k)){
142 d = ps[i].data;
143 return true; }
144 return false;
145 }
146
147 bool has (const K& k) const {
148 if (size == 0) return false;
149 const vec<Pair>& ps = table[index(k)];
150 for (int i = 0; i < ps.size(); i++)
151 if (equals(ps[i].key, k))
152 return true;
153 return false;
154 }
155
156 // PRECONDITION: the key must exist in the map.
157 void remove(const K& k) {
158 assert(table != nullptr);
159 vec<Pair>& ps = table[index(k)];
160 int j = 0;
161 for (; j < ps.size() && !equals(ps[j].key, k); j++);
162 assert(j < ps.size());
163 ps[j] = ps.last();
164 ps.pop();
165 size--;
166 }
167
168 void clear () {
169 cap = size = 0;
170 delete [] table;
171 table = nullptr;
172 }
173
174 int elems() const { return size; }
175 int bucket_count() const { return cap; }
176
177 // NOTE: the hash and equality objects are not moved by this method:
178 void moveTo(Map& other){
179 delete [] other.table;
180
181 other.table = table;
182 other.cap = cap;
183 other.size = size;
184
185 table = nullptr;
186 size = cap = 0;
187 }
188
189 // NOTE: given a bit more time, I could make a more C++-style iterator out of this:
190 const vec<Pair>& bucket(int i) const { return table[i]; }
191};
192
193//=================================================================================================
194} // namespace Internal
195} // namespace Minisat
196#pragma GCC visibility pop
bool checkCap(int new_size) const
Definition Map.h:73
bool peek(const K &k, D &d) const
Definition Map.h:137
vec< Pair > * table
Definition Map.h:65
void insert(const K &k, const D &d)
Definition Map.h:136
Map< K, D, H, E > & operator=(Map< K, D, H, E > &other)
Definition Map.h:70
void _insert(const K &k, const D &d)
Definition Map.h:76
int32_t index(const K &k) const
Definition Map.h:75
int elems() const
Definition Map.h:174
int bucket_count() const
Definition Map.h:175
bool has(const K &k) const
Definition Map.h:147
const vec< Pair > & bucket(int i) const
Definition Map.h:190
Map(Map< K, D, H, E > &other)
Definition Map.h:71
Map(const H &h, const E &e)
Definition Map.h:106
void moveTo(Map &other)
Definition Map.h:178
void remove(const K &k)
Definition Map.h:157
const D & operator[](const K &k) const
Definition Map.h:110
int size(void) const
Definition Vec.h:64
void pop(void)
Definition Vec.h:77
void push(void)
Definition Vec.h:74
const T & last(void) const
Definition Vec.h:83
static const int primes[nprimes]
Definition Map.h:50
static const int nprimes
Definition Map.h:49
static uint32_t hash(uint32_t x)
Definition Map.h:39
bool operator()(const K *k1, const K *k2) const
Definition Map.h:37
uint32_t operator()(const K *k) const
Definition Map.h:36
bool operator()(const K &k1, const K &k2) const
Definition Map.h:34
uint32_t operator()(const K &k) const
Definition Map.h:33