Fix iterator invalidation bug
Standard says operator[] may invalidate iterators. Never actually crashed though /shrug
This commit is contained in:
@@ -53,17 +53,21 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
if (keyUpdates < 100) {
|
if (keyUpdates < 100) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
auto iter = map.find(removalKey);
|
||||||
for (; keyUpdates > 0 && removalIter != map.end(); --keyUpdates) {
|
if (iter == map.end()) {
|
||||||
if (removalIter->second <= oldestVersion) {
|
iter = map.begin();
|
||||||
removalIter = map.erase(removalIter);
|
}
|
||||||
|
for (; keyUpdates > 0 && iter != map.end(); --keyUpdates) {
|
||||||
|
if (iter->second <= oldestVersion) {
|
||||||
|
iter = map.erase(iter);
|
||||||
} else {
|
} else {
|
||||||
++removalIter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (iter == map.end()) {
|
||||||
if (removalIter == map.end()) {
|
removalKey.clear();
|
||||||
removalIter = map.begin();
|
} else {
|
||||||
|
removalKey = iter->first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +75,7 @@ private:
|
|||||||
int64_t keyUpdates = 0;
|
int64_t keyUpdates = 0;
|
||||||
int64_t oldestVersion;
|
int64_t oldestVersion;
|
||||||
std::unordered_map<std::string, int64_t, string_hash, std::equal_to<>> map;
|
std::unordered_map<std::string, int64_t, string_hash, std::equal_to<>> map;
|
||||||
|
std::string removalKey;
|
||||||
// This iterator outliving the call to setOldestVersion is only safe because
|
|
||||||
// we only erase from within setOldestVersion
|
|
||||||
decltype(map.begin()) removalIter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ConflictSet::check(const ReadRange *reads, Result *results,
|
void ConflictSet::check(const ReadRange *reads, Result *results,
|
||||||
|
Reference in New Issue
Block a user