Skip to content

Commit bbd836e

Browse files
committed
sync: Add merge helper
1 parent 14799e9 commit bbd836e

3 files changed

Lines changed: 18 additions & 15 deletions

File tree

layers/sync/sync_access_context.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,11 +494,7 @@ AccessMap::iterator AccessContext::DoUpdateAccessState(AccessMap::iterator pos,
494494
AccessMap::iterator merge_last = end;
495495
const auto finish_merge = [&]() {
496496
if (merge_first != end && merge_first != merge_last) {
497-
const AccessRange merged_range(merge_first->first.begin, merge_last->first.end);
498-
AccessState merged_state = merge_last->second;
499-
const auto next = std::next(merge_last);
500-
access_state_map_.Erase(merge_first, next);
501-
access_state_map_.Insert(next, merged_range, merged_state);
497+
access_state_map_.Merge(merge_first, std::next(merge_last));
502498
}
503499
};
504500
const auto track_updated_range = [&](AccessMap::iterator updated) {

layers/sync/sync_access_map.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ void AccessMap::Erase(iterator first, iterator last) {
4747
}
4848
}
4949

50+
AccessMap::iterator AccessMap::Merge(iterator first, iterator last) {
51+
assert(first != last);
52+
auto merge_last = last;
53+
--merge_last;
54+
assert(first != merge_last);
55+
56+
const AccessRange merged_range(first->first.begin, merge_last->first.end);
57+
auto node = impl_map_.extract(merge_last);
58+
Erase(first, last);
59+
node.key() = merged_range;
60+
return impl_map_.insert(last, std::move(node));
61+
}
62+
5063
AccessMap::iterator AccessMap::Insert(const_iterator hint, const AccessRange& range, const AccessState& access_state) {
5164
assert(range.non_empty());
5265
bool hint_open;
@@ -193,16 +206,7 @@ void Consolidate(AccessMap& map) {
193206

194207
// Current isn't in the active merge range. If there is a non-trivial merge range, we resolve it here.
195208
if (merge_first != merge_last) {
196-
// IFF there is more than one range in (merge_first, merge_last) <- again noting the *inclusive* last
197-
// Create a new Val spanning (first, last), substitute it for the multiple entries.
198-
199-
const AccessRange merged_range(merge_first->first.begin, merge_last->first.end);
200-
AccessState access = merge_last->second;
201-
202-
// Note that current points to merge_last + 1, and is valid even if at map_end for these operations
203-
map.Erase(merge_first, current);
204-
205-
map.Insert(current, merged_range, std::move(access));
209+
map.Merge(merge_first, current);
206210
}
207211
}
208212
}

layers/sync/sync_access_map.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class AccessMap {
7676
void Clear() { impl_map_.clear(); }
7777
iterator Erase(const iterator& pos);
7878
void Erase(iterator first, iterator last);
79+
// Merge at least two entries in [first, last), retaining the last entry's state.
80+
// The caller must ensure the entries are adjacent and their states can be merged.
81+
iterator Merge(iterator first, iterator last);
7982
iterator Insert(const_iterator hint, const AccessRange& range, const AccessState& access_state);
8083
iterator InfillGap(const_iterator range_lower_bound, const AccessRange& range, const AccessState& access_state);
8184
void InfillGaps(const AccessRange& range, const AccessState& access_state);

0 commit comments

Comments
 (0)