This commit is contained in:
2024-05-09 16:49:23 -07:00
parent cdd186ed83
commit 7efd68f084

View File

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