Skip to content

Commit 2dcaff6

Browse files
committed
Add store prune method.
1 parent 7102bf0 commit 2dcaff6

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

include/bitcoin/database/impl/store.ipp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,61 @@ code CLASS::open(const event_handler& handler) NOEXCEPT
418418
return ec;
419419
}
420420

421+
TEMPLATE
422+
code CLASS::prune(const event_handler& handler) NOEXCEPT
423+
{
424+
while (!transactor_mutex_.try_lock_for(std::chrono::seconds(1)))
425+
{
426+
handler(event_t::wait_lock, table_t::store);
427+
}
428+
429+
code ec{ error::success };
430+
const auto prune = [&handler](code& ec, auto& storage, table_t table) NOEXCEPT
431+
{
432+
if (!ec)
433+
{
434+
handler(event_t::prune_table, table);
435+
if (!storage.reset())
436+
ec = error::prune_table;
437+
}
438+
};
439+
440+
const auto unload = [&handler](code& ec, auto& storage, table_t table) NOEXCEPT
441+
{
442+
if (!ec)
443+
{
444+
handler(event_t::unload_file, table);
445+
ec = storage.unload();
446+
}
447+
};
448+
449+
const auto load = [&handler](code& ec, auto& storage, table_t table) NOEXCEPT
450+
{
451+
if (!ec)
452+
{
453+
handler(event_t::load_file, table);
454+
ec = storage.load();
455+
}
456+
};
457+
458+
// Prevouts resettable if all candidates confirmed (fork is candidate top).
459+
const query<CLASS> query_{ *this };
460+
if (query_.get_fork() == query_.get_top_candidate())
461+
{
462+
// zeroize table head, set body logical size to zero.
463+
prune(ec, prevout, table_t::prevout_table);
464+
465+
// unmap body, setting mapped size to logical size (zero).
466+
unload(ec, prevout_body_, table_t::prevout_body);
467+
468+
// map body, making table usable again.
469+
load(ec, prevout_body_, table_t::prevout_body);
470+
}
471+
472+
transactor_mutex_.unlock();
473+
return ec;
474+
}
475+
421476
TEMPLATE
422477
code CLASS::snapshot(const event_handler& handler) NOEXCEPT
423478
{

include/bitcoin/database/store.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class store
6363
/// Open and load the set of tables, set locks.
6464
code open(const event_handler& handler) NOEXCEPT;
6565

66+
/// Prune prunable tables (from loaded, leaves loaded).
67+
code prune(const event_handler& handler) NOEXCEPT;
68+
6669
/// Snapshot the set of tables (from loaded, leaves loaded).
6770
code snapshot(const event_handler& handler) NOEXCEPT;
6871

test/store.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
*/
1919
#include "test.hpp"
20+
#include "mocks/blocks.hpp"
2021
#include "mocks/map_store.hpp"
2122

2223
// these are the slow tests (mmap)
@@ -274,6 +275,22 @@ BOOST_AUTO_TEST_CASE(store__open__created__success)
274275
BOOST_REQUIRE(!instance.close(events));
275276
}
276277

278+
// prune
279+
// ----------------------------------------------------------------------------
280+
// Empty store asserts so create and initialize.
281+
282+
BOOST_AUTO_TEST_CASE(store__prune__initialized__success)
283+
{
284+
settings configuration{};
285+
configuration.path = TEST_DIRECTORY;
286+
store<map> instance{ configuration };
287+
query<store<map>> query_{ instance };
288+
BOOST_REQUIRE(!instance.create(events));
289+
BOOST_REQUIRE(query_.initialize(test::genesis));
290+
BOOST_REQUIRE(!instance.prune(events));
291+
BOOST_REQUIRE(!instance.close(events));
292+
}
293+
277294
// snapshot
278295
// ----------------------------------------------------------------------------
279296

0 commit comments

Comments
 (0)