mCRL2
Loading...
Searching...
No Matches
sim_hashtable.cpp
Go to the documentation of this file.
1// Author(s): Bas Ploeger
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
11
12#define NOT_FOUND (std::size_t)(-1)
13#define END_OF_LIST (std::size_t)(-1)
14#define REMOVED (std::size_t)(-2)
15
16/* ---------------- hash_table_iterator ----------------------------- */
17
19 : hash_table(ht)
20{
21 bucket_it = hash_table->buckets.begin();
22 while (bucket_it != hash_table->buckets.end()
23 && (bucket_it->next == REMOVED))
24 {
25 ++bucket_it;
26 }
27}
28
30{
31 if (bucket_it != hash_table->buckets.end())
32 {
33 ++bucket_it;
34 while (bucket_it != hash_table->buckets.end()
35 && (bucket_it->next == REMOVED))
36 {
37 ++bucket_it;
38 }
39 }
40}
41
43 : hash_table(ht)
44{
45 bucket_it = hash_table->buckets.begin();
46 end = hash_table->buckets.end();
47 while (bucket_it != end && bucket_it->next == REMOVED)
48 {
49 ++bucket_it;
50 }
51}
52
54{
55 if (bucket_it != end)
56 {
57 ++bucket_it;
58 while (bucket_it != end && bucket_it->next == REMOVED)
59 {
60 ++bucket_it;
61 }
62 }
63}
64
65/* ---------------- hash_table -------------------------------------- */
66
67hash_table2::hash_table2(std::size_t initsize)
68{
69 mask = 1;
70 while (mask < initsize)
71 {
72 mask = mask << 1;
73 }
74 --mask;
75 clear();
76}
77
79{}
80
82{
83 table.assign(mask+1,END_OF_LIST);
84 buckets.clear();
85 removed_count = 0;
86}
87
88void hash_table2::add(std::size_t x,std::size_t y)
89{
90 std::size_t h = hash(x,y);
91 if (hfind(h,x,y) == NOT_FOUND)
92 {
93 if (check_table())
94 {
95 h = hash(x,y);
96 }
97 bucket2 new_bucket;
98 new_bucket.x = x;
99 new_bucket.y = y;
100 new_bucket.next = table[h];
101 table[h] = buckets.size();
102 buckets.push_back(new_bucket);
103 }
104}
105
106bool hash_table2::find(std::size_t x,std::size_t y)
107{
108 return (hfind(hash(x,y),x,y) != NOT_FOUND);
109}
110
111void hash_table2::remove(std::size_t x,std::size_t y)
112{
113 bucket2 b;
114 std::size_t i, prev_i;
115 std::size_t h = hash(x,y);
116 i = table[h];
117 if (i != END_OF_LIST)
118 {
119 b = buckets[i];
120 if (b.x == x && b.y == y)
121 {
122 table[h] = b.next;
123 buckets[i].next = REMOVED;
125 return;
126 }
127 prev_i = i;
128 i = b.next;
129 }
130 while (i != END_OF_LIST)
131 {
132 b = buckets[i];
133 if (b.x == x && b.y == y)
134 {
135 buckets[prev_i].next = buckets[i].next;
136 buckets[i].next = REMOVED;
138 return;
139 }
140 prev_i = i;
141 i = b.next;
142 }
143}
144
145std::size_t hash_table2::hfind(std::size_t h,std::size_t x,std::size_t y)
146{
147 std::size_t i = table[h];
148 bucket2 b;
149 while (i != END_OF_LIST)
150 {
151 b = buckets[i];
152 if (b.x == x && b.y == y)
153 {
154 return i;
155 }
156 i = b.next;
157 }
158 return NOT_FOUND;
159}
160
162{
163 if (4*(buckets.size() - removed_count) >= 3*table.size())
164 {
165 /* table is filled for at least 75%, so let's rehash! */
166 mask = (2*mask) + 1;
167 table.assign(mask+1,END_OF_LIST);
168 std::size_t h;
169 for (std::size_t i = 0; i < buckets.size(); ++i)
170 {
171 if (buckets[i].next != REMOVED)
172 {
173 h = hash(buckets[i].x,buckets[i].y);
174 buckets[i].next = table[h];
175 table[h] = i;
176 }
177 }
178 return true;
179 }
180 return false;
181}
182
183std::size_t hash_table2::hash(std::size_t x, std::size_t y)
184{
185 return ((159403*x + 389651*y) & mask);
186}
187
188hash_table3::hash_table3(std::size_t initsize)
189{
190 mask = 1;
191 while (mask < initsize)
192 {
193 mask = mask << 1;
194 }
195 --mask;
196 clear();
197}
198
200{}
201
203{
204 table.assign(mask+1,END_OF_LIST);
205 buckets.clear();
206 removed_count = 0;
207}
208
209void hash_table3::add(std::size_t x,std::size_t y,std::size_t z)
210{
211 std::size_t h = hash(x,y,z);
212 if (hfind(h,x,y,z) == NOT_FOUND)
213 {
214 if (check_table())
215 {
216 h = hash(x,y,z);
217 }
218 bucket3 new_bucket;
219 new_bucket.x = x;
220 new_bucket.y = y;
221 new_bucket.z = z;
222 new_bucket.next = table[h];
223 table[h] = buckets.size();
224 buckets.push_back(new_bucket);
225 }
226}
227
228bool hash_table3::find(std::size_t x,std::size_t y,std::size_t z)
229{
230 return (hfind(hash(x,y,z),x,y,z) != NOT_FOUND);
231}
232
233void hash_table3::remove(std::size_t x,std::size_t y,std::size_t z)
234{
235 bucket3 b;
236 std::size_t i, prev_i;
237 std::size_t h = hash(x,y,z);
238 i = table[h];
239 if (i != END_OF_LIST)
240 {
241 b = buckets[i];
242 if (b.x == x && b.y == y && b.z == z)
243 {
244 table[h] = b.next;
245 buckets[i].next = REMOVED;
247 return;
248 }
249 prev_i = i;
250 i = b.next;
251 }
252 while (i != END_OF_LIST)
253 {
254 b = buckets[i];
255 if (b.x == x && b.y == y && b.z == z)
256 {
257 buckets[prev_i].next = buckets[i].next;
258 buckets[i].next = REMOVED;
260 return;
261 }
262 prev_i = i;
263 i = b.next;
264 }
265}
266
267std::size_t hash_table3::hfind(std::size_t h,std::size_t x,std::size_t y,std::size_t z)
268{
269 std::size_t i = table[h];
270 bucket3 b;
271 while (i != END_OF_LIST)
272 {
273 b = buckets[i];
274 if (b.x == x && b.y == y && b.z == z)
275 {
276 return i;
277 }
278 i = b.next;
279 }
280 return NOT_FOUND;
281}
282
284{
285 if (4*(buckets.size() - removed_count) >= 3*table.size())
286 {
287 /* table is filled for at least 75%, so let's rehash! */
288 mask = (2*mask) + 1;
289 table.assign(mask+1,END_OF_LIST);
290 std::size_t h;
291 for (std::size_t i = 0; i < buckets.size(); ++i)
292 {
293 if (buckets[i].next != REMOVED)
294 {
295 h = hash(buckets[i].x,buckets[i].y,buckets[i].z);
296 buckets[i].next = table[h];
297 table[h] = i;
298 }
299 }
300 return true;
301 }
302 return false;
303}
304
305std::size_t hash_table3::hash(std::size_t x, std::size_t y, std::size_t z)
306{
307 return ((159403*x + 389651*y + 521503*z) & mask);
308}
hash_table2_iterator(hash_table2 *ht)
std::vector< bucket2 >::iterator bucket_it
hash_table2 * hash_table
std::vector< bucket2 > buckets
bool find(std::size_t x, std::size_t y)
std::size_t removed_count
std::size_t hash(std::size_t x, std::size_t y)
void remove(std::size_t x, std::size_t y)
void add(std::size_t x, std::size_t y)
std::size_t mask
std::size_t hfind(std::size_t h, std::size_t x, std::size_t y)
std::vector< std::size_t > table
hash_table2(std::size_t initsize)
std::vector< bucket3 >::iterator bucket_it
hash_table3_iterator(hash_table3 *ht)
std::vector< bucket3 >::iterator end
hash_table3 * hash_table
hash_table3(std::size_t initsize)
std::size_t hash(std::size_t x, std::size_t y, std::size_t z)
std::size_t mask
bool find(std::size_t x, std::size_t y, std::size_t z)
void remove(std::size_t x, std::size_t y, std::size_t z)
void add(std::size_t x, std::size_t y, std::size_t z)
std::size_t removed_count
std::vector< bucket3 > buckets
std::size_t hfind(std::size_t h, std::size_t x, std::size_t y, std::size_t z)
std::vector< std::size_t > table
#define NOT_FOUND
#define END_OF_LIST
#define REMOVED
Header file for hash table data structure used by the simulation preorder algorithm.
std::size_t next
std::size_t y
std::size_t x
std::size_t next
std::size_t z
std::size_t x
std::size_t y
#define hash(l, r, m)
Definition tree_set.cpp:23