small_map.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 // SPDX-License-Identifier: BSD-3-Clause
4 // SPDX-FileCopyrightText: Czech Technical University in Prague
5 
13 #include <algorithm>
14 #include <list>
15 #include <mutex>
16 #include <utility>
17 
18 namespace cras
19 {
20 
31 template<typename K, typename V>
32 class SmallMap
33 {
34 public:
40  V& operator[](const K& key)
41  {
42  return this->insertIfNew(key);
43  }
44 
51  const V& at(const K& key) const
52  {
53  const auto searchFn = [&key](const auto& item) {return item.first == key;};
54  auto it = ::std::find_if(this->data.begin(), this->data.end(), searchFn);
55  if (__builtin_expect(it == this->data.end(), 0))
56  throw ::std::out_of_range("Key not found");
57  return it->second;
58  }
59 
65  bool contains(const K& key) const
66  {
67  const auto searchFn = [&key](const auto& item) {return item.first == key;};
68  auto it = ::std::find_if(this->data.begin(), this->data.end(), searchFn);
69  return it != this->data.end();
70  }
71 
78  template<typename... Args>
79  V& insertIfNew(const K& key, Args&&... args)
80  {
81  const auto searchFn = [&key](const auto& item) {return item.first == key;};
82  auto it = ::std::find_if(this->data.begin(), this->data.end(), searchFn);
83  if (__builtin_expect(it == this->data.end(), 0))
84  {
85  ::std::unique_lock<::std::mutex> lock(this->mutex);
86  // Check once again with the lock; if key is still not there, insert it, otherwise find it
87  it = ::std::find_if(this->data.begin(), this->data.end(), searchFn);
88  if (__builtin_expect(it == this->data.end(), 1))
89  // Do not use emplace_back - its reference-returning variant is C++17 only
90  it = this->data.emplace(this->data.end(), key, V{::std::forward<Args>(args)...});
91  }
92  return it->second;
93  }
94 
99  size_t size() const
100  {
101  return this->data.size();
102  }
103 
108  bool empty() const
109  {
110  return this->data.empty();
111  }
112 
113 private:
114  ::std::list<::std::pair<K, V>> data;
115  ::std::mutex mutex;
116 };
117 
118 
128 template<typename K>
129 class SmallSet
130 {
131 public:
137  bool contains(const K& key) const
138  {
139  return ::std::find(this->data.begin(), this->data.end(), key) != this->data.end();
140  }
141 
147  bool insert(const K& key)
148  {
149  auto it = std::find(this->data.begin(), this->data.end(), key);
150  if (__builtin_expect(it == this->data.end(), 0))
151  {
152  std::unique_lock<std::mutex> lock(this->mutex);
153  // Check once again with the lock; if key is still not there, insert it, otherwise find it
154  it = std::find(this->data.begin(), this->data.end(), key);
155  if (__builtin_expect(it == this->data.end(), 1))
156  {
157  this->data.emplace(this->data.end(), key);
158  return true;
159  }
160  }
161  return false;
162  }
163 
168  size_t size() const
169  {
170  return this->data.size();
171  }
172 
177  bool empty() const
178  {
179  return this->data.empty();
180  }
181 
182 private:
183  ::std::list<K> data;
184  ::std::mutex mutex;
185 };
186 
187 }
cras
Definition: any.hpp:15
cras::SmallMap
Simple map implemented on top of a std::list<std::pair>. The map is append-only, with lock-free reads...
Definition: small_map.hpp:32
cras::SmallMap::mutex
::std::mutex mutex
Definition: small_map.hpp:115
cras::SmallSet::mutex
::std::mutex mutex
Definition: small_map.hpp:184
cras::SmallSet::contains
bool contains(const K &key) const
Check whether the given key is stored in this set.
Definition: small_map.hpp:137
cras::SmallSet::data
::std::list< K > data
Definition: small_map.hpp:183
cras::SmallMap::insertIfNew
V & insertIfNew(const K &key, Args &&... args)
Search this map for the key. If it is not found, store the key with a value constructed from args.
Definition: small_map.hpp:79
cras::SmallSet
Simple set implemented on top of a std::list. The set is append-only, with lock-free reads and mutex-...
Definition: small_map.hpp:129
cras::SmallMap::data
::std::list<::std::pair< K, V > > data
Definition: small_map.hpp:114
cras::SmallMap::size
size_t size() const
Return the number of elements of this map.
Definition: small_map.hpp:99
cras::SmallMap::at
const V & at(const K &key) const
Get the stored value for the given key.
Definition: small_map.hpp:51
cras::SmallSet::empty
bool empty() const
Return whether this map is empty.
Definition: small_map.hpp:177
cras::SmallSet::insert
bool insert(const K &key)
Search this set for the key. If it is not found, store the key.
Definition: small_map.hpp:147
cras::SmallMap::empty
bool empty() const
Return whether this map is empty.
Definition: small_map.hpp:108
cras::SmallMap::contains
bool contains(const K &key) const
Check whether the given key is stored in this map.
Definition: small_map.hpp:65
cras::SmallMap::operator[]
V & operator[](const K &key)
Find (or insert a default-constructed value) the value for the given key.
Definition: small_map.hpp:40
args
cras::SmallSet::size
size_t size() const
Return the number of elements of this map.
Definition: small_map.hpp:168


cras_cpp_common
Author(s): Martin Pecka
autogenerated on Tue Nov 26 2024 03:49:04