24 #ifndef GRAPHLAB_UTIL_HOPSCOTCH_HASH_HPP
25 #define GRAPHLAB_UTIL_HOPSCOTCH_HASH_HPP
27 #include <graphlab/util/hopscotch_table.hpp>
28 #include <graphlab/parallel/pthread_tools.hpp>
29 #include <graphlab/parallel/atomic.hpp>
31 #include <graphlab/serialization/serialization_includes.hpp>
34 #include <boost/functional/hash.hpp>
35 #define _HOPSCOTCH_MAP_DEFAULT_HASH boost::hash<Key>
61 template <
typename Key,
63 bool Synchronized =
true,
64 typename Hash = _HOPSCOTCH_MAP_DEFAULT_HASH,
65 typename KeyEqual = std::equal_to<Key> >
71 typedef std::pair<Key, Value> value_type;
72 typedef Value mapped_type;
73 typedef size_t size_type;
75 typedef KeyEqual equality_function;
76 typedef value_type* pointer;
77 typedef value_type& reference;
78 typedef const value_type* const_pointer;
79 typedef const value_type& const_reference;
82 typedef std::pair<Key, Value> storage_type;
86 hash_redirect(Hash h): hashfun(h) { }
87 size_t operator()(
const storage_type& v)
const {
88 return hashfun(v.first);
91 struct key_equal_redirect{
93 key_equal_redirect(KeyEqual k): keyeq(k) { }
94 bool operator()(
const storage_type& v,
const storage_type& v2)
const {
95 return keyeq(v.first, v2.first);
115 hash_redirect hashfun;
119 key_equal_redirect equalfun;
131 container_type* rehash_to_new_container(
size_t newsize = (
size_t)(-1)) {
138 if (newsize == (
size_t)(-1)) newsize = container->
size() * 2;
141 while (citer != end()) {
142 assert(newcontainer->
insert(*citer) != newcontainer->
end());
150 iterator do_insert(
const value_type &v) {
153 if (iter != container->
end()) {
158 iter = newcontainer->
insert(v);
159 assert(iter != newcontainer->
end());
160 std::swap(container, newcontainer);
169 KeyEqual equalfun = KeyEqual()):
171 hashfun(hashfun), equalfun(equalfun) {
172 container = create_new_container(32);
176 hashfun(h.hashfun), equalfun(h.equalfun) {
177 container = create_new_container(h.capacity());
178 (*container) = *(h.container);
182 void rehash(
size_t s) {
183 if (s > capacity()) {
185 std::swap(container, newcontainer);
194 hasher hash_function()
const {
195 return hashfun.hashfun;
198 KeyEqual key_eq()
const {
199 return equalfun.equalfun;
203 (*container) = *(other.container);
204 hashfun = other.hashfun;
205 equalfun = other.equalfun;
209 size_type size()
const {
210 return container->
size();
214 return container->
begin();
218 return container->
end();
223 return container->
begin();
227 return container->
end();
231 std::pair<iterator, bool> insert(
const value_type& v) {
233 if (i != end())
return std::make_pair(i,
false);
234 else return std::make_pair(do_insert(v),
true);
239 return insert(v).first;
243 value_type v(k, mapped_type());
244 return container->
find(v);
248 value_type v(k, mapped_type());
249 return container->
find(v);
252 size_t count(key_type
const& k)
const {
253 value_type v(k, mapped_type());
254 return container->
count(v);
259 return container->
erase(iter);
262 bool erase(key_type
const& k) {
263 value_type v(k, mapped_type());
264 return container->
erase(v);
268 std::swap(container, other.container);
269 std::swap(hashfun, other.hashfun);
270 std::swap(equalfun, other.equalfun);
273 mapped_type& operator[](
const key_type& i) {
275 value_type tmp(i, mapped_type());
276 if (iter == end()) iter = do_insert(tmp);
282 container = create_new_container(128);
286 size_t capacity()
const {
291 float load_factor()
const {
292 return container->load_factor();
296 oarc << size() << capacity();
298 while (iter != end()) {
308 if (capacity() != c) {
310 container = create_new_container(c);
315 for (
size_t i = 0;i < s; ++i) {
322 void put_sync(
const value_type &v) {
324 (*this)[v.first] = v.second;
340 if (container->
insert(v) != container->
end()) {
348 assert(newcontainer->
insert(v) != newcontainer->
end());
349 std::swap(container, newcontainer);
356 void put_sync(
const Key& k,
const Value& v) {
357 put_sync(std::make_pair(k, v));
360 std::pair<bool, Value> get_sync(
const Key& k)
const {
363 return std::make_pair(iter == end(), iter->second);
367 std::pair<bool, value_type> v =
368 container->
get_sync(std::make_pair(k, mapped_type()));
370 return std::make_pair(v.first, v.second.second);
373 bool erase_sync(
const Key& k) {
374 if (!Synchronized)
return erase(k);