* iterator is set to the existing entry.
*/
std::pair<iterator,bool> insert(const value_type& r) {
- SimpleRetT ret = insertInternal(r);
+ SimpleRetT ret = insertInternal(r.first, r.second);
+ return std::make_pair(iterator(this, ret.idx), ret.success);
+ }
+ std::pair<iterator,bool> insert(value_type&& r) {
+ SimpleRetT ret = insertInternal(r.first, std::move(r.second));
return std::make_pair(iterator(this, ret.idx), ret.success);
}
SimpleRetT() {}
};
- SimpleRetT insertInternal(const value_type& record);
+ template <class T>
+ SimpleRetT insertInternal(KeyT key, T&& value);
SimpleRetT findInternal(const KeyT key);
return cellKeyPtr(r)->load(std::memory_order_relaxed);
}
+ static KeyT acquireLoadKey(const value_type& r) {
+ return cellKeyPtr(r)->load(std::memory_order_acquire);
+ }
+
// Fun with thread local storage - atomic increment is expensive
// (relatively), so we accumulate in the thread cache and periodically
// flush to the actual variable, and walk through the unflushed counts when
inline bool tryLockCell(value_type* const cell) {
KeyT expect = kEmptyKey_;
return cellKeyPtr(*cell)->compare_exchange_strong(expect, kLockedKey_,
- std::memory_order_acquire);
+ std::memory_order_acq_rel);
}
inline size_t keyToAnchorIdx(const KeyT k) const {