GC fixes
This commit is contained in:
@@ -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;
|
||||||
|
Reference in New Issue
Block a user