226 InsertReturnType DoInsert(
const Key& key, ValuePtr value);
228 rcu::Variable<RawMap, RcuTraits> rcu_;
232template <
typename ValuePtrType>
233struct RcuMap<K, V, RcuMapTraits>::InsertReturnTypeImpl {
238template <
typename K,
typename V,
typename RcuMapTraits>
239typename RcuMap<K, V, RcuMapTraits>::ConstIterator RcuMap<K, V, RcuMapTraits>::begin()
const {
240 auto ptr = rcu_.Read();
241 const auto iter = ptr->cbegin();
242 return typename RcuMap<K, V, RcuMapTraits>::ConstIterator(std::move(ptr), iter);
245template <
typename K,
typename V,
typename RcuMapTraits>
246typename RcuMap<K, V, RcuMapTraits>::ConstIterator RcuMap<K, V, RcuMapTraits>::end()
const {
252template <
typename K,
typename V,
typename RcuMapTraits>
253typename RcuMap<K, V, RcuMapTraits>::Iterator RcuMap<K, V, RcuMapTraits>::begin() {
254 auto ptr = rcu_.Read();
255 const auto iter = ptr->cbegin();
256 return {std::move(ptr), iter};
259template <
typename K,
typename V,
typename RcuMapTraits>
260typename RcuMap<K, V, RcuMapTraits>::Iterator RcuMap<K, V, RcuMapTraits>::end() {
266template <
typename K,
typename V,
typename RcuMapTraits>
268 auto ptr = rcu_.Read();
272template <
typename K,
typename V,
typename RcuMapTraits>
275const utils::
NotNull<
typename RcuMap<K, V, RcuMapTraits>::ConstValuePtr> RcuMap<
278 RcuMapTraits>::
operator[](
const K& key)
const {
279 if (
auto value = Get(key)) {
285template <
typename K,
typename V,
typename RcuMapTraits>
288const typename RcuMap<K, V, RcuMapTraits>::ConstValuePtr RcuMap<K, V, RcuMapTraits>::
Get(
const K& key)
const {
290 return const_cast<RcuMap<K, V, RcuMapTraits>*>(
this)->Get(key);
293template <
typename K,
typename V,
typename RcuMapTraits>
296const utils::
NotNull<
typename RcuMap<K, V, RcuMapTraits>::ValuePtr> RcuMap<K, V, RcuMapTraits>::
operator[](
const K& key
298 auto value = Get(key);
300 auto ptr = std::make_shared<V>();
301 auto txn = rcu_.StartWrite();
302 auto insertion_result = txn->emplace(key, std::move(ptr));
303 value = insertion_result.first->second;
304 if (insertion_result.second) {
311template <
typename K,
typename V,
typename RcuMapTraits>
312typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
315 RcuMapTraits>::
Insert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
316 InsertReturnType result{Get(key),
false};
321 return DoInsert(key, std::move(value));
325template <
typename... Args>
326typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
329 RcuMapTraits>::
Emplace(
const K& key, Args&&... args) {
330 InsertReturnType result{Get(key),
false};
335 return DoInsert(key, std::make_shared<V>(std::forward<Args>(args)...));
338template <
typename K,
typename V,
typename RcuMapTraits>
339typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
342 RcuMapTraits>::DoInsert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
343 auto txn = rcu_.StartWrite();
344 auto insertion_result = txn->emplace(key, std::move(value));
345 InsertReturnType result{insertion_result.first->second, insertion_result.second};
346 if (result.inserted) {
353template <
typename... Args>
354typename RcuMap<K, V, RcuMapTraits>::InsertReturnType RcuMap<
357 RcuMapTraits>::
TryEmplace(
const K& key, Args&&... args) {
358 InsertReturnType result{Get(key),
false};
360 auto txn = rcu_.StartWrite();
361 auto insertion_result = txn->try_emplace(key,
nullptr);
362 if (insertion_result.second) {
363 result.value = insertion_result.first->second = std::make_shared<V>(std::forward<Args>(args)...);
365 result.inserted =
true;
367 result.value = insertion_result.first->second;
374template <
typename RawKey>
375void RcuMap<Key, Value, RcuMapTraits>::
InsertOrAssign(RawKey&& key, RcuMap::ValuePtr value) {
376 auto txn = rcu_.StartWrite();
377 txn->insert_or_assign(std::forward<RawKey>(key), std::move(value));
381template <
typename K,
typename V,
typename RcuMapTraits>
384const typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Get(
const K& key) {
385 auto snapshot = rcu_.Read();
386 auto it = snapshot->find(key);
387 if (it == snapshot->end()) {
393template <
typename K,
typename V,
typename RcuMapTraits>
394bool RcuMap<K, V, RcuMapTraits>::
Erase(
const K& key) {
396 auto txn = rcu_.StartWrite();
397 if (txn->erase(key)) {
405template <
typename K,
typename V,
typename RcuMapTraits>
406typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Pop(
const K& key) {
407 auto value = Get(key);
409 auto txn = rcu_.StartWrite();
410 if (txn->erase(key)) {
417template <
typename K,
typename V,
typename RcuMapTraits>
418void RcuMap<K, V, RcuMapTraits>::
Clear() {
422template <
typename K,
typename V,
typename RcuMapTraits>
423void RcuMap<K, V, RcuMapTraits>::
Assign(RawMap new_map) {
424 rcu_.Assign(std::move(new_map));
427template <
typename K,
typename V,
typename RcuMapTraits>
428auto RcuMap<K, V, RcuMapTraits>::
StartWrite() ->
rcu::WritablePtr<RawMap, RcuTraits> {
429 return rcu_.StartWrite();
432template <
typename K,
typename V,
typename RcuMapTraits>
433typename RcuMap<K, V, RcuMapTraits>::Snapshot RcuMap<K, V, RcuMapTraits>::
GetSnapshot()
const {
434 return {begin(), end()};