47 uint64_t index = key & mode_num_;
48 return table_[index].Has(key);
51 bool Get(K key, V **value) {
52 uint64_t index = key & mode_num_;
53 return table_[index].Get(key, value);
56 bool Get(K key, V *value) {
57 uint64_t index = key & mode_num_;
59 bool res = table_[index].Get(key, &val);
67 uint64_t index = key & mode_num_;
68 table_[index].Insert(key);
71 void Set(K key,
const V &value) {
72 uint64_t index = key & mode_num_;
73 table_[index].Insert(key, value);
76 void Set(K key, V &&value) {
77 uint64_t index = key & mode_num_;
78 table_[index].Insert(key, std::forward<V>(value));
84 explicit Entry(K key) : key(key) {
85 value_ptr.store(
new V(), std::memory_order_release);
87 Entry(K key,
const V &value) : key(key) {
88 value_ptr.store(
new V(value), std::memory_order_release);
90 Entry(K key, V &&value) : key(key) {
91 value_ptr.store(
new V(std::forward<V>(value)), std::memory_order_release);
93 ~Entry() {
delete value_ptr.load(std::memory_order_acquire); }
96 std::atomic<V *> value_ptr = {
nullptr};
97 std::atomic<Entry *> next = {
nullptr};
102 Bucket() : head_(new Entry()) {}
106 auto tmp = ite->next.load(std::memory_order_acquire);
113 Entry *m_target = head_->next.load(std::memory_order_acquire);
114 while (Entry *target = m_target) {
115 if (target->key < key) {
116 m_target = target->next.load(std::memory_order_acquire);
119 return target->key == key;
125 bool Find(K key, Entry **prev_ptr, Entry **target_ptr) {
127 Entry *m_target = head_->next.load(std::memory_order_acquire);
128 while (Entry *target = m_target) {
129 if (target->key == key) {
131 *target_ptr = target;
133 }
else if (target->key > key) {
135 *target_ptr = target;
139 m_target = target->next.load(std::memory_order_acquire);
143 *target_ptr =
nullptr;
147 void Insert(K key,
const V &value) {
148 Entry *prev =
nullptr;
149 Entry *target =
nullptr;
150 Entry *new_entry =
nullptr;
151 V *new_value =
nullptr;
153 if (Find(key, &prev, &target)) {
156 new_value =
new V(value);
158 auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);
159 if (target->value_ptr.compare_exchange_strong(
160 old_val_ptr, new_value, std::memory_order_acq_rel,
161 std::memory_order_relaxed)) {
172 new_entry =
new Entry(key, value);
174 new_entry->next.store(target, std::memory_order_release);
175 if (prev->next.compare_exchange_strong(target, new_entry,
176 std::memory_order_acq_rel,
177 std::memory_order_relaxed)) {
190 void Insert(K key, V &&value) {
191 Entry *prev =
nullptr;
192 Entry *target =
nullptr;
193 Entry *new_entry =
nullptr;
194 V *new_value =
nullptr;
196 if (Find(key, &prev, &target)) {
199 new_value =
new V(std::forward<V>(value));
201 auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);
202 if (target->value_ptr.compare_exchange_strong(
203 old_val_ptr, new_value, std::memory_order_acq_rel,
204 std::memory_order_relaxed)) {
215 new_entry =
new Entry(key, value);
217 new_entry->next.store(target, std::memory_order_release);
218 if (prev->next.compare_exchange_strong(target, new_entry,
219 std::memory_order_acq_rel,
220 std::memory_order_relaxed)) {
234 Entry *prev =
nullptr;
235 Entry *target =
nullptr;
236 Entry *new_entry =
nullptr;
237 V *new_value =
nullptr;
239 if (Find(key, &prev, &target)) {
244 auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);
245 if (target->value_ptr.compare_exchange_strong(
246 old_val_ptr, new_value, std::memory_order_acq_rel,
247 std::memory_order_relaxed)) {
258 new_entry =
new Entry(key);
260 new_entry->next.store(target, std::memory_order_release);
261 if (prev->next.compare_exchange_strong(target, new_entry,
262 std::memory_order_acq_rel,
263 std::memory_order_relaxed)) {
276 bool Get(K key, V **value) {
277 Entry *prev =
nullptr;
278 Entry *target =
nullptr;
279 if (Find(key, &prev, &target)) {
280 *value = target->value_ptr.load(std::memory_order_acquire);
290 Bucket table_[TableSize];