233 InsertReturnType DoInsert(
const Key& key, ValuePtr value);
235 rcu::Variable<RawMap, RcuTraits> rcu_;
239template <
typename ValuePtrType>
240struct RcuMap<K, V, RcuMapTraits>::InsertReturnTypeImpl {
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) txn.Commit();
311template <
typename K,
typename V,
typename RcuMapTraits>
312typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
313RcuMap<K, V, RcuMapTraits>::
Insert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
314 InsertReturnType result{Get(key),
false};
315 if (result.value)
return result;
317 return DoInsert(key, std::move(value));
313RcuMap<K, V, RcuMapTraits>::
Insert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
…}
321template <
typename... Args>
322typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
323RcuMap<K, V, RcuMapTraits>::
Emplace(
const K& key, Args&&... args) {
324 InsertReturnType result{Get(key),
false};
325 if (result.value)
return result;
327 return DoInsert(key, std::make_shared<V>(std::forward<Args>(args)...));
330template <
typename K,
typename V,
typename RcuMapTraits>
331typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
332RcuMap<K, V, RcuMapTraits>::DoInsert(
const K& key,
typename RcuMap<K, V, RcuMapTraits>::ValuePtr value) {
333 auto txn = rcu_.StartWrite();
334 auto insertion_result = txn->emplace(key, std::move(value));
335 InsertReturnType result{insertion_result.first->second, insertion_result.second};
336 if (result.inserted) txn.Commit();
341template <
typename... Args>
342typename RcuMap<K, V, RcuMapTraits>::InsertReturnType
343RcuMap<K, V, RcuMapTraits>::
TryEmplace(
const K& key, Args&&... args) {
344 InsertReturnType result{Get(key),
false};
346 auto txn = rcu_.StartWrite();
347 auto insertion_result = txn->try_emplace(key,
nullptr);
348 if (insertion_result.second) {
349 result.value = insertion_result.first->second = std::make_shared<V>(std::forward<Args>(args)...);
351 result.inserted =
true;
353 result.value = insertion_result.first->second;
360template <
typename RawKey>
361void RcuMap<Key, Value, RcuMapTraits>::
InsertOrAssign(RawKey&& key, RcuMap::ValuePtr value) {
362 auto txn = rcu_.StartWrite();
363 txn->insert_or_assign(std::forward<RawKey>(key), std::move(value));
361void RcuMap<Key, Value, RcuMapTraits>::
InsertOrAssign(RawKey&& key, RcuMap::ValuePtr value) {
…}
367template <
typename K,
typename V,
typename RcuMapTraits>
370const typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Get(
const K& key) {
371 auto snapshot = rcu_.Read();
372 auto it = snapshot->find(key);
373 if (it == snapshot->end())
return {};
377template <
typename K,
typename V,
typename RcuMapTraits>
378bool RcuMap<K, V, RcuMapTraits>::
Erase(
const K& key) {
380 auto txn = rcu_.StartWrite();
381 if (txn->erase(key)) {
378bool RcuMap<K, V, RcuMapTraits>::
Erase(
const K& key) {
…}
389template <
typename K,
typename V,
typename RcuMapTraits>
390typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Pop(
const K& key) {
391 auto value = Get(key);
393 auto txn = rcu_.StartWrite();
394 if (txn->erase(key)) txn.Commit();
390typename RcuMap<K, V, RcuMapTraits>::ValuePtr RcuMap<K, V, RcuMapTraits>::
Pop(
const K& key) {
…}
399template <
typename K,
typename V,
typename RcuMapTraits>
400void RcuMap<K, V, RcuMapTraits>::
Clear() {
400void RcuMap<K, V, RcuMapTraits>::
Clear() {
…}
404template <
typename K,
typename V,
typename RcuMapTraits>
405void RcuMap<K, V, RcuMapTraits>::
Assign(RawMap new_map) {
406 rcu_.Assign(std::move(new_map));
405void RcuMap<K, V, RcuMapTraits>::
Assign(RawMap new_map) {
…}
409template <
typename K,
typename V,
typename RcuMapTraits>
410auto RcuMap<K, V, RcuMapTraits>::
StartWrite() ->
rcu::WritablePtr<RawMap, RcuTraits> {
411 return rcu_.StartWrite();
410auto RcuMap<K, V, RcuMapTraits>::
StartWrite() ->
rcu::WritablePtr<RawMap, RcuTraits> {
…}
414template <
typename K,
typename V,
typename RcuMapTraits>
415typename RcuMap<K, V, RcuMapTraits>::Snapshot RcuMap<K, V, RcuMapTraits>::
GetSnapshot()
const {
416 return {begin(), end()};
415typename RcuMap<K, V, RcuMapTraits>::Snapshot RcuMap<K, V, RcuMapTraits>::
GetSnapshot()
const {
…}