1 // This is free and unencumbered software released into the public domain.
2 //
3 // Anyone is free to copy, modify, publish, use, compile, sell, or
4 // distribute this software, either in source code form or as a compiled
5 // binary, for any purpose, commercial or non-commercial, and by any
6 // means.
7 
8 // -------------------------------------------------------
9 // Written by Claire Xenia Wolf <claire@yosyshq.com> in 2014
10 // -------------------------------------------------------
11 
12 #ifndef HASHLIB_H
13 #define HASHLIB_H
14 
15 #include <stdexcept>
16 #include <algorithm>
17 #include <string>
18 #include <vector>
19 
20 namespace hashlib {
21 
22 const int hashtable_size_trigger = 2;
23 const int hashtable_size_factor = 3;
24 
25 // The XOR version of DJB2
mkhash(unsigned int a,unsigned int b)26 inline unsigned int mkhash(unsigned int a, unsigned int b) {
27 	return ((a << 5) + a) ^ b;
28 }
29 
30 // traditionally 5381 is used as starting value for the djb2 hash
31 const unsigned int mkhash_init = 5381;
32 
33 // The ADD version of DJB2
34 // (use this version for cache locality in b)
mkhash_add(unsigned int a,unsigned int b)35 inline unsigned int mkhash_add(unsigned int a, unsigned int b) {
36 	return ((a << 5) + a) + b;
37 }
38 
mkhash_xorshift(unsigned int a)39 inline unsigned int mkhash_xorshift(unsigned int a) {
40 	if (sizeof(a) == 4) {
41 		a ^= a << 13;
42 		a ^= a >> 17;
43 		a ^= a << 5;
44 	} else if (sizeof(a) == 8) {
45 		a ^= a << 13;
46 		a ^= a >> 7;
47 		a ^= a << 17;
48 	} else
49 		throw std::runtime_error("mkhash_xorshift() only implemented for 32 bit and 64 bit ints");
50 	return a;
51 }
52 
53 template<typename T> struct hash_ops {
cmphash_ops54 	static inline bool cmp(const T &a, const T &b) {
55 		return a == b;
56 	}
hashhash_ops57 	static inline unsigned int hash(const T &a) {
58 		return a.hash();
59 	}
60 };
61 
62 struct hash_int_ops {
63 	template<typename T>
cmphash_int_ops64 	static inline bool cmp(T a, T b) {
65 		return a == b;
66 	}
67 };
68 
69 template<> struct hash_ops<bool> : hash_int_ops
70 {
71 	static inline unsigned int hash(bool a) {
72 		return a ? 1 : 0;
73 	}
74 };
75 template<> struct hash_ops<int32_t> : hash_int_ops
76 {
77 	static inline unsigned int hash(int32_t a) {
78 		return a;
79 	}
80 };
81 template<> struct hash_ops<int64_t> : hash_int_ops
82 {
83 	static inline unsigned int hash(int64_t a) {
84 		return mkhash((unsigned int)(a), (unsigned int)(a >> 32));
85 	}
86 };
87 
88 template<> struct hash_ops<std::string> {
89 	static inline bool cmp(const std::string &a, const std::string &b) {
90 		return a == b;
91 	}
92 	static inline unsigned int hash(const std::string &a) {
93 		unsigned int v = 0;
94 		for (auto c : a)
95 			v = mkhash(v, c);
96 		return v;
97 	}
98 };
99 
100 template<typename P, typename Q> struct hash_ops<std::pair<P, Q>> {
101 	static inline bool cmp(std::pair<P, Q> a, std::pair<P, Q> b) {
102 		return a == b;
103 	}
104 	static inline unsigned int hash(std::pair<P, Q> a) {
105 		return mkhash(hash_ops<P>::hash(a.first), hash_ops<Q>::hash(a.second));
106 	}
107 };
108 
109 template<typename... T> struct hash_ops<std::tuple<T...>> {
110 	static inline bool cmp(std::tuple<T...> a, std::tuple<T...> b) {
111 		return a == b;
112 	}
113 	template<size_t I = 0>
114 	static inline typename std::enable_if<I == sizeof...(T), unsigned int>::type hash(std::tuple<T...>) {
115 		return mkhash_init;
116 	}
117 	template<size_t I = 0>
118 	static inline typename std::enable_if<I != sizeof...(T), unsigned int>::type hash(std::tuple<T...> a) {
119 		typedef hash_ops<typename std::tuple_element<I, std::tuple<T...>>::type> element_ops_t;
120 		return mkhash(hash<I+1>(a), element_ops_t::hash(std::get<I>(a)));
121 	}
122 };
123 
124 template<typename T> struct hash_ops<std::vector<T>> {
125 	static inline bool cmp(std::vector<T> a, std::vector<T> b) {
126 		return a == b;
127 	}
128 	static inline unsigned int hash(std::vector<T> a) {
129 		unsigned int h = mkhash_init;
130 		for (auto k : a)
131 			h = mkhash(h, hash_ops<T>::hash(k));
132 		return h;
133 	}
134 };
135 
136 struct hash_cstr_ops {
137 	static inline bool cmp(const char *a, const char *b) {
138 		for (int i = 0; a[i] || b[i]; i++)
139 			if (a[i] != b[i])
140 				return false;
141 		return true;
142 	}
143 	static inline unsigned int hash(const char *a) {
144 		unsigned int hash = mkhash_init;
145 		while (*a)
146 			hash = mkhash(hash, *(a++));
147 		return hash;
148 	}
149 };
150 
151 struct hash_ptr_ops {
152 	static inline bool cmp(const void *a, const void *b) {
153 		return a == b;
154 	}
155 	static inline unsigned int hash(const void *a) {
156 		return (uintptr_t)a;
157 	}
158 };
159 
160 struct hash_obj_ops {
161 	static inline bool cmp(const void *a, const void *b) {
162 		return a == b;
163 	}
164 	template<typename T>
165 	static inline unsigned int hash(const T *a) {
166 		return a ? a->hash() : 0;
167 	}
168 };
169 
170 template<typename T>
171 inline unsigned int mkhash(const T &v) {
172 	return hash_ops<T>().hash(v);
173 }
174 
175 inline int hashtable_size(int min_size)
176 {
177 	static std::vector<int> zero_and_some_primes = {
178 		0, 23, 29, 37, 47, 59, 79, 101, 127, 163, 211, 269, 337, 431, 541, 677,
179 		853, 1069, 1361, 1709, 2137, 2677, 3347, 4201, 5261, 6577, 8231, 10289,
180 		12889, 16127, 20161, 25219, 31531, 39419, 49277, 61603, 77017, 96281,
181 		120371, 150473, 188107, 235159, 293957, 367453, 459317, 574157, 717697,
182 		897133, 1121423, 1401791, 1752239, 2190299, 2737937, 3422429, 4278037,
183 		5347553, 6684443, 8355563, 10444457, 13055587, 16319519, 20399411,
184 		25499291, 31874149, 39842687, 49803361, 62254207, 77817767, 97272239,
185 		121590311, 151987889, 189984863, 237481091, 296851369, 371064217
186 	};
187 
188 	for (auto p : zero_and_some_primes)
189 		if (p >= min_size) return p;
190 
191 	if (sizeof(int) == 4)
192 		throw std::length_error("hash table exceeded maximum size. use a ILP64 abi for larger tables.");
193 
194 	for (auto p : zero_and_some_primes)
195 		if (100129 * p > min_size) return 100129 * p;
196 
197 	throw std::length_error("hash table exceeded maximum size.");
198 }
199 
200 template<typename K, typename T, typename OPS = hash_ops<K>> class dict;
201 template<typename K, int offset = 0, typename OPS = hash_ops<K>> class idict;
202 template<typename K, typename OPS = hash_ops<K>> class pool;
203 template<typename K, typename OPS = hash_ops<K>> class mfp;
204 
205 template<typename K, typename T, typename OPS>
206 class dict
207 {
208 	struct entry_t
209 	{
210 		std::pair<K, T> udata;
211 		int next;
212 
213 		entry_t() { }
214 		entry_t(const std::pair<K, T> &udata, int next) : udata(udata), next(next) { }
215 		entry_t(std::pair<K, T> &&udata, int next) : udata(std::move(udata)), next(next) { }
216 		bool operator<(const entry_t &other) const { return udata.first < other.udata.first; }
217 	};
218 
219 	std::vector<int> hashtable;
220 	std::vector<entry_t> entries;
221 	OPS ops;
222 
223 #ifdef NDEBUG
224 	static inline void do_assert(bool) { }
225 #else
226 	static inline void do_assert(bool cond) {
227 		if (!cond) throw std::runtime_error("dict<> assert failed.");
228 	}
229 #endif
230 
231 	int do_hash(const K &key) const
232 	{
233 		unsigned int hash = 0;
234 		if (!hashtable.empty())
235 			hash = ops.hash(key) % (unsigned int)(hashtable.size());
236 		return hash;
237 	}
238 
239 	void do_rehash()
240 	{
241 		hashtable.clear();
242 		hashtable.resize(hashtable_size(entries.capacity() * hashtable_size_factor), -1);
243 
244 		for (int i = 0; i < int(entries.size()); i++) {
245 			do_assert(-1 <= entries[i].next && entries[i].next < int(entries.size()));
246 			int hash = do_hash(entries[i].udata.first);
247 			entries[i].next = hashtable[hash];
248 			hashtable[hash] = i;
249 		}
250 	}
251 
252 	int do_erase(int index, int hash)
253 	{
254 		do_assert(index < int(entries.size()));
255 		if (hashtable.empty() || index < 0)
256 			return 0;
257 
258 		int k = hashtable[hash];
259 		do_assert(0 <= k && k < int(entries.size()));
260 
261 		if (k == index) {
262 			hashtable[hash] = entries[index].next;
263 		} else {
264 			while (entries[k].next != index) {
265 				k = entries[k].next;
266 				do_assert(0 <= k && k < int(entries.size()));
267 			}
268 			entries[k].next = entries[index].next;
269 		}
270 
271 		int back_idx = entries.size()-1;
272 
273 		if (index != back_idx)
274 		{
275 			int back_hash = do_hash(entries[back_idx].udata.first);
276 
277 			k = hashtable[back_hash];
278 			do_assert(0 <= k && k < int(entries.size()));
279 
280 			if (k == back_idx) {
281 				hashtable[back_hash] = index;
282 			} else {
283 				while (entries[k].next != back_idx) {
284 					k = entries[k].next;
285 					do_assert(0 <= k && k < int(entries.size()));
286 				}
287 				entries[k].next = index;
288 			}
289 
290 			entries[index] = std::move(entries[back_idx]);
291 		}
292 
293 		entries.pop_back();
294 
295 		if (entries.empty())
296 			hashtable.clear();
297 
298 		return 1;
299 	}
300 
301 	int do_lookup(const K &key, int &hash) const
302 	{
303 		if (hashtable.empty())
304 			return -1;
305 
306 		if (entries.size() * hashtable_size_trigger > hashtable.size()) {
307 			((dict*)this)->do_rehash();
308 			hash = do_hash(key);
309 		}
310 
311 		int index = hashtable[hash];
312 
313 		while (index >= 0 && !ops.cmp(entries[index].udata.first, key)) {
314 			index = entries[index].next;
315 			do_assert(-1 <= index && index < int(entries.size()));
316 		}
317 
318 		return index;
319 	}
320 
321 	int do_insert(const K &key, int &hash)
322 	{
323 		if (hashtable.empty()) {
324 			entries.emplace_back(std::pair<K, T>(key, T()), -1);
325 			do_rehash();
326 			hash = do_hash(key);
327 		} else {
328 			entries.emplace_back(std::pair<K, T>(key, T()), hashtable[hash]);
329 			hashtable[hash] = entries.size() - 1;
330 		}
331 		return entries.size() - 1;
332 	}
333 
334 	int do_insert(const std::pair<K, T> &value, int &hash)
335 	{
336 		if (hashtable.empty()) {
337 			entries.emplace_back(value, -1);
338 			do_rehash();
339 			hash = do_hash(value.first);
340 		} else {
341 			entries.emplace_back(value, hashtable[hash]);
342 			hashtable[hash] = entries.size() - 1;
343 		}
344 		return entries.size() - 1;
345 	}
346 
347 	int do_insert(std::pair<K, T> &&rvalue, int &hash)
348 	{
349 		if (hashtable.empty()) {
350 			auto key = rvalue.first;
351 			entries.emplace_back(std::forward<std::pair<K, T>>(rvalue), -1);
352 			do_rehash();
353 			hash = do_hash(key);
354 		} else {
355 			entries.emplace_back(std::forward<std::pair<K, T>>(rvalue), hashtable[hash]);
356 			hashtable[hash] = entries.size() - 1;
357 		}
358 		return entries.size() - 1;
359 	}
360 
361 public:
362 	class const_iterator : public std::iterator<std::forward_iterator_tag, std::pair<K, T>>
363 	{
364 		friend class dict;
365 	protected:
366 		const dict *ptr;
367 		int index;
368 		const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { }
369 	public:
370 		const_iterator() { }
371 		const_iterator operator++() { index--; return *this; }
372 		const_iterator operator+=(int amt) { index -= amt; return *this; }
373 		bool operator<(const const_iterator &other) const { return index > other.index; }
374 		bool operator==(const const_iterator &other) const { return index == other.index; }
375 		bool operator!=(const const_iterator &other) const { return index != other.index; }
376 		const std::pair<K, T> &operator*() const { return ptr->entries[index].udata; }
377 		const std::pair<K, T> *operator->() const { return &ptr->entries[index].udata; }
378 	};
379 
380 	class iterator : public std::iterator<std::forward_iterator_tag, std::pair<K, T>>
381 	{
382 		friend class dict;
383 	protected:
384 		dict *ptr;
385 		int index;
386 		iterator(dict *ptr, int index) : ptr(ptr), index(index) { }
387 	public:
388 		iterator() { }
389 		iterator operator++() { index--; return *this; }
390 		iterator operator+=(int amt) { index -= amt; return *this; }
391 		bool operator<(const iterator &other) const { return index > other.index; }
392 		bool operator==(const iterator &other) const { return index == other.index; }
393 		bool operator!=(const iterator &other) const { return index != other.index; }
394 		std::pair<K, T> &operator*() { return ptr->entries[index].udata; }
395 		std::pair<K, T> *operator->() { return &ptr->entries[index].udata; }
396 		const std::pair<K, T> &operator*() const { return ptr->entries[index].udata; }
397 		const std::pair<K, T> *operator->() const { return &ptr->entries[index].udata; }
398 		operator const_iterator() const { return const_iterator(ptr, index); }
399 	};
400 
401 	dict()
402 	{
403 	}
404 
405 	dict(const dict &other)
406 	{
407 		entries = other.entries;
408 		do_rehash();
409 	}
410 
411 	dict(dict &&other)
412 	{
413 		swap(other);
414 	}
415 
416 	dict &operator=(const dict &other) {
417 		entries = other.entries;
418 		do_rehash();
419 		return *this;
420 	}
421 
422 	dict &operator=(dict &&other) {
423 		clear();
424 		swap(other);
425 		return *this;
426 	}
427 
428 	dict(const std::initializer_list<std::pair<K, T>> &list)
429 	{
430 		for (auto &it : list)
431 			insert(it);
432 	}
433 
434 	template<class InputIterator>
435 	dict(InputIterator first, InputIterator last)
436 	{
437 		insert(first, last);
438 	}
439 
440 	template<class InputIterator>
441 	void insert(InputIterator first, InputIterator last)
442 	{
443 		for (; first != last; ++first)
444 			insert(*first);
445 	}
446 
447 	std::pair<iterator, bool> insert(const K &key)
448 	{
449 		int hash = do_hash(key);
450 		int i = do_lookup(key, hash);
451 		if (i >= 0)
452 			return std::pair<iterator, bool>(iterator(this, i), false);
453 		i = do_insert(key, hash);
454 		return std::pair<iterator, bool>(iterator(this, i), true);
455 	}
456 
457 	std::pair<iterator, bool> insert(const std::pair<K, T> &value)
458 	{
459 		int hash = do_hash(value.first);
460 		int i = do_lookup(value.first, hash);
461 		if (i >= 0)
462 			return std::pair<iterator, bool>(iterator(this, i), false);
463 		i = do_insert(value, hash);
464 		return std::pair<iterator, bool>(iterator(this, i), true);
465 	}
466 
467 	std::pair<iterator, bool> insert(std::pair<K, T> &&rvalue)
468 	{
469 		int hash = do_hash(rvalue.first);
470 		int i = do_lookup(rvalue.first, hash);
471 		if (i >= 0)
472 			return std::pair<iterator, bool>(iterator(this, i), false);
473 		i = do_insert(std::forward<std::pair<K, T>>(rvalue), hash);
474 		return std::pair<iterator, bool>(iterator(this, i), true);
475 	}
476 
477 	std::pair<iterator, bool> emplace(K const &key, T const &value)
478 	{
479 		int hash = do_hash(key);
480 		int i = do_lookup(key, hash);
481 		if (i >= 0)
482 			return std::pair<iterator, bool>(iterator(this, i), false);
483 		i = do_insert(std::make_pair(key, value), hash);
484 		return std::pair<iterator, bool>(iterator(this, i), true);
485 	}
486 
487 	std::pair<iterator, bool> emplace(K const &key, T &&rvalue)
488 	{
489 		int hash = do_hash(key);
490 		int i = do_lookup(key, hash);
491 		if (i >= 0)
492 			return std::pair<iterator, bool>(iterator(this, i), false);
493 		i = do_insert(std::make_pair(key, std::forward<T>(rvalue)), hash);
494 		return std::pair<iterator, bool>(iterator(this, i), true);
495 	}
496 
497 	std::pair<iterator, bool> emplace(K &&rkey, T const &value)
498 	{
499 		int hash = do_hash(rkey);
500 		int i = do_lookup(rkey, hash);
501 		if (i >= 0)
502 			return std::pair<iterator, bool>(iterator(this, i), false);
503 		i = do_insert(std::make_pair(std::forward<K>(rkey), value), hash);
504 		return std::pair<iterator, bool>(iterator(this, i), true);
505 	}
506 
507 	std::pair<iterator, bool> emplace(K &&rkey, T &&rvalue)
508 	{
509 		int hash = do_hash(rkey);
510 		int i = do_lookup(rkey, hash);
511 		if (i >= 0)
512 			return std::pair<iterator, bool>(iterator(this, i), false);
513 		i = do_insert(std::make_pair(std::forward<K>(rkey), std::forward<T>(rvalue)), hash);
514 		return std::pair<iterator, bool>(iterator(this, i), true);
515 	}
516 
517 	int erase(const K &key)
518 	{
519 		int hash = do_hash(key);
520 		int index = do_lookup(key, hash);
521 		return do_erase(index, hash);
522 	}
523 
524 	iterator erase(iterator it)
525 	{
526 		int hash = do_hash(it->first);
527 		do_erase(it.index, hash);
528 		return ++it;
529 	}
530 
531 	int count(const K &key) const
532 	{
533 		int hash = do_hash(key);
534 		int i = do_lookup(key, hash);
535 		return i < 0 ? 0 : 1;
536 	}
537 
538 	int count(const K &key, const_iterator it) const
539 	{
540 		int hash = do_hash(key);
541 		int i = do_lookup(key, hash);
542 		return i < 0 || i > it.index ? 0 : 1;
543 	}
544 
545 	iterator find(const K &key)
546 	{
547 		int hash = do_hash(key);
548 		int i = do_lookup(key, hash);
549 		if (i < 0)
550 			return end();
551 		return iterator(this, i);
552 	}
553 
554 	const_iterator find(const K &key) const
555 	{
556 		int hash = do_hash(key);
557 		int i = do_lookup(key, hash);
558 		if (i < 0)
559 			return end();
560 		return const_iterator(this, i);
561 	}
562 
563 	T& at(const K &key)
564 	{
565 		int hash = do_hash(key);
566 		int i = do_lookup(key, hash);
567 		if (i < 0)
568 			throw std::out_of_range("dict::at()");
569 		return entries[i].udata.second;
570 	}
571 
572 	const T& at(const K &key) const
573 	{
574 		int hash = do_hash(key);
575 		int i = do_lookup(key, hash);
576 		if (i < 0)
577 			throw std::out_of_range("dict::at()");
578 		return entries[i].udata.second;
579 	}
580 
581 	const T& at(const K &key, const T &defval) const
582 	{
583 		int hash = do_hash(key);
584 		int i = do_lookup(key, hash);
585 		if (i < 0)
586 			return defval;
587 		return entries[i].udata.second;
588 	}
589 
590 	T& operator[](const K &key)
591 	{
592 		int hash = do_hash(key);
593 		int i = do_lookup(key, hash);
594 		if (i < 0)
595 			i = do_insert(std::pair<K, T>(key, T()), hash);
596 		return entries[i].udata.second;
597 	}
598 
599 	template<typename Compare = std::less<K>>
600 	void sort(Compare comp = Compare())
601 	{
602 		std::sort(entries.begin(), entries.end(), [comp](const entry_t &a, const entry_t &b){ return comp(b.udata.first, a.udata.first); });
603 		do_rehash();
604 	}
605 
606 	void swap(dict &other)
607 	{
608 		hashtable.swap(other.hashtable);
609 		entries.swap(other.entries);
610 	}
611 
612 	bool operator==(const dict &other) const {
613 		if (size() != other.size())
614 			return false;
615 		for (auto &it : entries) {
616 			auto oit = other.find(it.udata.first);
617 			if (oit == other.end() || !(oit->second == it.udata.second))
618 				return false;
619 		}
620 		return true;
621 	}
622 
623 	bool operator!=(const dict &other) const {
624 		return !operator==(other);
625 	}
626 
627 	unsigned int hash() const {
628 		unsigned int h = mkhash_init;
629 		for (auto &entry : entries) {
630 			h ^= hash_ops<K>::hash(entry.udata.first);
631 			h ^= hash_ops<T>::hash(entry.udata.second);
632 		}
633 		return h;
634 	}
635 
636 	void reserve(size_t n) { entries.reserve(n); }
637 	size_t size() const { return entries.size(); }
638 	bool empty() const { return entries.empty(); }
639 	void clear() { hashtable.clear(); entries.clear(); }
640 
641 	iterator begin() { return iterator(this, int(entries.size())-1); }
642 	iterator element(int n) { return iterator(this, int(entries.size())-1-n); }
643 	iterator end() { return iterator(nullptr, -1); }
644 
645 	const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
646 	const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
647 	const_iterator end() const { return const_iterator(nullptr, -1); }
648 };
649 
650 template<typename K, typename OPS>
651 class pool
652 {
653 	template<typename, int, typename> friend class idict;
654 
655 protected:
656 	struct entry_t
657 	{
658 		K udata;
659 		int next;
660 
661 		entry_t() { }
662 		entry_t(const K &udata, int next) : udata(udata), next(next) { }
663 		entry_t(K &&udata, int next) : udata(std::move(udata)), next(next) { }
664 	};
665 
666 	std::vector<int> hashtable;
667 	std::vector<entry_t> entries;
668 	OPS ops;
669 
670 #ifdef NDEBUG
671 	static inline void do_assert(bool) { }
672 #else
673 	static inline void do_assert(bool cond) {
674 		if (!cond) throw std::runtime_error("pool<> assert failed.");
675 	}
676 #endif
677 
678 	int do_hash(const K &key) const
679 	{
680 		unsigned int hash = 0;
681 		if (!hashtable.empty())
682 			hash = ops.hash(key) % (unsigned int)(hashtable.size());
683 		return hash;
684 	}
685 
686 	void do_rehash()
687 	{
688 		hashtable.clear();
689 		hashtable.resize(hashtable_size(entries.capacity() * hashtable_size_factor), -1);
690 
691 		for (int i = 0; i < int(entries.size()); i++) {
692 			do_assert(-1 <= entries[i].next && entries[i].next < int(entries.size()));
693 			int hash = do_hash(entries[i].udata);
694 			entries[i].next = hashtable[hash];
695 			hashtable[hash] = i;
696 		}
697 	}
698 
699 	int do_erase(int index, int hash)
700 	{
701 		do_assert(index < int(entries.size()));
702 		if (hashtable.empty() || index < 0)
703 			return 0;
704 
705 		int k = hashtable[hash];
706 		if (k == index) {
707 			hashtable[hash] = entries[index].next;
708 		} else {
709 			while (entries[k].next != index) {
710 				k = entries[k].next;
711 				do_assert(0 <= k && k < int(entries.size()));
712 			}
713 			entries[k].next = entries[index].next;
714 		}
715 
716 		int back_idx = entries.size()-1;
717 
718 		if (index != back_idx)
719 		{
720 			int back_hash = do_hash(entries[back_idx].udata);
721 
722 			k = hashtable[back_hash];
723 			if (k == back_idx) {
724 				hashtable[back_hash] = index;
725 			} else {
726 				while (entries[k].next != back_idx) {
727 					k = entries[k].next;
728 					do_assert(0 <= k && k < int(entries.size()));
729 				}
730 				entries[k].next = index;
731 			}
732 
733 			entries[index] = std::move(entries[back_idx]);
734 		}
735 
736 		entries.pop_back();
737 
738 		if (entries.empty())
739 			hashtable.clear();
740 
741 		return 1;
742 	}
743 
744 	int do_lookup(const K &key, int &hash) const
745 	{
746 		if (hashtable.empty())
747 			return -1;
748 
749 		if (entries.size() * hashtable_size_trigger > hashtable.size()) {
750 			((pool*)this)->do_rehash();
751 			hash = do_hash(key);
752 		}
753 
754 		int index = hashtable[hash];
755 
756 		while (index >= 0 && !ops.cmp(entries[index].udata, key)) {
757 			index = entries[index].next;
758 			do_assert(-1 <= index && index < int(entries.size()));
759 		}
760 
761 		return index;
762 	}
763 
764 	int do_insert(const K &value, int &hash)
765 	{
766 		if (hashtable.empty()) {
767 			entries.emplace_back(value, -1);
768 			do_rehash();
769 			hash = do_hash(value);
770 		} else {
771 			entries.emplace_back(value, hashtable[hash]);
772 			hashtable[hash] = entries.size() - 1;
773 		}
774 		return entries.size() - 1;
775 	}
776 
777 	int do_insert(K &&rvalue, int &hash)
778 	{
779 		if (hashtable.empty()) {
780 			entries.emplace_back(std::forward<K>(rvalue), -1);
781 			do_rehash();
782 			hash = do_hash(rvalue);
783 		} else {
784 			entries.emplace_back(std::forward<K>(rvalue), hashtable[hash]);
785 			hashtable[hash] = entries.size() - 1;
786 		}
787 		return entries.size() - 1;
788 	}
789 
790 public:
791 	class const_iterator : public std::iterator<std::forward_iterator_tag, K>
792 	{
793 		friend class pool;
794 	protected:
795 		const pool *ptr;
796 		int index;
797 		const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { }
798 	public:
799 		const_iterator() { }
800 		const_iterator operator++() { index--; return *this; }
801 		bool operator==(const const_iterator &other) const { return index == other.index; }
802 		bool operator!=(const const_iterator &other) const { return index != other.index; }
803 		const K &operator*() const { return ptr->entries[index].udata; }
804 		const K *operator->() const { return &ptr->entries[index].udata; }
805 	};
806 
807 	class iterator : public std::iterator<std::forward_iterator_tag, K>
808 	{
809 		friend class pool;
810 	protected:
811 		pool *ptr;
812 		int index;
813 		iterator(pool *ptr, int index) : ptr(ptr), index(index) { }
814 	public:
815 		iterator() { }
816 		iterator operator++() { index--; return *this; }
817 		bool operator==(const iterator &other) const { return index == other.index; }
818 		bool operator!=(const iterator &other) const { return index != other.index; }
819 		K &operator*() { return ptr->entries[index].udata; }
820 		K *operator->() { return &ptr->entries[index].udata; }
821 		const K &operator*() const { return ptr->entries[index].udata; }
822 		const K *operator->() const { return &ptr->entries[index].udata; }
823 		operator const_iterator() const { return const_iterator(ptr, index); }
824 	};
825 
826 	pool()
827 	{
828 	}
829 
830 	pool(const pool &other)
831 	{
832 		entries = other.entries;
833 		do_rehash();
834 	}
835 
836 	pool(pool &&other)
837 	{
838 		swap(other);
839 	}
840 
841 	pool &operator=(const pool &other) {
842 		entries = other.entries;
843 		do_rehash();
844 		return *this;
845 	}
846 
847 	pool &operator=(pool &&other) {
848 		clear();
849 		swap(other);
850 		return *this;
851 	}
852 
853 	pool(const std::initializer_list<K> &list)
854 	{
855 		for (auto &it : list)
856 			insert(it);
857 	}
858 
859 	template<class InputIterator>
860 	pool(InputIterator first, InputIterator last)
861 	{
862 		insert(first, last);
863 	}
864 
865 	template<class InputIterator>
866 	void insert(InputIterator first, InputIterator last)
867 	{
868 		for (; first != last; ++first)
869 			insert(*first);
870 	}
871 
872 	std::pair<iterator, bool> insert(const K &value)
873 	{
874 		int hash = do_hash(value);
875 		int i = do_lookup(value, hash);
876 		if (i >= 0)
877 			return std::pair<iterator, bool>(iterator(this, i), false);
878 		i = do_insert(value, hash);
879 		return std::pair<iterator, bool>(iterator(this, i), true);
880 	}
881 
882 	std::pair<iterator, bool> insert(K &&rvalue)
883 	{
884 		int hash = do_hash(rvalue);
885 		int i = do_lookup(rvalue, hash);
886 		if (i >= 0)
887 			return std::pair<iterator, bool>(iterator(this, i), false);
888 		i = do_insert(std::forward<K>(rvalue), hash);
889 		return std::pair<iterator, bool>(iterator(this, i), true);
890 	}
891 
892 	template<typename... Args>
893 	std::pair<iterator, bool> emplace(Args&&... args)
894 	{
895 		return insert(K(std::forward<Args>(args)...));
896 	}
897 
898 	int erase(const K &key)
899 	{
900 		int hash = do_hash(key);
901 		int index = do_lookup(key, hash);
902 		return do_erase(index, hash);
903 	}
904 
905 	iterator erase(iterator it)
906 	{
907 		int hash = do_hash(*it);
908 		do_erase(it.index, hash);
909 		return ++it;
910 	}
911 
912 	int count(const K &key) const
913 	{
914 		int hash = do_hash(key);
915 		int i = do_lookup(key, hash);
916 		return i < 0 ? 0 : 1;
917 	}
918 
919 	int count(const K &key, const_iterator it) const
920 	{
921 		int hash = do_hash(key);
922 		int i = do_lookup(key, hash);
923 		return i < 0 || i > it.index ? 0 : 1;
924 	}
925 
926 	iterator find(const K &key)
927 	{
928 		int hash = do_hash(key);
929 		int i = do_lookup(key, hash);
930 		if (i < 0)
931 			return end();
932 		return iterator(this, i);
933 	}
934 
935 	const_iterator find(const K &key) const
936 	{
937 		int hash = do_hash(key);
938 		int i = do_lookup(key, hash);
939 		if (i < 0)
940 			return end();
941 		return const_iterator(this, i);
942 	}
943 
944 	bool operator[](const K &key)
945 	{
946 		int hash = do_hash(key);
947 		int i = do_lookup(key, hash);
948 		return i >= 0;
949 	}
950 
951 	template<typename Compare = std::less<K>>
952 	void sort(Compare comp = Compare())
953 	{
954 		std::sort(entries.begin(), entries.end(), [comp](const entry_t &a, const entry_t &b){ return comp(b.udata, a.udata); });
955 		do_rehash();
956 	}
957 
958 	K pop()
959 	{
960 		iterator it = begin();
961 		K ret = *it;
962 		erase(it);
963 		return ret;
964 	}
965 
966 	void swap(pool &other)
967 	{
968 		hashtable.swap(other.hashtable);
969 		entries.swap(other.entries);
970 	}
971 
972 	bool operator==(const pool &other) const {
973 		if (size() != other.size())
974 			return false;
975 		for (auto &it : entries)
976 			if (!other.count(it.udata))
977 				return false;
978 		return true;
979 	}
980 
981 	bool operator!=(const pool &other) const {
982 		return !operator==(other);
983 	}
984 
985 	bool hash() const {
986 		unsigned int hashval = mkhash_init;
987 		for (auto &it : entries)
988 			hashval ^= ops.hash(it.udata);
989 		return hashval;
990 	}
991 
992 	void reserve(size_t n) { entries.reserve(n); }
993 	size_t size() const { return entries.size(); }
994 	bool empty() const { return entries.empty(); }
995 	void clear() { hashtable.clear(); entries.clear(); }
996 
997 	iterator begin() { return iterator(this, int(entries.size())-1); }
998 	iterator element(int n) { return iterator(this, int(entries.size())-1-n); }
999 	iterator end() { return iterator(nullptr, -1); }
1000 
1001 	const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
1002 	const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
1003 	const_iterator end() const { return const_iterator(nullptr, -1); }
1004 };
1005 
1006 template<typename K, int offset, typename OPS>
1007 class idict
1008 {
1009 	pool<K, OPS> database;
1010 
1011 public:
1012 	class const_iterator : public std::iterator<std::forward_iterator_tag, K>
1013 	{
1014 		friend class idict;
1015 	protected:
1016 		const idict &container;
1017 		int index;
1018 		const_iterator(const idict &container, int index) : container(container), index(index) { }
1019 	public:
1020 		const_iterator() { }
1021 		const_iterator operator++() { index++; return *this; }
1022 		bool operator==(const const_iterator &other) const { return index == other.index; }
1023 		bool operator!=(const const_iterator &other) const { return index != other.index; }
1024 		const K &operator*() const { return container[index]; }
1025 		const K *operator->() const { return &container[index]; }
1026 	};
1027 
1028 	int operator()(const K &key)
1029 	{
1030 		int hash = database.do_hash(key);
1031 		int i = database.do_lookup(key, hash);
1032 		if (i < 0)
1033 			i = database.do_insert(key, hash);
1034 		return i + offset;
1035 	}
1036 
1037 	int at(const K &key) const
1038 	{
1039 		int hash = database.do_hash(key);
1040 		int i = database.do_lookup(key, hash);
1041 		if (i < 0)
1042 			throw std::out_of_range("idict::at()");
1043 		return i + offset;
1044 	}
1045 
1046 	int at(const K &key, int defval) const
1047 	{
1048 		int hash = database.do_hash(key);
1049 		int i = database.do_lookup(key, hash);
1050 		if (i < 0)
1051 			return defval;
1052 		return i + offset;
1053 	}
1054 
1055 	int count(const K &key) const
1056 	{
1057 		int hash = database.do_hash(key);
1058 		int i = database.do_lookup(key, hash);
1059 		return i < 0 ? 0 : 1;
1060 	}
1061 
1062 	void expect(const K &key, int i)
1063 	{
1064 		int j = (*this)(key);
1065 		if (i != j)
1066 			throw std::out_of_range("idict::expect()");
1067 	}
1068 
1069 	const K &operator[](int index) const
1070 	{
1071 		return database.entries.at(index - offset).udata;
1072 	}
1073 
1074 	void swap(idict &other)
1075 	{
1076 		database.swap(other.database);
1077 	}
1078 
1079 	void reserve(size_t n) { database.reserve(n); }
1080 	size_t size() const { return database.size(); }
1081 	bool empty() const { return database.empty(); }
1082 	void clear() { database.clear(); }
1083 
1084 	const_iterator begin() const { return const_iterator(*this, offset); }
1085 	const_iterator element(int n) const { return const_iterator(*this, n); }
1086 	const_iterator end() const { return const_iterator(*this, offset + size()); }
1087 };
1088 
1089 template<typename K, typename OPS>
1090 class mfp
1091 {
1092 	mutable idict<K, 0, OPS> database;
1093 	mutable std::vector<int> parents;
1094 
1095 public:
1096 	typedef typename idict<K, 0, OPS>::const_iterator const_iterator;
1097 
1098 	int operator()(const K &key) const
1099 	{
1100 		int i = database(key);
1101 		parents.resize(database.size(), -1);
1102 		return i;
1103 	}
1104 
1105 	const K &operator[](int index) const
1106 	{
1107 		return database[index];
1108 	}
1109 
1110 	int ifind(int i) const
1111 	{
1112 		int p = i, k = i;
1113 
1114 		while (parents[p] != -1)
1115 			p = parents[p];
1116 
1117 		while (k != p) {
1118 			int next_k = parents[k];
1119 			parents[k] = p;
1120 			k = next_k;
1121 		}
1122 
1123 		return p;
1124 	}
1125 
1126 	void imerge(int i, int j)
1127 	{
1128 		i = ifind(i);
1129 		j = ifind(j);
1130 
1131 		if (i != j)
1132 			parents[i] = j;
1133 	}
1134 
1135 	void ipromote(int i)
1136 	{
1137 		int k = i;
1138 
1139 		while (k != -1) {
1140 			int next_k = parents[k];
1141 			parents[k] = i;
1142 			k = next_k;
1143 		}
1144 
1145 		parents[i] = -1;
1146 	}
1147 
1148 	int lookup(const K &a) const
1149 	{
1150 		return ifind((*this)(a));
1151 	}
1152 
1153 	const K &find(const K &a) const
1154 	{
1155 		int i = database.at(a, -1);
1156 		if (i < 0)
1157 			return a;
1158 		return (*this)[ifind(i)];
1159 	}
1160 
1161 	void merge(const K &a, const K &b)
1162 	{
1163 		imerge((*this)(a), (*this)(b));
1164 	}
1165 
1166 	void promote(const K &a)
1167 	{
1168 		int i = database.at(a, -1);
1169 		if (i >= 0)
1170 			ipromote(i);
1171 	}
1172 
1173 	void swap(mfp &other)
1174 	{
1175 		database.swap(other.database);
1176 		parents.swap(other.parents);
1177 	}
1178 
1179 	void reserve(size_t n) { database.reserve(n); }
1180 	size_t size() const { return database.size(); }
1181 	bool empty() const { return database.empty(); }
1182 	void clear() { database.clear(); parents.clear(); }
1183 
1184 	const_iterator begin() const { return database.begin(); }
1185 	const_iterator element(int n) const { return database.element(n); }
1186 	const_iterator end() const { return database.end(); }
1187 };
1188 
1189 } /* namespace hashlib */
1190 
1191 #endif
1192