25 #ifndef TERVEL_CONTAINER_WF_HASH_MAP_WFHM_HASHMAP_H
26 #define TERVEL_CONTAINER_WF_HASH_MAP_WFHM_HASHMAP_H
45 double val = std::log2(value);
46 int int_val =
static_cast<int>(val);
54 namespace containers {
60 template<
class Key,
class Value>
61 struct default_functor {
84 template<
class Key,
class Value,
class Functor = default_functor<Key, Value> >
113 if (temp !=
nullptr) {
135 bool at(Key key, ValueAccessor &va);
182 return (
value_ !=
nullptr);
258 for (
size_t i = 0; i <
len_; i++) {
267 for (
size_t i = 0; i <
len_; i++) {
269 if (temp !=
nullptr) {
281 assert(pos < len_ && pos >=0);
341 void expand_map(Location * loc,
Node * &curr_value, uint64_t next_position);
356 template<
class Key,
class Value,
class Functor>
360 key = functor.hash(key);
363 uint64_t position = get_position(key, depth);
364 Location *loc = &(primary_array_[position]);
369 curr_value = loc->load();
371 if (curr_value ==
nullptr) {
373 }
else if (curr_value->
is_array()) {
376 position = get_position(key, depth);
377 loc = array_node->
access(position);
383 if (functor.key_equals(data_node->key_, key)) {
384 va.
init(&(data_node->value_));
395 template<
class Key,
class Value,
class Functor>
399 key = functor.hash(key);
404 uint64_t position = get_position(key, depth);
405 Location *loc = &(primary_array_[position]);
406 Node *curr_value = loc->load();
411 if (curr_value ==
nullptr) {
412 if (loc->compare_exchange_strong(curr_value, new_node)) {
417 }
else if (curr_value->
is_array()) {
420 position = get_position(key, depth);
421 loc = array_node->
access(position);
422 curr_value = loc->load();
427 if (functor.key_equals(data_node->key_, key)) {
432 const uint64_t next_position = get_position(data_node->key_, depth+1);
433 expand_map(loc, curr_value, next_position);
439 assert(loc->load() != new_node);
446 template<
class Key,
class Value,
class Functor>
452 array_node->access(next_position)->store(curr_value);
453 assert(array_node->is_array());
455 if (loc->compare_exchange_strong(curr_value, array_node)) {
458 assert(loc->load() != array_node);
459 array_node->access(next_position)->store(
nullptr);
464 template<
class Key,
class Value,
class Functor>
467 const uint64_t *long_array =
reinterpret_cast<uint64_t *
>(&key);
468 const size_t max_length =
sizeof(Key) / (64 / 8);
470 assert(depth <= max_depth());
473 assert(primary_array_pow_ < 64);
475 uint64_t position = long_array[0] >> (64 - primary_array_pow_);
477 assert(position < primary_array_size_);
480 const int start_bit_offset = (depth-1)*secondary_array_pow_ +
482 const int end_bit_offset = (depth)*secondary_array_pow_ +
485 const size_t start_idx = start_bit_offset / 64;
486 const size_t start_idx_offset = start_bit_offset % 64;
487 const size_t end_idx = end_bit_offset / 64;
488 const size_t end_idx_offset = end_bit_offset % 64;
490 assert(start_idx == end_idx || start_idx + 1 == end_idx);
491 assert(end_idx <= max_length);
495 if (start_idx == end_idx) {
496 uint64_t value = long_array[start_idx];
497 value = value << start_idx_offset;
498 value = value >> (64 - secondary_array_pow_);
500 assert(value < secondary_array_size_);
503 uint64_t value = long_array[start_idx];
504 value = value << start_idx_offset;
505 value = value >> (64 - secondary_array_pow_ + end_idx_offset);
506 value = value << (end_idx_offset);
510 if (end_idx == max_length) {
513 value2 = long_array[end_idx];
515 value2 = value2 >> (64 - end_idx_offset);
517 uint64_t position = (value | value2);
518 assert(position < secondary_array_size_);
524 template<
class Key,
class Value,
class Functor>
527 uint64_t max_depth =
sizeof(Key)*8;
528 max_depth -= primary_array_pow_;
529 max_depth = std::ceil(max_depth / secondary_array_pow_);
535 template<
class Key,
class Value,
class Functor>
538 size_t max_depth_ = max_depth();
539 std::cout <<
"K(" << key <<
") :";
540 for (
size_t i = 0; i <= max_depth_; i++) {
541 uint64_t temp = get_position(key, i);
542 std::cout << temp <<
"-";
544 std::cout <<
"\n" << std::endl;
551 #endif // TERVEL_CONTAINER_WF_HASH_MAP_WFHM_HASHMAP_H
Key hash(Key k)
Definition: wf_hash_map_no_delete.h:62
const size_t primary_array_size_
Definition: wf_hash_map_no_delete.h:345
const size_t secondary_array_size_
Definition: wf_hash_map_no_delete.h:347
const size_t primary_array_pow_
Definition: wf_hash_map_no_delete.h:346
Value value_
Definition: wf_hash_map_no_delete.h:331
uint64_t get_position(Key &key, size_t depth)
Definition: wf_hash_map_no_delete.h:466
std::atomic< Node * > Location
Definition: wf_hash_map_no_delete.h:228
This class is used to hold the secondary array structure.
Definition: wf_hash_map_no_delete.h:253
std::unique_ptr< Location[]> internal_array_
Definition: wf_hash_map_no_delete.h:301
TODO(steven):
Definition: mcas.h:36
bool is_data()
Definition: wf_hash_map_no_delete.h:326
~HashMapNoDelete()
Not Thread Safe! If it is a node type then the node will be freed If it is an array node then the des...
Definition: wf_hash_map_no_delete.h:110
bool key_equals(Key a, Key b)
Definition: wf_hash_map_no_delete.h:66
~ValueAccessor()
Definition: wf_hash_map_no_delete.h:169
virtual ~Node()
Definition: wf_hash_map_no_delete.h:237
virtual bool is_array()=0
bool valid()
Definition: wf_hash_map_no_delete.h:181
DataNode(Key k, Value v)
Definition: wf_hash_map_no_delete.h:310
int round_to_next_power_of_two(uint64_t value)
Returns the next power of two.
Definition: wf_hash_map_no_delete.h:44
HashMapNoDelete(uint64_t capacity, uint64_t expansion_rate=3)
Definition: wf_hash_map_no_delete.h:89
~DataNode()
Definition: wf_hash_map_no_delete.h:314
uint64_t max_depth()
Definition: wf_hash_map_no_delete.h:526
size_t size()
Definition: wf_hash_map_no_delete.h:155
~ArrayNode()
See Notes on hash map destructor.
Definition: wf_hash_map_no_delete.h:266
Key key_
Definition: wf_hash_map_no_delete.h:330
std::unique_ptr< Location[]> primary_array_
Definition: wf_hash_map_no_delete.h:352
uint64_t len_
Definition: wf_hash_map_no_delete.h:300
bool at(Key key, ValueAccessor &va)
This function returns true and initializes the passed ValueAccessor if the key exists in the hash map...
Definition: wf_hash_map_no_delete.h:358
void print_key(Key &key)
Outputs the positions a key belongs in at each depth.
Definition: wf_hash_map_no_delete.h:537
Value * value()
Definition: wf_hash_map_no_delete.h:174
Value * value_
Definition: wf_hash_map_no_delete.h:199
A wait-free hash map implementation.
Definition: wf_hash_map_no_delete.h:85
const size_t secondary_array_pow_
Definition: wf_hash_map_no_delete.h:348
uint64_t Value
Definition: testObject.h:59
This class is used to hold a key and value pair.
Definition: wf_hash_map_no_delete.h:308
This class is used to safe guard access to values.
Definition: wf_hash_map_no_delete.h:163
This class is used to differentiate between data_nodes and array_nodes/.
Definition: wf_hash_map_no_delete.h:234
bool is_array()
Definition: wf_hash_map_no_delete.h:288
Location * access(uint64_t pos)
Definition: wf_hash_map_no_delete.h:280
void init(Value *value)
Initializes the value accessors.
Definition: wf_hash_map_no_delete.h:197
bool insert(Key key, Value value)
This function returns true if the key value pair was successfully inserted.
Definition: wf_hash_map_no_delete.h:397
Node()
Definition: wf_hash_map_no_delete.h:236
bool is_array()
Definition: wf_hash_map_no_delete.h:319
void expand_map(Location *loc, Node *&curr_value, uint64_t next_position)
Increases the capacity of the hash map by replacing a data node reference with a reference to an arra...
Definition: wf_hash_map_no_delete.h:448
void reset()
Resets this value accessors,clearing the variables.
Definition: wf_hash_map_no_delete.h:188
std::atomic< uint64_t > size_
Definition: wf_hash_map_no_delete.h:350
bool is_data()
Definition: wf_hash_map_no_delete.h:295
ValueAccessor()
Definition: wf_hash_map_no_delete.h:166
ArrayNode(uint64_t len)
Definition: wf_hash_map_no_delete.h:255