Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Map.h
Go to the documentation of this file.
1 /*******************************************************************************************[Map.h]
2 Copyright (c) 2006-2010, Niklas Sorensson
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5 associated documentation files (the "Software"), to deal in the Software without restriction,
6 including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 furnished to do so, subject to the following conditions:
9 
10 The above copyright notice and this permission notice shall be included in all copies or
11 substantial portions of the Software.
12 
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 **************************************************************************************************/
19 
20 #pragma once
21 
24 
25 namespace Minisat {
26 namespace Internal {
27 
28 //=================================================================================================
29 // Default hash/equals functions
30 //
31 
32 template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
33 template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
34 
35 template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
36 template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
37 
38 static inline uint32_t hash(uint32_t x){ return x; }
39 static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
40 static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
41 static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
42 
43 
44 //=================================================================================================
45 // Some primes
46 //
47 
48 static const int nprimes = 25;
49 static 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 
55 template<class K, class D, class H = Hash<K>, class E = Equal<K> >
56 class Map {
57  public:
58  struct Pair { K key; D data; };
59 
60  private:
61  H hash;
62  E equals;
63 
65  int cap;
66  int size;
67 
68  // Don't allow copying (error prone):
69  Map<K,D,H,E>& operator = (Map<K,D,H,E>& other) { assert(0); }
70  Map (Map<K,D,H,E>& other) { assert(0); }
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:
177  void moveTo(Map& other){
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
Vec.h
Minisat::Internal::Map::rehash
void rehash()
Definition: Map.h:79
Minisat::Internal::Map::elems
int elems() const
Definition: Map.h:173
Minisat::Internal::DeepEqual::operator()
bool operator()(const K *k1, const K *k2) const
Definition: Map.h:36
Minisat::Internal::Map::Pair::data
D data
Definition: Map.h:58
Minisat::Internal::DeepEqual
Definition: Map.h:36
Minisat::Internal::Map::hash
H hash
Definition: Map.h:61
Minisat::Internal::Equal::operator()
bool operator()(const K &k1, const K &k2) const
Definition: Map.h:33
Minisat::Internal::Map
Definition: Map.h:56
Minisat::Internal::Map::checkCap
bool checkCap(int new_size) const
Definition: Map.h:72
Minisat::Internal::Map::moveTo
void moveTo(Map &other)
Definition: Map.h:177
Minisat::Internal::Map::peek
bool peek(const K &k, D &d) const
Definition: Map.h:136
Minisat::Internal::Map::bucket
const vec< Pair > & bucket(int i) const
Definition: Map.h:189
Minisat::Internal::nprimes
static const int nprimes
Definition: Map.h:48
IntTypes.h
Minisat::Internal::vec::size
int size(void) const
Definition: Vec.h:63
Minisat::Internal::Map::Map
Map(const H &h, const E &e)
Definition: Map.h:105
Minisat::Internal::vec::push
void push(void)
Definition: Vec.h:73
Minisat::Internal::Map::size
int size
Definition: Map.h:66
Minisat::Internal::Map::Pair::key
K key
Definition: Map.h:58
Minisat::Internal::Map::~Map
~Map()
Definition: Map.h:106
Minisat::Internal::vec::pop
void pop(void)
Definition: Vec.h:76
Minisat::Internal::primes
static const int primes[nprimes]
Definition: Map.h:49
Minisat::Internal::Map::cap
int cap
Definition: Map.h:65
Minisat
Definition: Minisat.h:48
Minisat::Internal::Map::Map
Map(Map< K, D, H, E > &other)
Definition: Map.h:70
Minisat::Internal::Map::insert
void insert(const K &k, const D &d)
Definition: Map.h:135
Minisat::Internal::DeepHash
Definition: Map.h:35
Minisat::Internal::Map::remove
void remove(const K &k)
Definition: Map.h:156
Minisat::Internal::Hash::operator()
uint32_t operator()(const K &k) const
Definition: Map.h:32
Minisat::Internal::vec
Definition: Vec.h:38
Minisat::Internal::Map::index
int32_t index(const K &k) const
Definition: Map.h:74
Minisat::Internal::Hash
Definition: Map.h:32
Minisat::Internal::Map::bucket_count
int bucket_count() const
Definition: Map.h:174
Minisat::Internal::DeepHash::operator()
uint32_t operator()(const K *k) const
Definition: Map.h:35
Minisat::Internal::Map::equals
E equals
Definition: Map.h:62
Minisat::Internal::Map::Map
Map()
Definition: Map.h:104
Minisat::Internal::vec::last
const T & last(void) const
Definition: Vec.h:82
Minisat::Internal::Map::has
bool has(const K &k) const
Definition: Map.h:146
Minisat::Internal::Map::table
vec< Pair > * table
Definition: Map.h:64
Minisat::Internal::Map::Pair
Definition: Map.h:58
Minisat::Internal::Map::operator=
Map< K, D, H, E > & operator=(Map< K, D, H, E > &other)
Definition: Map.h:69
Minisat::Internal::Map::clear
void clear()
Definition: Map.h:167
Minisat::Internal::hash
static uint32_t hash(uint32_t x)
Definition: Map.h:38
Minisat::Internal::Map::_insert
void _insert(const K &k, const D &d)
Definition: Map.h:75
Minisat::Internal::Map::operator[]
const D & operator[](const K &k) const
Definition: Map.h:109
Minisat::Internal::vec::data
T * data
Definition: Vec.h:39
Minisat::Internal::Equal
Definition: Map.h:33