233 InsertReturnType DoInsert(
const Key& key, ValuePtr value);
235 rcu::Variable<RawMap, RcuTraits> rcu_;
239template <
typename ValuePtrType>
240struct RcuMap<K, V, RcuMapTraits>::InsertReturnTypeImpl {
245template <
typename K,
typename V,
typename RcuMapTraits>
246typename RcuMap<K, V, RcuMapTraits>::ConstIterator RcuMap<K, V, RcuMapTraits>::begin()
const {
247 auto ptr = rcu_.Read();
248 const auto iter = ptr->cbegin();
249 return typename RcuMap<K, V, RcuMapTraits>::ConstIterator(std::move(ptr), iter);
252template <
typename K,
typename V,
typename RcuMapTraits>
253typename RcuMap<K, V, RcuMapTraits>::ConstIterator RcuMap<K, V, RcuMapTraits>::end()
const {
259template <
typename K,
typename V,
typename RcuMapTraits>
260typename RcuMap<K, V, RcuMapTraits>::Iterator RcuMap<K, V, RcuMapTraits>::begin() {
261 auto ptr = rcu_.Read();
262 const auto iter = ptr->cbegin();
263 return {std::move(ptr), iter};
266template <
typename K,
typename V,
typename RcuMapTraits>
267typename RcuMap<K, V, RcuMapTraits>::Iterator RcuMap<K, V, RcuMapTraits>::end() {
273template <
typename K,
typename V,
typename RcuMapTraits>
275 auto ptr = rcu_.Read();
279template <
typename K,
typename V,
typename RcuMapTraits>
282const typename RcuMap<K, V, RcuMapTraits>::ConstValuePtr RcuMap<K, V, RcuMapTraits>::
operator[](
const K& key)
const {
283 if (
auto value = Get(key)) {
289template <
typename K,
typename V,
typename RcuMapTraits>
292const typename RcuMap<K, V, RcuMapTraits>::ConstValuePtr RcuMap<K, V, RcuMapTraits>::
Get(
const K& key)
const {
294 return const_cast<RcuMap<K, V, RcuMapTraits>*>(
this)->Get(key);
297template <
typename K,
typename V,
typename RcuMapTraits>
300const typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
operator[](
const K& key) {
301 auto value = Get(key);
303 auto txn = rcu_.StartWrite();
304 auto insertion_result = txn->emplace(key, std::make_shared<V>());
305 value = insertion_result.first->second;
306 if (insertion_result.second) {
313template <
typename K,
typename V,
typename RcuMapTraits>
314typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
317 RcuMapTraits>::
Insert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
318 InsertReturnType result{Get(key),
false};
323 return DoInsert(key, std::move(value));
327template <
typename... Args>
328typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
331 RcuMapTraits>::
Emplace(
const K& key, Args&&... args) {
332 InsertReturnType result{Get(key),
false};
337 return DoInsert(key, std::make_shared<V>(std::forward<Args>(args)...));
340template <
typename K,
typename V,
typename RcuMapTraits>
341typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
344 RcuMapTraits>::DoInsert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
345 auto txn = rcu_.StartWrite();
346 auto insertion_result = txn->emplace(key, std::move(value));
347 InsertReturnType result{insertion_result.first->second, insertion_result.second};
348 if (result.inserted) {
355template <
typename... Args>
356typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
359 RcuMapTraits>::
TryEmplace(
const K& key, Args&&... args) {
360 InsertReturnType result{Get(key),
false};
362 auto txn = rcu_.StartWrite();
363 auto insertion_result = txn->try_emplace(key,
nullptr);
364 if (insertion_result.second) {
365 result.value = insertion_result.first->second = std::make_shared<V>(std::forward<Args>(args)...);
367 result.inserted =
true;
369 result.value = insertion_result.first->second;
376template <
typename RawKey>
377void RcuMap<Key, Value, RcuMapTraits>::
InsertOrAssign(RawKey&& key, RcuMap::ValuePtr value) {
378 auto txn = rcu_.StartWrite();
379 txn->insert_or_assign(std::forward<RawKey>(key), std::move(value));
383template <
typename K,
typename V,
typename RcuMapTraits>
386const typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Get(
const K& key) {
387 auto snapshot = rcu_.Read();
388 auto it = snapshot->find(key);
389 if (it == snapshot->end()) {
395template <
typename K,
typename V,
typename RcuMapTraits>
396bool RcuMap<K, V, RcuMapTraits>::
Erase(
const K& key) {
398 auto txn = rcu_.StartWrite();
399 if (txn->erase(key)) {
407template <
typename K,
typename V,
typename RcuMapTraits>
408typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Pop(
const K& key) {
409 auto value = Get(key);
411 auto txn = rcu_.StartWrite();
412 if (txn->erase(key)) {
419template <
typename K,
typename V,
typename RcuMapTraits>
420void RcuMap<K, V, RcuMapTraits>::
Clear() {
424template <
typename K,
typename V,
typename RcuMapTraits>
425void RcuMap<K, V, RcuMapTraits>::
Assign(RawMap new_map) {
426 rcu_.Assign(std::move(new_map));
429template <
typename K,
typename V,
typename RcuMapTraits>
430auto RcuMap<K, V, RcuMapTraits>::
StartWrite() ->
rcu::WritablePtr<RawMap, RcuTraits> {
431 return rcu_.StartWrite();
434template <
typename K,
typename V,
typename RcuMapTraits>
435typename RcuMap<K, V, RcuMapTraits>::Snapshot RcuMap<K, V, RcuMapTraits>::
GetSnapshot()
const {
436 return {begin(), end()};