258 InsertReturnType DoInsert(
const Key& key, ValuePtr value);
264template <
typename ValuePtrType>
270template <
typename K,
typename V,
typename RcuMapTraits>
271typename RcuMap<K, V, RcuMapTraits>::ConstIterator
RcuMap<K, V, RcuMapTraits>::begin()
const {
272 auto ptr = rcu_.Read();
273 const auto iter = ptr->cbegin();
274 return typename RcuMap<K, V, RcuMapTraits>::ConstIterator(std::move(ptr), iter);
277template <
typename K,
typename V,
typename RcuMapTraits>
278typename RcuMap<K, V, RcuMapTraits>::ConstIterator
RcuMap<K, V, RcuMapTraits>::end()
const {
284template <
typename K,
typename V,
typename RcuMapTraits>
285typename RcuMap<K, V, RcuMapTraits>::Iterator
RcuMap<K, V, RcuMapTraits>::begin() {
286 auto ptr = rcu_.Read();
287 const auto iter = ptr->cbegin();
288 return {std::move(ptr), iter};
291template <
typename K,
typename V,
typename RcuMapTraits>
292typename RcuMap<K, V, RcuMapTraits>::Iterator
RcuMap<K, V, RcuMapTraits>::end() {
298template <
typename K,
typename V,
typename RcuMapTraits>
300 auto ptr = rcu_.Read();
304template <
typename K,
typename V,
typename RcuMapTraits>
310 RcuMapTraits>::
operator[](
const K& key)
const {
311 if (
auto value = Get(key)) {
318template <
typename CompatibleKey>
321const typename RcuMap<K, V, RcuMapTraits>::ConstValuePtr
RcuMap<K, V, RcuMapTraits>::
Get(
const CompatibleKey& key
324 return const_cast<
RcuMap<K, V, RcuMapTraits>*>(
this)->Get(key);
328template <
typename CompatibleKey>
331const typename RcuMap<K, V, RcuMapTraits>::ValuePtr
RcuMap<K, V, RcuMapTraits>::
Get(
const CompatibleKey& key) {
332 auto snapshot = rcu_.Read();
333 auto it = snapshot->find(key);
334 if (it == snapshot->end()) {
340template <
typename K,
typename V,
typename RcuMapTraits>
345 auto value = Get(key);
347 auto ptr = std::make_shared<V>();
348 auto txn = rcu_.StartWrite();
349 auto insertion_result = txn->emplace(key, std::move(ptr));
350 value = insertion_result.first->second;
351 if (insertion_result.second) {
358template <
typename K,
typename V,
typename RcuMapTraits>
359typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
RcuMap<
362 RcuMapTraits>::
Insert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
363 InsertReturnType result{.value = Get(key), .inserted =
false};
368 return DoInsert(key, std::move(value));
372template <
typename... Args>
373typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
RcuMap<
376 RcuMapTraits>::
Emplace(
const K& key, Args&&... args) {
377 InsertReturnType result{.value = Get(key), .inserted =
false};
382 return DoInsert(key, std::make_shared<V>(std::forward<Args>(args)...));
385template <
typename K,
typename V,
typename RcuMapTraits>
386typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
RcuMap<
389 RcuMapTraits>::DoInsert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
390 auto txn = rcu_.StartWrite();
391 auto insertion_result = txn->emplace(key, std::move(value));
392 InsertReturnType result{.value = insertion_result.first->second, .inserted = insertion_result.second};
393 if (result.inserted) {
400template <
typename... Args>
401typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
RcuMap<
404 RcuMapTraits>::
TryEmplace(
const K& key, Args&&... args) {
405 InsertReturnType result{.value = Get(key), .inserted =
false};
407 auto txn = rcu_.StartWrite();
408 auto insertion_result = txn->try_emplace(key,
nullptr);
409 if (insertion_result.second) {
410 result.value = insertion_result.first->second = std::make_shared<V>(std::forward<Args>(args)...);
412 result.inserted =
true;
414 result.value = insertion_result.first->second;
421template <
typename RawKey>
423 auto txn = rcu_.StartWrite();
424 txn->insert_or_assign(std::forward<RawKey>(key), std::move(value));
428template <
typename K,
typename V,
typename RcuMapTraits>
431 auto txn = rcu_.StartWrite();
432 if (txn->erase(key)) {
440template <
typename K,
typename V,
typename RcuMapTraits>
441typename RcuMap<K, V, RcuMapTraits>::ValuePtr
RcuMap<K, V, RcuMapTraits>::
Pop(
const K& key) {
442 auto value = Get(key);
444 auto txn = rcu_.StartWrite();
445 if (txn->erase(key)) {
452template <
typename K,
typename V,
typename RcuMapTraits>
457template <
typename K,
typename V,
typename RcuMapTraits>
459 rcu_.Assign(std::move(new_map));
462template <
typename K,
typename V,
typename RcuMapTraits>
464 return rcu_.StartWrite();
467template <
typename K,
typename V,
typename RcuMapTraits>
469 return {begin(), end()};
477 RcuMapTraits>::RcuMapIterator(
ReadablePtr<MapType, RcuTraits>&& ptr,
typename MapType::const_iterator iter)