17 #ifndef FOLLY_ATOMICHASHMAP_H_ 18 #error "This should only be included by AtomicHashMap.h" 34 typename KeyConvertFcn>
44 config.growthFactor < 0 ? 1.0
f - config.maxLoadFactor
45 : config.growthFactor) {
49 std::memory_order_relaxed);
52 subMaps_[
i].store(
nullptr, std::memory_order_relaxed);
65 typename KeyConvertFcn>
68 typename LookupHashFcn,
69 typename LookupEqualFcn,
70 typename LookupKeyToKeyFcn,
89 KeyConvertFcn>
::emplace(LookupKeyT
k, ArgTs&&... vCtorArgs) {
94 LookupKeyToKeyFcn>(
k, std::forward<ArgTs>(vCtorArgs)...);
96 return std::make_pair(
108 typename KeyConvertFcn>
111 typename LookupHashFcn,
112 typename LookupEqualFcn,
113 typename LookupKeyToKeyFcn,
142 LookupKeyToKeyFcn>(key, std::forward<ArgTs>(vCtorArgs)...);
153 SubMap* primarySubMap =
subMaps_[0].load(std::memory_order_relaxed);
163 size_t numCellsAllocated = (size_t)(
166 size_t newSize = size_t(numCellsAllocated *
kGrowthFrac_);
180 SubMap::create(newSize, config).release(), std::memory_order_relaxed);
196 SubMap* loadedMap =
subMaps_[nextMapIdx].load(std::memory_order_relaxed);
198 ret = loadedMap->insertInternal(key, std::forward<ArgTs>(vCtorArgs)...);
199 if (ret.
idx != loadedMap->capacity_) {
204 goto beginInsertInternal;
215 typename KeyConvertFcn>
216 template <
class LookupKeyT,
class LookupHashFcn,
class LookupEqualFcn>
224 KeyConvertFcn>::iterator
233 SimpleRetT ret = findInternal<LookupKeyT, LookupHashFcn, LookupEqualFcn>(
k);
248 typename KeyConvertFcn>
249 template <
class LookupKeyT,
class LookupHashFcn,
class LookupEqualFcn>
267 ->find<LookupKeyT, LookupHashFcn, LookupEqualFcn>(k);
278 typename KeyConvertFcn>
279 template <
class LookupKeyT,
class LookupHashFcn,
class LookupEqualFcn>
296 SubMap*
const primaryMap =
subMaps_[0].load(std::memory_order_relaxed);
299 ->template findInternal<LookupKeyT, LookupHashFcn, LookupEqualFcn>(
k);
303 const unsigned int numMaps =
310 ->template findInternal<LookupKeyT, LookupHashFcn, LookupEqualFcn>(
328 typename KeyConvertFcn>
348 idx &= ~kSecondaryMapBit_;
357 return SimpleRetT(subMapIdx, subMapOffset,
true);
368 typename KeyConvertFcn>
404 typename KeyConvertFcn>
416 totalCap +=
subMaps_[
i].load(std::memory_order_relaxed)->capacity_;
430 typename KeyConvertFcn>
458 typename KeyConvertFcn>
467 subMaps_[0].load(std::memory_order_relaxed)->clear();
473 subMaps_[
i].store(
nullptr, std::memory_order_relaxed);
486 typename KeyConvertFcn>
498 totalSize +=
subMaps_[
i].load(std::memory_order_relaxed)->size();
528 typename KeyConvertFcn>
559 typename KeyConvertFcn>
560 template <
class ContT,
class IterVal,
class SubIt>
569 : boost::iterator_facade<
570 ahm_iterator<ContT, IterVal, SubIt>,
572 boost::forward_traversal_tag> {
578 template <
class OtherContT,
class OtherVal,
class OtherSubIt>
581 typename std::enable_if<
583 : ahm_(o.ahm_), subMap_(o.subMap_), subIt_(o.subIt_) {}
591 return ahm_->encodeIndex(subMap_, subIt_.getIndex());
597 : ahm_(ahm), subMap_(subMap), subIt_(subIt) {}
599 friend class boost::iterator_core_access;
604 checkAdvanceToNextSubmap();
608 if (ahm_ != other.
ahm_) {
612 if (isEnd() || other.
isEnd()) {
613 return isEnd() == other.
isEnd();
624 return ahm_ ==
nullptr;
632 SubMap* thisMap = ahm_->subMaps_[subMap_].load(std::memory_order_relaxed);
633 while (subIt_ == thisMap->
end()) {
636 ahm_->numMapsAllocated_.load(std::memory_order_acquire)) {
638 thisMap = ahm_->subMaps_[subMap_].load(std::memory_order_relaxed);
639 subIt_ = thisMap->
begin();
bool equal(const ahm_iterator &other) const
uint32_t getIndex() const
bool tryLockMap(unsigned int idx)
static const uint32_t kNumSubMapBits_
iterator find(LookupKeyT k)
void atomic_hash_spin_wait(Cond condition)
SimpleRetT findAtInternal(uint32_t idx) const
ThreadCachedInt< uint64_t > numEntries_
void checkAdvanceToNextSubmap()
—— Concurrent Priority Queue Implementation ——
#define FOR_EACH_RANGE(i, begin, end)
static void destroy(AtomicHashArray *)
size_t spaceRemaining() const
uint32_t entryCountThreadCacheSize
std::atomic< SubMap * > subMaps_[kNumSubMaps_]
std::atomic< uint32_t > numMapsAllocated_
static const uint32_t kSubMapIndexMask_
uint32_t getEntryCountThreadCacheSize() const
size_type erase(key_type k)
ahm_iterator(const ahm_iterator< OtherContT, OtherVal, OtherSubIt > &o, typename std::enable_if< std::is_convertible< OtherSubIt, SubIt >::value >::type *=nullptr)
ahm_iterator(ContT *ahm, uint32_t subMap, const SubIt &subIt)
SimpleRetT findInternal(const LookupKeyT k) const
static const char *const value
SimpleRetT insertInternal(LookupKeyT key, ArgTs &&...value)
static const uint32_t kSubMapIndexShift_
static SmartPtr create(size_t maxSize, const Config &c=Config())
static const uintptr_t kLockedPtr_
static uint32_t encodeIndex(uint32_t subMap, uint32_t subMapIdx)
static const uint32_t kSecondaryMapBit_
IterVal & dereference() const
static const uint32_t kNumSubMaps_
double maxLoadFactor() const
iterator makeIter(size_t idx)
ahm_iterator< AtomicHashMap, value_type, typename SubMap::iterator > iterator
std::pair< iterator, bool > emplace(LookupKeyT k, ArgTs &&...vCtorArg)