mCRL2
Loading...
Searching...
No Matches
hashtable.h
Go to the documentation of this file.
1// Author(s): Maurice Laveaux
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//
9
10#ifndef MCRL2_UTILITIES_DETAIL_HASHTABLE_H
11#define MCRL2_UTILITIES_DETAIL_HASHTABLE_H
12#pragma once
13
15#include "mcrl2/utilities/hashtable.h" // necessary for header test.
16#include "mcrl2/utilities/indexed_set.h" // necessary for header test.
17
18namespace mcrl2
19{
20namespace utilities
21{
22
23template <class Key, typename Hash, typename Equals, typename Allocator>
25{
26 // Copy the old hashtable.
27 std::vector<Key> old = std::move(m_hashtable);
28
29 m_hashtable = std::vector<Key>(size, nullptr);
30 m_buckets_mask = m_hashtable.size() - 1;
31
32 for (const Key& key : old)
33 {
34 const std::size_t key_index = get_index(key);
35 auto it = begin() + key_index;
36 // Find the first empty position.
37 while (*it != nullptr)
38 {
39 ++it;
40 if (it == end())
41 {
42 it = begin();
43 }
44
45 assert(it != begin() + key_index);
46 }
47
48 // Found an empty spot, insert a new index belonging to key,
49 *it = key;
50 }
51}
52
53template <class Key, typename Hash, typename Equals, typename Allocator>
55 : hashtable(128)
56{
57}
58
59template <class Key, typename Hash, typename Equals, typename Allocator>
61 const hasher& hasher,
62 const key_equal& equals)
63 : m_hashtable(std::max(initial_size, detail::minimal_hashtable_size), nullptr),
64 m_hasher(hasher),
65 m_equals(equals)
66{
67 assert(utilities::is_power_of_two(initial_size));
68 m_buckets_mask = m_hashtable.size() - 1;
69}
70
71template <class Key, typename Hash, typename Equals, typename Allocator>
73{
74 m_hashtable.clear();
75}
76
77template <class Key, typename Hash, typename Equals, typename Allocator>
79{
80 return (2 * m_number_of_elements >= m_hashtable.size());
81}
82
83template <class Key, typename Hash, typename Equals, typename Allocator>
85{
86 rehash(2 * m_hashtable.size());
87}
88
89template <class Key, typename Hash, typename Equals, typename Allocator>
90inline std::pair<typename hashtable<Key,Hash,Equals,Allocator>::iterator, bool> hashtable<Key,Hash,Equals,Allocator>::insert(const Key& key)
91{
92 // Resize hashtable must be done explicitly.
93 assert(!must_resize());
94 ++m_number_of_elements;
95
96 const std::size_t key_index = get_index(key);
97 auto it = begin() + key_index;
98
99 // Find the first empty position.
100 while (*it != nullptr)
101 {
102 ++it;
103 if (it == end())
104 {
105 it = begin();
106 }
107
108 assert(it != begin() + key_index);
109 }
110
111 // Found an empty spot, insert a new index belonging to key,
112 *it = key;
113 return std::make_pair(it, true);
114}
115
116
117template <class Key, typename Hash, typename Equals, typename Allocator>
119{
120 const std::size_t key_index = get_index(key);
121 auto it = begin() + key_index;
123 // Find the key.
124 while (!m_equals(*it, key))
125 {
126 ++it;
127 if (it == end())
128 {
129 it = begin();
130 }
131
132 if (it == begin() + key_index)
134 // An element not in the hashset is begin removed.
135 // When optimizing, the gcc compiler tends to generate
136 // destructions of non generated aterms. If this is
137 // repaired, this safety escape can be removed.
138 return it;
139 }
140 assert(it != begin() + key_index);
141 }
142
143 *it = nullptr;
144 --m_number_of_elements;
145 return it;
147
148
149template <class Key, typename Hash, typename Equals, typename Allocator>
151{
152 for (auto it = begin(); it != end(); ++it)
153 {
154 if (*it == key)
155 {
156 return it;
157 }
158 }
159
160 return end();
161}
162
163// PRIVATE FUNCTIONS
164
165template <class Key, typename Hash, typename Equals, typename Allocator>
166inline std::size_t hashtable<Key,Hash,Equals,Allocator>::get_index(const Key& key)
168 return m_hasher(key) & m_buckets_mask;
169}
170
171
172} // namespace utilities
173
174} // namespace mcrl2
175
176#endif // MCRL2_UTILITIES_DETAIL_INDEXED_SET_H
A set that assigns each element an unique index.
Definition hashtable.h:27
void clear()
Clears the indexed set by removing all its elements. It is not guaranteed that the memory is released...
Definition hashtable.h:72
iterator find(const key_type &key)
Find the given key and returns an iterator to that position.
Definition hashtable.h:150
std::vector< Key >::iterator iterator
Definition hashtable.h:40
void rehash(std::size_t size)
Resizes the hash table to the given power of two size.
Definition hashtable.h:24
void resize()
Resize the hashtable. This is not done automatically.
Definition hashtable.h:84
std::size_t get_index(const key_type &key)
Definition hashtable.h:166
hashtable()
Constructor of an empty indexed set. Starts with a hashtable of size 128.
Definition hashtable.h:54
size_type m_buckets_mask
Always equal to m_hashtable.size() - 1.
Definition hashtable.h:164
bool must_resize()
Check whether the hashtable must be resized. This is not automatic and must be done explicitly.
Definition hashtable.h:78
std::pair< iterator, bool > insert(const key_type &key)
Insert a key in the indexed set and return its index.
Definition hashtable.h:90
std::vector< Key > m_hashtable
Definition hashtable.h:156
iterator erase(const key_type &key)
Erases the key assuming that this key is present in the hashtable..
Definition hashtable.h:118
static std::size_t get_index(const function_symbol &func)
static constexpr bool is_power_of_two(T value)
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
STL namespace.