From 636328fdc2483fa840be33a895971e89d9536ec1 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Sun, 28 Jan 2018 00:55:43 -0500 Subject: [PATCH] roots: add scan-mode 2 "oldest crawler first" Add a third scan mode with alternative trade-offs. Benefits: Good sequential read performance. Avoids race conditions described in https://github.com/Zygo/bees/issues/27. Avoids diverting scan resources into short-lived snapshots before their long-lived origin subvols are fully scanned. Drawbacks: Takes the longest time of the three implemented scan-modes to free space in extents that are shared between snapshots. Uses the maximum amount of temporary space. Signed-off-by: Zygo Blaxell --- src/bees-roots.cc | 26 ++++++++++++++++++++++++++ src/bees.h | 1 + 2 files changed, 27 insertions(+) diff --git a/src/bees-roots.cc b/src/bees-roots.cc index c94da6f..f1f2e34 100644 --- a/src/bees-roots.cc +++ b/src/bees-roots.cc @@ -56,6 +56,7 @@ BeesRoots::scan_mode_ntoa(BeesRoots::ScanMode mode) static const bits_ntoa_table table[] = { NTOA_TABLE_ENTRY_ENUM(SCAN_MODE_ZERO), NTOA_TABLE_ENTRY_ENUM(SCAN_MODE_ONE), + NTOA_TABLE_ENTRY_ENUM(SCAN_MODE_TWO), NTOA_TABLE_ENTRY_ENUM(SCAN_MODE_COUNT), NTOA_TABLE_ENTRY_END() }; @@ -262,6 +263,7 @@ BeesRoots::crawl_roots() } switch (s_scan_mode) { + case SCAN_MODE_ZERO: { // Scan the same inode/offset tuple in each subvol (good for snapshots) BeesFileRange first_range; @@ -289,6 +291,7 @@ BeesRoots::crawl_roots() break; } + case SCAN_MODE_ONE: { // Scan each subvol one extent at a time (good for continuous forward progress) size_t batch_count = 0; @@ -303,6 +306,29 @@ BeesRoots::crawl_roots() break; } + case SCAN_MODE_TWO: { + // Scan oldest crawl first (requires maximum amount of temporary space) + vector> crawl_vector; + for (auto i : crawl_map_copy) { + crawl_vector.push_back(i.second); + } + sort(crawl_vector.begin(), crawl_vector.end(), [&](const shared_ptr &a, const shared_ptr &b) -> bool { + auto a_state = a->get_state(); + auto b_state = b->get_state(); + return tie(a_state.m_started, a_state.m_root) < tie(b_state.m_started, b_state.m_root); + }); + + size_t batch_count = 0; + for (auto i : crawl_vector) { + batch_count += crawl_batch(i); + if (batch_count) { + return; + } + } + + break; + } + case SCAN_MODE_COUNT: assert(false); break; } diff --git a/src/bees.h b/src/bees.h index 54f9636..c9f0f00 100644 --- a/src/bees.h +++ b/src/bees.h @@ -564,6 +564,7 @@ public: enum ScanMode { SCAN_MODE_ZERO, SCAN_MODE_ONE, + SCAN_MODE_TWO, SCAN_MODE_COUNT, // must be last };