From 74c004a5e04299143199e2450718a2d142facb04 Mon Sep 17 00:00:00 2001 From: Alan Wang Date: Tue, 24 Mar 2026 16:55:39 -0700 Subject: [PATCH 1/3] method for CommandStores used by nodetool cleanup --- .../src/main/java/accord/local/CommandStores.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/accord-core/src/main/java/accord/local/CommandStores.java b/accord-core/src/main/java/accord/local/CommandStores.java index 9a6e2d29af..d69078b9ad 100644 --- a/accord-core/src/main/java/accord/local/CommandStores.java +++ b/accord-core/src/main/java/accord/local/CommandStores.java @@ -1121,4 +1121,13 @@ protected Snapshot current() { return current; } + + public Ranges commandStoresOwnedRanges() + { + Ranges currentRanges = Ranges.EMPTY; + for (ShardHolder shard : current.shards) + currentRanges = currentRanges.union(AbstractRanges.UnionMode.MERGE_ADJACENT, shard.ranges.all()); + + return currentRanges; + } } From ca673853df058b45a39dd004f282375d79d94f56 Mon Sep 17 00:00:00 2001 From: Alan Wang Date: Wed, 1 Apr 2026 00:59:10 -0700 Subject: [PATCH 2/3] changed method to return command store ranges modulo retired ranges --- .../src/main/java/accord/local/CommandStores.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/accord-core/src/main/java/accord/local/CommandStores.java b/accord-core/src/main/java/accord/local/CommandStores.java index d69078b9ad..e7de9f4539 100644 --- a/accord-core/src/main/java/accord/local/CommandStores.java +++ b/accord-core/src/main/java/accord/local/CommandStores.java @@ -1122,12 +1122,14 @@ protected Snapshot current() return current; } - public Ranges commandStoresOwnedRanges() + public AsyncResult> getInUseRanges() { - Ranges currentRanges = Ranges.EMPTY; - for (ShardHolder shard : current.shards) - currentRanges = currentRanges.union(AbstractRanges.UnionMode.MERGE_ADJACENT, shard.ranges.all()); + List> results = new ArrayList<>(); + Snapshot snapshot = current; + for (ShardHolder shard : snapshot.shards) + results.add(shard.store.submit((PreLoadContext.Empty) () -> "Get not retired ranges", + safeCommandStore -> shard.ranges().notRetired(safeCommandStore))); - return currentRanges; + return AsyncResults.allOf(results); } } From 28d5bca978c75b9c8f4e5ed745e7376395b16df5 Mon Sep 17 00:00:00 2001 From: Alan Wang Date: Mon, 18 May 2026 11:46:29 -0700 Subject: [PATCH 3/3] Mark unsafe to read retired ranges --- .../src/main/java/accord/local/CommandStore.java | 2 +- .../src/main/java/accord/local/CommandStores.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/accord-core/src/main/java/accord/local/CommandStore.java b/accord-core/src/main/java/accord/local/CommandStore.java index d321bc6794..e656989734 100644 --- a/accord-core/src/main/java/accord/local/CommandStore.java +++ b/accord-core/src/main/java/accord/local/CommandStore.java @@ -1219,7 +1219,7 @@ private static ImmutableSortedMap purgeAndInser return ImmutableSortedMap.copyOf(build); } - private static ImmutableSortedMap purgeHistory(NavigableMap in, Ranges remove) + protected static ImmutableSortedMap purgeHistory(NavigableMap in, Ranges remove) { return ImmutableSortedMap.copyOf(purgeHistoryIterator(in, remove)); } diff --git a/accord-core/src/main/java/accord/local/CommandStores.java b/accord-core/src/main/java/accord/local/CommandStores.java index e7de9f4539..ea68113029 100644 --- a/accord-core/src/main/java/accord/local/CommandStores.java +++ b/accord-core/src/main/java/accord/local/CommandStores.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.NavigableMap; import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -82,6 +83,7 @@ import org.agrona.collections.Int2IntHashMap; import org.agrona.collections.Int2ObjectHashMap; +import static accord.local.CommandStore.purgeHistory; import static accord.topology.EpochReady.done; import static accord.api.DataStore.FetchKind.Sync; import static accord.local.CommandStores.BootstrapRangeAction.BOOTSTRAP_NOT_NEEDED; @@ -1122,13 +1124,20 @@ protected Snapshot current() return current; } - public AsyncResult> getInUseRanges() + public AsyncResult> getInUseRangesAndMarkRetiredRangesUnsafeToRead() { List> results = new ArrayList<>(); Snapshot snapshot = current; for (ShardHolder shard : snapshot.shards) - results.add(shard.store.submit((PreLoadContext.Empty) () -> "Get not retired ranges", - safeCommandStore -> shard.ranges().notRetired(safeCommandStore))); + results.add(shard.store.submit((PreLoadContext.Empty) () -> "Get not retired ranges and mark retired ranges unsafe to read", + safeCommandStore -> { + Ranges notRetiredRanges = shard.ranges().notRetired(safeCommandStore); + Ranges retired = shard.ranges().all().without(notRetiredRanges); + NavigableMap safeToReadAt = safeCommandStore.safeToReadAt(); + if (safeToReadAt.values().stream().anyMatch(r -> r.intersects(retired))) + safeCommandStore.setSafeToRead(purgeHistory(safeToReadAt, retired)); + return notRetiredRanges; + })); return AsyncResults.allOf(results); }