77 typename HashFn = std::hash<KeyType>,
78 typename KeyEqual = std::equal_to<KeyType>,
79 typename Allocator = std::allocator<uint8_t>,
81 template <
typename>
class Atom = std::atomic,
125 segments_[
i].store(
nullptr, std::memory_order_relaxed);
133 o.segments_[
i].load(std::memory_order_relaxed),
134 std::memory_order_relaxed);
135 o.segments_[
i].store(
nullptr, std::memory_order_relaxed);
141 auto seg =
segments_[
i].load(std::memory_order_relaxed);
147 o.segments_[
i].load(std::memory_order_relaxed),
148 std::memory_order_relaxed);
149 o.segments_[
i].store(
nullptr, std::memory_order_relaxed);
163 auto seg =
segments_[
i].load(std::memory_order_relaxed);
173 auto seg =
segments_[
i].load(std::memory_order_acquire);
186 auto seg =
segments_[segment].load(std::memory_order_acquire);
187 if (!seg || !seg->find(res.
it_, k)) {
210 std::pair<key_type, mapped_type>&&
foo) {
212 std::pair<ConstIterator, bool> res(
213 std::piecewise_construct,
214 std::forward_as_tuple(
this, segment),
215 std::forward_as_tuple(
false));
220 template <
typename Key,
typename Value>
223 std::pair<ConstIterator, bool> res(
224 std::piecewise_construct,
225 std::forward_as_tuple(
this, segment),
226 std::forward_as_tuple(
false));
228 res.first.it_, std::forward<Key>(
k), std::forward<Value>(
v));
232 template <
typename Key,
typename...
Args>
235 std::pair<ConstIterator, bool> res(
236 std::piecewise_construct,
237 std::forward_as_tuple(
this, segment),
238 std::forward_as_tuple(
false));
240 res.first.it_, std::forward<Key>(
k), std::forward<Args>(args)...);
244 template <
typename...
Args>
247 auto node = (
Node*)Allocator().allocate(
sizeof(
Node));
248 new (node)
Node(std::forward<Args>(args)...);
250 std::pair<ConstIterator, bool> res(
251 std::piecewise_construct,
252 std::forward_as_tuple(
this, segment),
253 std::forward_as_tuple(
false));
255 res.first.it_, node->getItem().first, node);
258 Allocator().deallocate((
uint8_t*)node,
sizeof(
Node));
263 template <
typename Key,
typename Value>
266 std::pair<ConstIterator, bool> res(
267 std::piecewise_construct,
268 std::forward_as_tuple(
this, segment),
269 std::forward_as_tuple(
false));
271 res.first.it_, std::forward<Key>(
k), std::forward<Value>(
v));
275 template <
typename Key,
typename Value>
279 auto seg =
segments_[segment].load(std::memory_order_acquire);
284 seg->assign(res.
it_, std::forward<Key>(
k), std::forward<Value>(
v));
293 template <
typename Key,
typename Value>
298 auto seg =
segments_[segment].load(std::memory_order_acquire);
302 auto r = seg->assign_if_equal(
304 std::forward<Key>(
k),
306 std::forward<Value>(desired));
317 auto item =
insert(key, ValueType());
318 return item.first->second;
321 const ValueType
at(
const KeyType& key)
const {
322 auto item =
find(key);
323 if (item ==
cend()) {
324 throw std::out_of_range(
"at(): value out of range");
333 auto seg =
segments_[segment].load(std::memory_order_acquire);
337 return seg->erase(k);
353 auto seg =
segments_[
i].load(std::memory_order_acquire);
361 count = count >> ShardBits;
363 auto seg =
segments_[
i].load(std::memory_order_acquire);
374 auto seg =
segments_[
i].load(std::memory_order_acquire);
388 auto seg =
segments_[
i].load(std::memory_order_acquire);
390 seg->max_load_factor(factor);
418 return !(*
this == o);
462 if (segment_ < parent_->NumShards) {
480 auto h = HashFn()(
k);
490 return h & (NumShards - 1);
497 newseg =
new (newseg)
499 if (!
segments_[i].compare_exchange_strong(seg, newseg)) {
bool insert_or_assign(Iterator &it, Key &&k, Value &&v)
SegmentT * ensureSegment(uint64_t i) const
bool empty() const noexcept
ConstIterator & operator=(const ConstIterator &o)=delete
std::pair< ConstIterator, bool > try_emplace(Key &&k, Args &&...args)
ConstIterator(ConstIterator &&o) noexcept
constexpr T nextPowTwo(T const v)
ConstIterator cbegin() const noexcept
ConstIterator cend() const noexcept
const value_type * operator->() const
concurrenthashmap::NodeT< KeyType, ValueType, Allocator, Atom > Node
ConstIterator & operator++()
constexpr detail::Map< Move > move
folly::Optional< ConstIterator > assign(Key &&k, Value &&v)
internal::KeyMatcher< M > Key(M inner_matcher)
bool try_emplace(Iterator &it, Key &&k, Args &&...args)
const value_type & operator*() const
bool emplace(Iterator &it, const KeyType &k, Node *node)
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
std::pair< ConstIterator, bool > insert(Key &&k, Value &&v)
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
size_type erase(const key_type &k)
ConstIterator(const ConcurrentHashMap *parent)
const ValueType at(const KeyType &key) const
ConstIterator const_iterator
folly::Optional< ConstIterator > assign_if_equal(Key &&k, const ValueType &expected, Value &&desired)
bool operator==(const ConstIterator &o) const
ConcurrentHashMap(size_t size=8, size_t max_size=0)
uint64_t pickSegment(const KeyType &k) const
const ValueType operator[](const KeyType &key)
ConstIterator find(const KeyType &k) const
ConcurrentHashMap(ConcurrentHashMap &&o) noexcept
bool Value(const T &value, M matcher)
ConstIterator & operator=(ConstIterator &&o) noexcept
void max_load_factor(float factor)
std::pair< ConstIterator, bool > insert(std::pair< key_type, mapped_type > &&foo)
ConstIterator(const ConstIterator &o)=delete
static constexpr uint64_t NumShards
ConstIterator end() const noexcept
std::pair< ConstIterator, bool > emplace(Args &&...args)
ConstIterator begin() const noexcept
size_t size() const noexcept
T exchange(T &obj, U &&new_value)
size_type erase(const key_type &key)
const ConcurrentHashMap * parent_
ConstIterator(const ConcurrentHashMap *parent, uint64_t segment)
void reserve(size_t count)
bool insert(Iterator &it, std::pair< key_type, mapped_type > &&foo)
Atom< SegmentT * > segments_[NumShards]
float max_load_factor() const
ConcurrentHashMap & operator=(ConcurrentHashMap &&o)
ConstIterator erase(ConstIterator &pos)
ConstIterator(uint64_t shards)
std::pair< const KeyType, ValueType > value_type
folly::Function< void()> parent
detail::ConcurrentHashMapSegment< KeyType, ValueType, ShardBits, HashFn, KeyEqual, Allocator, Atom, Mutex > SegmentT
bool operator!=(const ConstIterator &o) const
std::pair< ConstIterator, bool > insert_or_assign(Key &&k, Value &&v)