33 class MyHashConstant {
35 static int const MAX_FILL = 75;
38 static size_t primeSize(
size_t n) {
39 static unsigned long long primes[] = {
40 (1ULL << 3) + 3, (1ULL << 4) + 3, (1ULL << 5) + 5,
41 (1ULL << 6) + 3, (1ULL << 7) + 3, (1ULL << 8) + 7,
42 (1ULL << 9) + 9, (1ULL << 10) + 7, (1ULL << 11) + 5,
43 (1ULL << 12) + 3, (1ULL << 13) + 17, (1ULL << 14) + 27,
44 (1ULL << 15) + 3, (1ULL << 16) + 3, (1ULL << 17) + 29,
45 (1ULL << 18) + 3, (1ULL << 19) + 21, (1ULL << 20) + 7,
46 (1ULL << 21) + 17, (1ULL << 22) + 15, (1ULL << 23) + 9,
47 (1ULL << 24) + 43, (1ULL << 25) + 35, (1ULL << 26) + 15,
48 (1ULL << 27) + 29, (1ULL << 28) + 3, (1ULL << 29) + 11,
49 (1ULL << 30) + 3, (1ULL << 31) + 11, (1ULL << 32) + 15,
50 (1ULL << 33) + 17, (1ULL << 34) + 25, (1ULL << 35) + 53,
51 (1ULL << 36) + 31, (1ULL << 37) + 9, (1ULL << 38) + 7,
52 (1ULL << 39) + 23, (1ULL << 40) + 15};
55 int hi =
sizeof(primes) /
sizeof(primes[0]) - 1;
57 if (n > primes[hi])
return n + 1;
59 int i = (lo + hi) / 2;
70 assert(i == lo && i == hi);
76 struct MyHashDefault {
77 size_t operator()(T
const& o)
const {
81 bool operator()(T
const& o1, T
const& o2)
const {
87 struct MyHashDefault<T*> {
88 size_t operator()(T
const* p)
const {
92 bool operator()(T
const* p1, T
const* p2)
const {
98 struct MyHashDefaultForInt {
99 size_t operator()(T k)
const {
100 return k * 314159257ULL;
103 bool operator()(T k1, T k2)
const {
109 struct MyHashDefault<int8_t> : MyHashDefaultForInt<int8_t> {
113 struct MyHashDefault<int16_t> : MyHashDefaultForInt<int16_t> {
117 struct MyHashDefault<int32_t> : MyHashDefaultForInt<int32_t> {
121 struct MyHashDefault<int64_t> : MyHashDefaultForInt<int64_t> {
125 struct MyHashDefault<uint8_t> : MyHashDefaultForInt<uint8_t> {
129 struct MyHashDefault<uint16_t> : MyHashDefaultForInt<uint16_t> {
133 struct MyHashDefault<uint32_t> : MyHashDefaultForInt<uint32_t> {
137 struct MyHashDefault<uint64_t> : MyHashDefaultForInt<uint64_t> {
145 template<
typename T,
typename Hash = MyHashDefault<T>,
146 typename Equal = MyHashDefault<T> >
165 MyHashTable(Hash
const& hash = Hash(), Equal
const& equal = Equal())
166 : hashFunc(hash), eqFunc(equal), tableCapacity_(0), tableSize_(0),
167 maxSize_(0), size_(0), table(0), collisions_(0) {
176 MyHashTable(
size_t n, Hash
const& hash = Hash(), Equal
const& equal =
178 : hashFunc(hash), eqFunc(equal), tableCapacity_(0), tableSize_(0),
179 maxSize_(0), size_(0), table(0), collisions_(0) {
189 : hashFunc(o.hashFunc), eqFunc(o.eqFunc), tableCapacity_(0),
190 tableSize_(0), maxSize_(0), size_(0), table(0), collisions_(0) {
192 for (const_iterator t = o.begin(); t != o.end(); ++t) {
199 for (const_iterator t = o.begin(); t != o.end(); ++t) {
254 collisions_ = o.collisions_;
263 size_t tableCapacity()
const {
264 return tableCapacity_ *
sizeof(Entry);
267 size_t tableSize()
const {
271 size_t size()
const {
279 size_t collisions()
const {
302 tableSize_ = primeSize(n * 100 / MAX_FILL + 1);
303 maxSize_ = tableSize_ * MAX_FILL / 100;
307 if (tableSize_ <= tableCapacity_) {
308 for (
size_t i = 0; i < tableSize_; ++i) {
313 tableCapacity_ = tableSize_;
315 table =
new Entry[tableCapacity_]();
324 MyHashTable tmp(std::max(tableSize_, n), hashFunc, eqFunc);
325 for (iterator t = begin(); t != end(); ++t) {
336 Entry&
add(Entry
const& elem) {
337 assert(!(elem == Entry()));
338 if (tableSize_ == 0) rehash();
342 i = hashFunc(elem) % tableSize_;
344 while (!(table[i] == Entry())) {
345 if (eqFunc(table[i], elem))
return table[i];
348 if (i >= tableSize_) i = 0;
351 if (size_ < maxSize_)
break;
367 Entry*
get(Entry
const& elem)
const {
368 assert(!(elem == Entry()));
370 if (tableSize_ > 0) {
371 size_t i = hashFunc(elem) % tableSize_;
372 while (!(table[i] == Entry())) {
373 if (eqFunc(table[i], elem))
return &table[i];
375 if (i >= tableSize_) i = 0;
379 return static_cast<Entry*
>(0);
387 explicit iterator(Entry* from, Entry
const* to)
388 : ptr(from), end(to) {
389 while (ptr < end && *ptr == Entry()) {
398 Entry* operator->() {
402 iterator& operator++() {
403 while (++ptr < end) {
404 if (!(*ptr == Entry()))
break;
409 bool operator==(iterator
const& o)
const {
413 bool operator!=(iterator
const& o)
const {
418 class const_iterator {
423 explicit const_iterator(Entry
const* from, Entry
const* to)
424 : ptr(from), end(to) {
425 while (ptr < end && *ptr == Entry()) {
430 Entry
const& operator*()
const {
434 Entry
const* operator->()
const {
438 const_iterator& operator++() {
439 while (++ptr < end) {
440 if (!(*ptr == Entry()))
break;
445 bool operator==(const_iterator
const& o)
const {
449 bool operator!=(const_iterator
const& o)
const {
455 return iterator(table, table + tableSize_);
458 const_iterator begin()
const {
459 return const_iterator(table, table + tableSize_);
463 return iterator(table + tableSize_, table + tableSize_);
466 const_iterator end()
const {
467 return const_iterator(table + tableSize_, table + tableSize_);
476 template<
typename K,
typename V>
489 : key(key), value() {
493 : key(key), value(value) {
521 return os <<
"(" << o.
key <<
" => " << o.
value <<
")";
526 template<
typename K,
typename V,
typename Hash,
typename Equal>
527 class MyHashMapHashWrapper {
532 MyHashMapHashWrapper(Hash
const& hash, Equal
const& equal)
533 : hashFunc(hash), eqFunc(equal) {
537 return hashFunc(o.
key);
542 return eqFunc(o1.
key, o2.
key);
552 template<
typename K,
typename V,
typename Hash = MyHashDefault<K>,
553 typename Equal = MyHashDefault<K> >
555 MyHashMapHashWrapper<K,V,Hash,Equal>,
556 MyHashMapHashWrapper<K,V,Hash,Equal> > {
559 MyHashMapHashWrapper<K,V,Hash,Equal> >
Table;
564 MyHashMap(Hash
const& hash = Hash(), Equal
const& equal = Equal())
565 : Table(MyHashMapHashWrapper<K,V,Hash,Equal>(hash, equal),
566 MyHashMapHashWrapper<K,V,Hash,Equal>(hash, equal)) {
575 MyHashMap(
size_t n, Hash
const& hash = Hash(), Equal
const& equal = Equal())
576 : Table(n, MyHashMapHashWrapper<K,V,Hash,Equal>(hash, equal),
577 MyHashMapHashWrapper<K,V,Hash,Equal>(hash, equal)) {
603 return Table::add(Entry(key)).value;
612 Entry* p = Table::get(Entry(key));
613 return (p != 0) ? &p->
value : 0;
bool operator<(MyHashMapEntry const &o) const
Check the order of keys with another object.
Closed hash map implementation.
Closed hash table implementation.
Entry * table
Pointer to the storage.
bool operator==(MyHashMapEntry const &o) const
Check key's equivalence between another object.
MyHashMap(MyHashMap const &o, size_t n=1)
Copy constructor.
MyHashTable(size_t n, Hash const &hash=Hash(), Equal const &equal=Equal())
Constructor.
Entry & add(Entry const &elem)
Insert an element if no other equivalent element is registered.
void clear()
Initialize the table to be empty.
Hash const hashFunc
Functor for getting hash codes.
MyHashTable(MyHashTable const &o, size_t n=1)
Copy constructor.
MyHashMap(size_t n, Hash const &hash=Hash(), Equal const &equal=Equal())
Constructor.
size_t tableSize_
Size of the hash table.
Equal const eqFunc
Functor for checking equivalence.
MyHashTable(Hash const &hash=Hash(), Equal const &equal=Equal())
Default constructor.
void rehash(size_t n=1)
Resize the storage appropriately.
V & operator[](K const &key)
Move constructor.
V * getValue(K const &key) const
Get the value that is already registered.
void initialize(size_t n)
Initialize the table to be empty.
void moveAssign(MyHashTable &o)
Move constructor.
MyHashMap(Hash const &hash=Hash(), Equal const &equal=Equal())
Default constructor.
size_t maxSize_
The maximum number of elements.
size_t tableCapacity_
Size of the hash table storage.
size_t size_
The number of elements.
friend std::ostream & operator<<(std::ostream &os, MyHashMapEntry const &o)
Print the object.