diff --git a/golpe b/golpe index 3da8c91..ea1ea8f 160000 --- a/golpe +++ b/golpe @@ -1 +1 @@ -Subproject commit 3da8c91ddb22b3bd7f62e4a94b4afbe56c2c65c9 +Subproject commit ea1ea8f5ce1208fef8fe895f68b623369276f8de diff --git a/src/RelayCron.cpp b/src/RelayCron.cpp index ef1d80c..5d41802 100644 --- a/src/RelayCron.cpp +++ b/src/RelayCron.cpp @@ -1,5 +1,7 @@ #include "RelayServer.h" +#include "gc.h" + void RelayServer::cleanupOldEvents() { std::vector expiredLevIds; @@ -63,3 +65,14 @@ void RelayServer::cleanupOldEvents() { if (numDeleted) LI << "Deleted " << numDeleted << " ephemeral events"; } } + +void RelayServer::garbageCollect() { + quadrable::Quadrable qdb; + { + auto txn = env.txn_ro(); + qdb.init(txn); + } + qdb.checkout("events"); + + quadrableGarbageCollect(qdb, 1); +} diff --git a/src/RelayServer.h b/src/RelayServer.h index 00b1ea1..d044e74 100644 --- a/src/RelayServer.h +++ b/src/RelayServer.h @@ -160,6 +160,7 @@ struct RelayServer { void runYesstr(ThreadPool::Thread &thr); void cleanupOldEvents(); + void garbageCollect(); // Utils (can be called by any thread) diff --git a/src/cmd_compact.cpp b/src/cmd_compact.cpp index efffdb1..2f994fd 100644 --- a/src/cmd_compact.cpp +++ b/src/cmd_compact.cpp @@ -4,7 +4,7 @@ #include #include "golpe.h" -#include "render.h" +#include "gc.h" static const char USAGE[] = @@ -39,29 +39,6 @@ void cmd_compact(const std::vector &subArgs) { } qdb.checkout("events"); - quadrable::Quadrable::GarbageCollector gc(qdb); - - { - auto txn = env.txn_ro(); - gc.markAllHeads(txn); - } - - { - auto txn = env.txn_rw(); - - auto stats = gc.sweep(txn); - /* - auto stats = gc.sweep(txn, [&](uint64_t nodeId){ - quadrable::Quadrable::ParsedNode node(&qdb, txn, nodeId); - if (!node.isBranch()) throw herr("unexpected quadrable node type during gc: ", (int)node.nodeType); - return true; - }); - */ - - txn.commit(); - - LI << "Total nodes: " << stats.total; - LI << "Collected: " << stats.collected << " (" << renderPercent((double)stats.collected / stats.total) << ")"; - } + quadrableGarbageCollect(qdb, 2); } } diff --git a/src/cmd_import.cpp b/src/cmd_import.cpp index f7e2de5..0100f01 100644 --- a/src/cmd_import.cpp +++ b/src/cmd_import.cpp @@ -5,6 +5,7 @@ #include "events.h" #include "filters.h" +#include "gc.h" static const char USAGE[] = @@ -59,6 +60,7 @@ void cmd_import(const std::vector &subArgs) { logStatus(); LI << "Committing " << numCommits << " records"; + txn.commit(); txn = env.txn_rw(); @@ -91,5 +93,7 @@ void cmd_import(const std::vector &subArgs) { flushChanges(); + quadrableGarbageCollect(qdb, 2); + txn.commit(); } diff --git a/src/cmd_relay.cpp b/src/cmd_relay.cpp index bc2f0d0..d1cc0b3 100644 --- a/src/cmd_relay.cpp +++ b/src/cmd_relay.cpp @@ -48,6 +48,10 @@ void RelayServer::run() { cleanupOldEvents(); }); + cron.repeat(60 * 60 * 1'000'000UL, [&]{ + garbageCollect(); + }); + cron.setupCb = []{ setThreadName("cron"); }; cron.run(); diff --git a/src/gc.h b/src/gc.h new file mode 100644 index 0000000..334e8bb --- /dev/null +++ b/src/gc.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include "golpe.h" + +#include "render.h" + + +inline void quadrableGarbageCollect(quadrable::Quadrable &qdb, int logLevel = 0) { + quadrable::Quadrable::GarbageCollector> gc(qdb); + quadrable::Quadrable::GCStats stats; + + if (logLevel >= 2) LI << "Running garbage collection"; + + { + auto txn = env.txn_ro(); + + if (logLevel >= 2) LI << "GC: mark phase"; + gc.markAllHeads(txn); + if (logLevel >= 2) LI << "GC: sweep phase"; + stats = gc.sweep(txn); + } + + if (logLevel >= 2) { + LI << "GC: Total nodes: " << stats.total; + LI << "GC: Garbage nodes: " << stats.garbage << " (" << renderPercent((double)stats.garbage / stats.total) << ")"; + } + + if (stats.garbage) { + auto txn = env.txn_rw(); + if (logLevel >= 1) LI << "GC: deleting " << stats.garbage << " garbage nodes"; + gc.deleteNodes(txn); + txn.commit(); + } + +}