Check insertion takes place before upsize check
This commit is contained in:
29
RootSet.cpp
29
RootSet.cpp
@@ -70,8 +70,14 @@ struct RootSet::Impl {
|
|||||||
void add(uint32_t node, int64_t version) {
|
void add(uint32_t node, int64_t version) {
|
||||||
ThreadSafeHandle::Impl *h = handle.load(std::memory_order_relaxed);
|
ThreadSafeHandle::Impl *h = handle.load(std::memory_order_relaxed);
|
||||||
|
|
||||||
|
auto end = h->end.load(std::memory_order_relaxed);
|
||||||
|
|
||||||
|
if (h->roots()[end - 1] == node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Upsize if necessary
|
// Upsize if necessary
|
||||||
if (h->end.load(std::memory_order_relaxed) == h->capacity) {
|
if (end == h->capacity) {
|
||||||
h->next = nullptr;
|
h->next = nullptr;
|
||||||
auto begin = h->lastLeq(oldestVersion);
|
auto begin = h->lastLeq(oldestVersion);
|
||||||
if (lastToFree != nullptr) {
|
if (lastToFree != nullptr) {
|
||||||
@@ -81,23 +87,20 @@ struct RootSet::Impl {
|
|||||||
firstToFree = h;
|
firstToFree = h;
|
||||||
lastToFree = h;
|
lastToFree = h;
|
||||||
}
|
}
|
||||||
auto *newH = ThreadSafeHandle::Impl::create((h->capacity - begin) * 2);
|
auto newEnd = h->capacity - begin;
|
||||||
memcpy(newH->roots(), h->roots() + begin,
|
auto *newH = ThreadSafeHandle::Impl::create(newEnd * 2);
|
||||||
sizeof(h->roots()[0]) * (h->capacity - begin));
|
memcpy(newH->roots(), h->roots() + begin, sizeof(h->roots()[0]) * newEnd);
|
||||||
memcpy(newH->versions(), h->versions() + begin,
|
memcpy(newH->versions(), h->versions() + begin,
|
||||||
sizeof(h->versions()[0]) * (h->capacity - begin));
|
sizeof(h->versions()[0]) * newEnd);
|
||||||
newH->end.store(h->capacity - begin, std::memory_order_relaxed);
|
newH->end.store(newEnd, std::memory_order_relaxed);
|
||||||
handle.store(newH, std::memory_order_release);
|
handle.store(newH, std::memory_order_release);
|
||||||
h = newH;
|
h = newH;
|
||||||
|
end = newEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = h->end.load(std::memory_order_relaxed);
|
h->roots()[end] = node;
|
||||||
|
h->versions()[end] = version;
|
||||||
if (h->roots()[end - 1] != node) {
|
h->end.store(end + 1, std::memory_order_release);
|
||||||
h->roots()[end] = node;
|
|
||||||
h->versions()[end] = version;
|
|
||||||
h->end.store(end + 1, std::memory_order_release);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOldestVersion(int64_t oldestVersion) {
|
void setOldestVersion(int64_t oldestVersion) {
|
||||||
|
Reference in New Issue
Block a user