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 #pragma GCC visibility push(default)
26 namespace Minisat {
27 namespace Internal {
28 
29 //=================================================================================================
30 // Default hash/equals functions
31 //
32 
33 template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
34 template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
35 
36 template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
37 template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
38 
39 static inline uint32_t hash(uint32_t x){ return x; }
40 static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
41 static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
42 static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
43 
44 
45 //=================================================================================================
46 // Some primes
47 //
48 
49 static const int nprimes = 25;
50 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 };
51 
52 //=================================================================================================
53 // Hash table implementation of Maps
54 //
55 
56 template<class K, class D, class H = Hash<K>, class E = Equal<K> >
57 class Map {
58  public:
59  struct Pair { K key; D data; };
60 
61  private:
62  H hash;
63  E equals;
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
Vec.h
Minisat::Internal::Map::rehash
void rehash()
Definition: Map.h:80
Minisat::Internal::Map::elems
int elems() const
Definition: Map.h:174
Minisat::Internal::DeepEqual::operator()
bool operator()(const K *k1, const K *k2) const
Definition: Map.h:37
Minisat::Internal::Map::Pair::data
D data
Definition: Map.h:59
Minisat::Internal::DeepEqual
Definition: Map.h:37
Minisat::Internal::Map::hash
H hash
Definition: Map.h:62
Minisat::Internal::Equal::operator()
bool operator()(const K &k1, const K &k2) const
Definition: Map.h:34
Minisat::Internal::Map
Definition: Map.h:57
Minisat::Internal::Map::checkCap
bool checkCap(int new_size) const
Definition: Map.h:73
Minisat::Internal::Map::moveTo
void moveTo(Map &other)
Definition: Map.h:178
Minisat::Internal::Map::peek
bool peek(const K &k, D &d) const
Definition: Map.h:137
Minisat::Internal::Map::bucket
const vec< Pair > & bucket(int i) const
Definition: Map.h:190
Minisat::Internal::nprimes
static const int nprimes
Definition: Map.h:49
IntTypes.h
Minisat::Internal::vec::size
int size(void) const
Definition: Vec.h:64
Minisat::Internal::Map::Map
Map(const H &h, const E &e)
Definition: Map.h:106
Minisat::Internal::vec::push
void push(void)
Definition: Vec.h:74
Minisat::Internal::Map::size
int size
Definition: Map.h:67
Minisat::Internal::Map::Pair::key
K key
Definition: Map.h:59
Minisat::Internal::Map::~Map
~Map()
Definition: Map.h:107
Minisat::Internal::vec::pop
void pop(void)
Definition: Vec.h:77
Minisat::Internal::primes
static const int primes[nprimes]
Definition: Map.h:50
Minisat::Internal::Map::cap
int cap
Definition: Map.h:66
Minisat
Definition: Minisat.h:55
Minisat::Internal::Map::Map
Map(Map< K, D, H, E > &other)
Definition: Map.h:71
Minisat::Internal::Map::insert
void insert(const K &k, const D &d)
Definition: Map.h:136
Minisat::Internal::DeepHash
Definition: Map.h:36
Minisat::Internal::Map::remove
void remove(const K &k)
Definition: Map.h:157
Minisat::Internal::Hash::operator()
uint32_t operator()(const K &k) const
Definition: Map.h:33
Minisat::Internal::vec
Definition: Vec.h:39
Minisat::Internal::Map::index
int32_t index(const K &k) const
Definition: Map.h:75
Minisat::Internal::Hash
Definition: Map.h:33
Minisat::Internal::Map::bucket_count
int bucket_count() const
Definition: Map.h:175
Minisat::Internal::DeepHash::operator()
uint32_t operator()(const K *k) const
Definition: Map.h:36
Minisat::Internal::Map::equals
E equals
Definition: Map.h:63
Minisat::Internal::Map::Map
Map()
Definition: Map.h:105
Minisat::Internal::vec::last
const T & last(void) const
Definition: Vec.h:83
Minisat::Internal::Map::has
bool has(const K &k) const
Definition: Map.h:147
Minisat::Internal::Map::table
vec< Pair > * table
Definition: Map.h:65
Minisat::Internal::Map::Pair
Definition: Map.h:59
Minisat::Internal::Map::operator=
Map< K, D, H, E > & operator=(Map< K, D, H, E > &other)
Definition: Map.h:70
Minisat::Internal::Map::clear
void clear()
Definition: Map.h:168
Minisat::Internal::hash
static uint32_t hash(uint32_t x)
Definition: Map.h:39
Minisat::Internal::Map::_insert
void _insert(const K &k, const D &d)
Definition: Map.h:76
Minisat::Internal::Map::operator[]
const D & operator[](const K &k) const
Definition: Map.h:110
Minisat::Internal::vec::data
T * data
Definition: Vec.h:40
Minisat::Internal::Equal
Definition: Map.h:34