diff --git a/VersionedMap.cpp b/VersionedMap.cpp index 9eb3866..9946c7f 100644 --- a/VersionedMap.cpp +++ b/VersionedMap.cpp @@ -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;