GC fixes
This commit is contained in:
@@ -111,10 +111,20 @@ struct Entry {
|
||||
|
||||
Entry *addref() const {
|
||||
++refCount;
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf("addref %p to %d\n", this, refCount);
|
||||
}
|
||||
#endif
|
||||
return (Entry *)this;
|
||||
}
|
||||
|
||||
void delref() const {
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf("delref %p to %d\n", this, refCount - 1);
|
||||
}
|
||||
#endif
|
||||
if (--refCount == 0) {
|
||||
free((void *)this);
|
||||
}
|
||||
@@ -165,7 +175,8 @@ constexpr uint32_t kUpsizeNodes = kUpsizeBytes / sizeof(Node);
|
||||
static_assert(kUpsizeNodes * sizeof(Node) == kUpsizeBytes);
|
||||
|
||||
struct BitSet {
|
||||
explicit BitSet(uint32_t size) : words((uint64_t *)malloc(size / 8 + 8)) {}
|
||||
explicit BitSet(uint32_t size)
|
||||
: words((uint64_t *)calloc(size / 64 + 1, 8)) {}
|
||||
|
||||
bool test(uint32_t i) const {
|
||||
return words[i >> 6] & (uint64_t(1) << (i & 63));
|
||||
@@ -250,6 +261,14 @@ struct MemManager {
|
||||
}
|
||||
|
||||
void gc(const uint32_t *roots, int numRoots, int64_t oldestVersion) {
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf("GC roots:\n");
|
||||
for (int i = 0; i < numRoots; ++i) {
|
||||
printf(" %u\n", roots[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Calculate reachable set
|
||||
BitSet reachable{next};
|
||||
// Each node has at most 3 children and nodes along the search path aren't
|
||||
@@ -257,7 +276,17 @@ struct MemManager {
|
||||
uint32_t stack[2 * kPathLengthUpperBound];
|
||||
int stackIndex = 0;
|
||||
auto tryPush = [&](uint32_t p) {
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf(" GC: visit: %u\n", p);
|
||||
}
|
||||
#endif
|
||||
if (!reachable.set(p)) {
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf(" GC: push on to stack: %u\n", p);
|
||||
}
|
||||
#endif
|
||||
assert(stackIndex < sizeof(stack) / sizeof(stack[0]));
|
||||
stack[stackIndex++] = p;
|
||||
}
|
||||
@@ -279,7 +308,9 @@ struct MemManager {
|
||||
tryPush(node.pointer[node.replacedPointer]);
|
||||
}
|
||||
}
|
||||
tryPush(node.pointer[2]);
|
||||
if (node.pointer[2] != 0) {
|
||||
tryPush(node.pointer[2]);
|
||||
}
|
||||
} else {
|
||||
if (node.pointer[0] != 0) {
|
||||
tryPush(node.pointer[0]);
|
||||
@@ -480,6 +511,11 @@ struct VersionedMap::Impl {
|
||||
|
||||
auto doCopy = [&]() {
|
||||
uint32_t copy = mm.allocate();
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf("Copy %u to %u\n", node, copy);
|
||||
}
|
||||
#endif
|
||||
auto &c = mm.base[copy];
|
||||
c.entry = n.entry->addref();
|
||||
c.pointer[which] = child;
|
||||
@@ -860,6 +896,11 @@ VersionedMap::Iterator::operator=(Iterator &&other) noexcept {
|
||||
|
||||
VersionedMap::Iterator::VersionedMutation
|
||||
VersionedMap::Iterator::operator*() const {
|
||||
#if DEBUG_VERBOSE
|
||||
if (debugVerboseEnabled) {
|
||||
printf("Dereference %u\n", impl->finger.backNode());
|
||||
}
|
||||
#endif
|
||||
assert(impl->finger.searchPathSize() != 0);
|
||||
assert(impl->mutationIndex < impl->mutationCount);
|
||||
assert(impl->mutationIndex >= 0);
|
||||
@@ -1100,6 +1141,10 @@ int64_t VersionedMap::getVersion() const { return impl->latestVersion; }
|
||||
|
||||
int64_t VersionedMap::getOldestVersion() const { return impl->oldestVersion; }
|
||||
|
||||
void VersionedMap::setOldestVersion(int64_t oldestVersion) {
|
||||
impl->setOldestVersion(oldestVersion);
|
||||
}
|
||||
|
||||
// TODO implement getBytes
|
||||
|
||||
// ==================== END IMPLEMENTATION ====================
|
||||
@@ -1122,6 +1167,7 @@ void VersionedMap::Impl::printInOrderHelper(int64_t version, uint32_t node,
|
||||
for (int i = 0; i < depth; ++i) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("node %u: ", node);
|
||||
printf("%.*s", mm.base[node].entry->keyLen, mm.base[node].entry->getKey());
|
||||
if (mm.base[node].entry->valLen >= 0) {
|
||||
printf(" -> '%.*s' @ %" PRId64, mm.base[node].entry->valLen,
|
||||
@@ -1181,11 +1227,10 @@ int main() {
|
||||
}
|
||||
const int64_t v = 3;
|
||||
cast(versionedMap)->printInOrder(v);
|
||||
weaselab::VersionedMap::Key k = {(const uint8_t *)"a", 1};
|
||||
weaselab::VersionedMap::Key k = {(const uint8_t *)"a", 2};
|
||||
weaselab::VersionedMap::Iterator iter;
|
||||
versionedMap.firstGeq(&k, &v, &iter, 1);
|
||||
auto begin = versionedMap.begin(v);
|
||||
assert(iter == begin);
|
||||
versionedMap.setOldestVersion(2);
|
||||
breakpoint_me();
|
||||
for (auto end = versionedMap.end(v); iter != end; ++iter) {
|
||||
const auto &m = *iter;
|
||||
|
Reference in New Issue
Block a user