82 #define FOLLY_ATOMICHASHMAP_H_ 84 #include <boost/iterator/iterator_facade.hpp> 85 #include <boost/noncopyable.hpp> 86 #include <boost/type_traits/is_convertible.hpp> 154 :
std::runtime_error(
"AtomicHashMap is full") {}
190 template <
class ContT,
class IterVal,
class SubIt>
193 typedef ahm_iterator<
198 typedef ahm_iterator<AtomicHashMap, value_type, typename SubMap::iterator>
207 explicit AtomicHashMap(
size_t finalSizeEst,
const Config&
c = Config());
210 const unsigned int numMaps =
211 numMapsAllocated_.load(std::memory_order_relaxed);
213 SubMap* thisMap = subMaps_[
i].load(std::memory_order_relaxed);
241 std::pair<iterator, bool>
insert(
const value_type& r) {
242 return emplace(r.first, r.second);
244 std::pair<iterator, bool>
insert(key_type
k,
const mapped_type&
v) {
245 return emplace(k, v);
247 std::pair<iterator, bool>
insert(value_type&& r) {
248 return emplace(r.first,
std::move(r.second));
250 std::pair<iterator, bool>
insert(key_type
k, mapped_type&&
v) {
266 typename LookupKeyT = key_type,
267 typename LookupHashFcn = hasher,
268 typename LookupEqualFcn = key_equal,
269 typename LookupKeyToKeyFcn = key_convert,
271 std::pair<iterator, bool> emplace(LookupKeyT
k, ArgTs&&... vCtorArg);
290 typename LookupKeyT = key_type,
291 typename LookupHashFcn = hasher,
292 typename LookupEqualFcn = key_equal>
296 typename LookupKeyT = key_type,
297 typename LookupHashFcn = hasher,
298 typename LookupEqualFcn = key_equal>
299 const_iterator find(LookupKeyT k)
const;
308 size_type erase(key_type k);
335 return find(k) ==
end() ? 0 : 1;
348 SimpleRetT ret = findAtInternal(idx);
349 DCHECK_LT(ret.i, numSubMaps());
353 subMaps_[ret.i].load(std::memory_order_relaxed)->makeIter(ret.j));
356 return const_cast<AtomicHashMap*
>(
this)->findAt(idx);
360 size_t capacity()
const;
363 size_t spaceRemaining()
const;
366 const int numMaps = numMapsAllocated_.load(std::memory_order_acquire);
367 for (
int i = 0;
i < numMaps; ++
i) {
368 SubMap*
map = subMaps_[
i].load(std::memory_order_relaxed);
376 return numMapsAllocated_.load(std::memory_order_acquire);
381 it.checkAdvanceToNextSubmap();
387 this, 0, subMaps_[0].
load(std::memory_order_relaxed)->
begin());
388 it.checkAdvanceToNextSubmap();
396 const_iterator
end()
const {
397 return const_iterator();
404 mayInsert ? insertInternal(r.first, r.second) : findInternal(r.first);
405 return encodeIndex(ret.i, ret.j);
409 SimpleRetT ret = mayInsert ? insertInternal(r.first,
std::move(r.second))
410 : findInternal(r.first);
411 return encodeIndex(ret.i, ret.j);
415 recToIdx(key_type k,
const mapped_type&
v,
bool mayInsert =
true) {
416 SimpleRetT ret = mayInsert ? insertInternal(k, v) : findInternal(k);
417 return encodeIndex(ret.i, ret.j);
422 mayInsert ? insertInternal(k,
std::move(
v)) : findInternal(k);
423 return encodeIndex(ret.i, ret.j);
427 return recToIdx(value_type(k), mayInsert);
431 SimpleRetT ret = findAtInternal(idx);
432 return subMaps_[ret.i].load(std::memory_order_relaxed)->idxToRec(ret.j);
442 static const uint32_t kSecondaryMapBit_ = 1u << 31;
443 static const uint32_t kSubMapIndexShift_ = 32 - kNumSubMapBits_ - 1;
444 static const uint32_t kSubMapIndexMask_ = (1 << kSubMapIndexShift_) - 1;
445 static const uint32_t kNumSubMaps_ = 1 << kNumSubMapBits_;
446 static const uintptr_t kLockedPtr_ = 0x88ULL << 48;
457 typename LookupKeyT = key_type,
458 typename LookupHashFcn = hasher,
459 typename LookupEqualFcn = key_equal,
460 typename LookupKeyToKeyFcn = key_convert,
465 typename LookupKeyT = key_type,
466 typename LookupHashFcn = hasher,
467 typename LookupEqualFcn = key_equal>
468 SimpleRetT findInternal(
const LookupKeyT k)
const;
472 std::atomic<SubMap*> subMaps_[kNumSubMaps_];
477 return subMaps_[idx].compare_exchange_strong(
478 val, (
SubMap*)kLockedPtr_, std::memory_order_acquire);
488 class HashFcn = std::hash<KeyT>,
489 class EqualFcn = std::equal_to<KeyT>,
490 class Allocator = std::allocator<char>>
ahm_iterator< const AtomicHashMap, const value_type, typename SubMap::const_iterator > const_iterator
bool tryLockMap(unsigned int idx)
const_iterator begin() const
std::pair< iterator, bool > insert(value_type &&r)
size_type count(key_type k) const
std::pair< const KeyT, ValueT > value_type
uint32_t keyToIdx(const KeyT k, bool mayInsert=false)
uint32_t recToIdx(const value_type &r, bool mayInsert=true)
AtomicHashArray< KeyT, ValueT, HashFcn, EqualFcn, Allocator, ProbeFcn, KeyConvertFcn > SubMap
constexpr detail::Map< Move > move
const_iterator end() const
auto begin(TestAdlIterable &instance)
—— Concurrent Priority Queue Implementation ——
#define FOR_EACH_RANGE(i, begin, end)
std::ptrdiff_t difference_type
constexpr auto size(C const &c) -> decltype(c.size())
void setEntryCountThreadCacheSize(uint32_t newSize)
std::atomic< uint32_t > numMapsAllocated_
KeyConvertFcn key_convert
auto end(TestAdlIterable &instance)
uint32_t recToIdx(key_type k, const mapped_type &v, bool mayInsert=true)
std::pair< iterator, bool > insert(const value_type &r)
std::pair< iterator, bool > insert(key_type k, mapped_type &&v)
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
SimpleRetT(uint32_t ii, size_t jj, bool s)
uint32_t recToIdx(value_type &&r, bool mayInsert=true)
hasher hash_function() const
uint32_t recToIdx(key_type k, mapped_type &&v, bool mayInsert=true)
void setEntryCountThreadCacheSize(int32_t newSize)
std::pair< iterator, bool > insert(key_type k, const mapped_type &v)
const value_type & idxToRec(uint32_t idx) const
const_iterator findAt(uint32_t idx) const
iterator findAt(uint32_t idx)
const value_type & const_reference
ahm_iterator< AtomicHashMap, value_type, typename SubMap::iterator > iterator