126 int64_t
Insert(std::unique_ptr<V> value);
135 void ApplyPendingModifications() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
137 void UpdateHasPendingModifications() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
139 mutable
absl::Mutex mutex_;
140 std::atomic<
bool> has_pending_modifications_ =
false;
141 int64_t next_id_ ABSL_GUARDED_BY(mutex_) = 0;
143 std::vector<
std::pair<int64_t,
std::unique_ptr<V>>> elements_;
144 std::vector<
std::pair<int64_t,
std::unique_ptr<V>>> pending_inserts_
145 ABSL_GUARDED_BY(mutex_);
146 absl::flat_hash_set<int64_t> pending_deletes_ ABSL_GUARDED_BY(mutex_);
154absl::Span<const
std::pair<int64_t,
std::unique_ptr<V>>>
156 if (has_pending_modifications_.load(std::memory_order_relaxed)) {
157 absl::MutexLock lock(mutex_);
158 ApplyPendingModifications();
160 return absl::MakeConstSpan(elements_);
165 absl::MutexLock lock(mutex_);
166 return static_cast<int64_t
>(elements_.size() + pending_inserts_.size()) -
167 static_cast<int64_t
>(pending_deletes_.size());
172 absl::MutexLock lock(mutex_);
173 if (pending_deletes_.contains(
id)) {
176 for (
const auto& [key, value] : pending_inserts_) {
181 for (
const auto& [key, value] : elements_) {
191 absl::MutexLock lock(mutex_);
192 std::vector<std::pair<int64_t, V*>> result;
193 for (
const auto& [
id, diff] : elements_) {
194 if (!pending_deletes_.contains(
id)) {
195 result.push_back({id, diff.get()});
198 for (
const auto& [
id, diff] : pending_inserts_) {
199 if (!pending_deletes_.contains(
id)) {
200 result.push_back({id, diff.get()});
208 absl::MutexLock lock(mutex_);
209 if (has_pending_modifications_.load()) {
210 ApplyPendingModifications();
212 for (
const auto& [key, value] : elements_) {
222 absl::MutexLock lock(mutex_);
223 const int64_t result = next_id_;
225 pending_inserts_.push_back(std::make_pair(result, std::move(value)));
226 has_pending_modifications_ =
true;
232 absl::MutexLock lock(mutex_);
233 for (
auto it = pending_inserts_.begin(); it != pending_inserts_.end(); ++it) {
234 if (it->first == key) {
235 pending_inserts_.erase(it);
236 UpdateHasPendingModifications();
240 for (
const auto& [k, v] : elements_) {
242 auto [unused, inserted] = pending_deletes_.insert(k);
244 UpdateHasPendingModifications();
254 if (!pending_deletes_.empty()) {
256 &elements_, [
this](
const std::pair<int64_t, std::unique_ptr<V>>& entry)
257 ABSL_SHARED_LOCKS_REQUIRED(mutex_) {
258 return pending_deletes_.contains(entry.first);
260 pending_deletes_.clear();
262 for (
auto& kv : pending_inserts_) {
263 elements_.push_back(std::move(kv));
265 pending_inserts_.clear();
266 has_pending_modifications_ =
false;
271 has_pending_modifications_ =
272 !pending_inserts_.empty() || !pending_deletes_.empty();