Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
hashmap_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_core/hashmap_impl.h
10 //! @brief Intrusive hash table implementation file.
11 
12 #ifndef ROC_CORE_HASHMAP_IMPL_H_
13 #define ROC_CORE_HASHMAP_IMPL_H_
14 
16 #include "roc_core/attributes.h"
17 #include "roc_core/hashmap_node.h"
18 #include "roc_core/hashsum.h"
19 #include "roc_core/iarena.h"
20 #include "roc_core/macro_helpers.h"
21 #include "roc_core/noncopyable.h"
23 #include "roc_core/panic.h"
24 #include "roc_core/stddefs.h"
25 
26 namespace roc {
27 namespace core {
28 
29 //! Intrusive hash table internal implementation.
30 class HashmapImpl {
31 public:
32  enum {
33  // rehash happens when n_elements >= n_buckets * LoadFactorNum / LoadFactorDen
34  LoadFactorNum = 13,
35  LoadFactorDen = 2,
36  };
37 
38  //! Bucket container.
39  struct Bucket {
40  //! Pointer to head node.
42  };
43 
44  //! Callback function pointer type for key equality check.
45  typedef bool (*key_equals_callback)(HashmapData* node, const void* key);
46 
47  //! Initialize empty hashmap.
48  HashmapImpl(void* preallocated_data, size_t num_embedded_buckets, IArena& arena);
49 
50  //! Deinitialize.
52 
53  //! Get maximum number of nodes that can be added to hashmap before
54  //! grow() should be called.
55  size_t capacity() const;
56 
57  //! Get number of nodes added to hashmap.
58  size_t size() const;
59 
60  //! Check if node belongs to hashmap.
61  bool contains(const HashmapData* node) const;
62 
63  //! Find node in the hashmap.
65  find_node(hashsum_t hash, const void* key, key_equals_callback callback) const;
66 
67  //! Get first node in hashmap.
68  HashmapData* front() const;
69 
70  //! Get last node in hashmap.
71  HashmapData* back() const;
72 
73  //! Get hashmap node next to given one.
75 
76  //! Get hashmap node previous to given one.
78 
79  //! Insert node into hashmap.
80  bool insert(HashmapData* node,
81  hashsum_t hash,
82  const void* key,
83  key_equals_callback callback);
84 
85  //! Remove node from hashmap.
86  void remove(HashmapData* node, bool skip_rehash);
87 
88  //! Grow hashtable capacity.
90 
91 private:
92  HashmapData* find_in_bucket_(const Bucket& bucket,
93  hashsum_t hash,
94  const void* key,
95  key_equals_callback callback) const;
96 
97  size_t buckets_capacity_(size_t n_buckets) const;
98 
99  bool realloc_buckets_(size_t n_buckets);
100  void dealloc_buckets_();
101 
102  bool member_of_bucket_array_(Bucket* buckets,
103  size_t n_buckets,
104  const HashmapData* node) const;
105 
106  Bucket& select_bucket_(hashsum_t hash) const;
107  void bucket_insert_(Bucket& bucket, HashmapData* node);
108  void bucket_remove_(HashmapData* node);
109  void all_list_insert_(HashmapData* node);
110  void all_list_remove_(HashmapData* node);
111  void proceed_rehash_(bool in_insert);
112  void migrate_node_(HashmapData* node);
113  size_t get_next_bucket_size_(size_t current_count);
114 
115  void* preallocated_data_;
116  size_t num_preallocated_buckets_;
117 
118  Bucket* curr_buckets_;
119  size_t n_curr_buckets_;
120 
121  Bucket* prev_buckets_;
122  size_t n_prev_buckets_;
123 
124  size_t size_;
125 
126  size_t rehash_pos_;
127  size_t rehash_remain_nodes_;
128 
129  // head of list of all nodes
130  HashmapData all_head_;
131 
132  IArena& arena_;
133 };
134 
135 } // namespace core
136 } // namespace roc
137 
138 #endif // ROC_CORE_HASHMAP_IMPL_H_
Aligned storage.
Compiler attributes.
#define ROC_ATTR_NODISCARD
Emit warning if function result is not checked.
Definition: attributes.h:31
Intrusive hash table internal implementation.
Definition: hashmap_impl.h:30
HashmapData * front() const
Get first node in hashmap.
bool insert(HashmapData *node, hashsum_t hash, const void *key, key_equals_callback callback)
Insert node into hashmap.
size_t size() const
Get number of nodes added to hashmap.
HashmapData * prevof(HashmapData *node) const
Get hashmap node previous to given one.
HashmapData * nextof(HashmapData *node) const
Get hashmap node next to given one.
bool(* key_equals_callback)(HashmapData *node, const void *key)
Callback function pointer type for key equality check.
Definition: hashmap_impl.h:45
HashmapData * back() const
Get last node in hashmap.
HashmapData * find_node(hashsum_t hash, const void *key, key_equals_callback callback) const
Find node in the hashmap.
void remove(HashmapData *node, bool skip_rehash)
Remove node from hashmap.
HashmapImpl(void *preallocated_data, size_t num_embedded_buckets, IArena &arena)
Initialize empty hashmap.
ROC_ATTR_NODISCARD bool grow()
Grow hashtable capacity.
bool contains(const HashmapData *node) const
Check if node belongs to hashmap.
~HashmapImpl()
Deinitialize.
size_t capacity() const
Get maximum number of nodes that can be added to hashmap before grow() should be called.
Memory arena interface.
Definition: iarena.h:23
Hashmap node.
Hash sum.
Memory arena interface.
Helper macros.
size_t hashsum_t
Hash type.
Definition: hashsum.h:21
Root namespace.
Non-copyable object.
Ownership policies.
Panic.
Commonly used types and functions.
Hashmap node internal data.
Definition: hashmap_node.h:25
HashmapData * head
Pointer to head node.
Definition: hashmap_impl.h:41