Run skip list gc at 200% entry insertion rate
This commit is contained in:
32
SkipList.cpp
32
SkipList.cpp
@@ -423,18 +423,23 @@ public:
|
||||
}
|
||||
void swap(SkipList &other) { std::swap(header, other.header); }
|
||||
|
||||
void addConflictRanges(const Finger *fingers, int rangeCount,
|
||||
Version version) {
|
||||
// Returns the change in the number of entries
|
||||
int64_t addConflictRanges(const Finger *fingers, int rangeCount,
|
||||
Version version) {
|
||||
int64_t result = rangeCount;
|
||||
for (int r = rangeCount - 1; r >= 0; r--) {
|
||||
const Finger &startF = fingers[r * 2];
|
||||
const Finger &endF = fingers[r * 2 + 1];
|
||||
|
||||
if (endF.found() == nullptr)
|
||||
if (endF.found() == nullptr) {
|
||||
++result;
|
||||
insert(endF, endF.finger[0]->getMaxVersion(0));
|
||||
}
|
||||
|
||||
remove(startF, endF);
|
||||
result -= remove(startF, endF);
|
||||
insert(startF, version);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void detectConflicts(ReadConflictRange *ranges, int count,
|
||||
@@ -564,9 +569,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void remove(const Finger &start, const Finger &end) {
|
||||
// Returns the number of entries removed
|
||||
int64_t remove(const Finger &start, const Finger &end) {
|
||||
if (start.finger[0] == end.finger[0])
|
||||
return;
|
||||
return 0;
|
||||
|
||||
Node *x = start.finger[0]->getNext(0);
|
||||
|
||||
@@ -575,13 +581,16 @@ private:
|
||||
if (start.finger[i] != end.finger[i])
|
||||
start.finger[i]->setNext(i, end.finger[i]->getNext(i));
|
||||
|
||||
int64_t result = 0;
|
||||
while (true) {
|
||||
Node *next = x->getNext(0);
|
||||
x->destroy();
|
||||
++result;
|
||||
if (x == end.finger[0])
|
||||
break;
|
||||
x = next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void insert(const Finger &f, Version version) {
|
||||
@@ -772,17 +781,20 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
StringRef values[stripeSize];
|
||||
int64_t writeVersions[stripeSize / 2];
|
||||
int ss = stringCount - (stripes - 1) * stripeSize;
|
||||
int64_t entryDelta = 0;
|
||||
for (int s = stripes - 1; s >= 0; s--) {
|
||||
for (int i = 0; i * 2 < ss; ++i) {
|
||||
const auto &w = combinedWriteConflictRanges[s * stripeSize / 2 + i];
|
||||
values[i * 2] = w.first;
|
||||
values[i * 2 + 1] = w.second;
|
||||
keyUpdates += 3;
|
||||
}
|
||||
skipList.find(values, fingers, temp, ss);
|
||||
skipList.addConflictRanges(fingers, ss / 2, writeVersion);
|
||||
entryDelta += skipList.addConflictRanges(fingers, ss / 2, writeVersion);
|
||||
ss = stripeSize;
|
||||
}
|
||||
|
||||
// Run gc at least 200% the rate we're inserting entries
|
||||
keyUpdates += std::max<int64_t>(entryDelta, 0) * 2;
|
||||
}
|
||||
|
||||
void setOldestVersion(int64_t oldestVersion) {
|
||||
@@ -792,7 +804,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
int temp;
|
||||
std::span<const uint8_t> key = removalKey;
|
||||
skipList.find(&key, &finger, &temp, 1);
|
||||
skipList.removeBefore(oldestVersion, finger, std::exchange(keyUpdates, 10));
|
||||
skipList.removeBefore(oldestVersion, finger, std::exchange(keyUpdates, 0));
|
||||
removalArena = Arena();
|
||||
removalKey = copyToArena(
|
||||
removalArena, {finger.getValue().data(), finger.getValue().size()});
|
||||
@@ -801,7 +813,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
int64_t totalBytes = 0;
|
||||
|
||||
private:
|
||||
int64_t keyUpdates = 10;
|
||||
int64_t keyUpdates = 0;
|
||||
Arena removalArena;
|
||||
std::span<const uint8_t> removalKey;
|
||||
int64_t oldestVersion;
|
||||
|
Reference in New Issue
Block a user