Skip to content

Commit

Permalink
test loading times
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Dudley <[email protected]>
  • Loading branch information
siladu committed Oct 30, 2023
1 parent 326f722 commit 1e1f574
Showing 1 changed file with 21 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

Expand All @@ -41,33 +38,28 @@ public class TrieLogPruner {

private static final Logger LOG = LoggerFactory.getLogger(TrieLogPruner.class);

private static final int DEFAULT_PRUNING_LIMIT = 1000;
private final int pruningLimit;
private final int loadingLimit;
private final long loadingLimit;
private final BonsaiWorldStateKeyValueStorage rootWorldStateStorage;
private final Blockchain blockchain;
private final long numBlocksToRetain;
private static final Multimap<Long, byte[]> knownTrieLogKeysByDescendingBlockNumber =
TreeMultimap.create(Comparator.reverseOrder(), Comparator.comparingInt(Arrays::hashCode));

public TrieLogPruner(
final BonsaiWorldStateKeyValueStorage rootWorldStateStorage,
final Blockchain blockchain,
final long numBlocksToRetain) {
this(rootWorldStateStorage, blockchain, numBlocksToRetain, DEFAULT_PRUNING_LIMIT);
this(rootWorldStateStorage, blockchain, numBlocksToRetain, numBlocksToRetain);
}

@VisibleForTesting
TrieLogPruner(
final BonsaiWorldStateKeyValueStorage rootWorldStateStorage,
final Blockchain blockchain,
final long numBlocksToRetain,
final int pruningLimit) {
final long pruningLimit) {
this.rootWorldStateStorage = rootWorldStateStorage;
this.blockchain = blockchain;
this.numBlocksToRetain = numBlocksToRetain;
this.pruningLimit = pruningLimit;
this.loadingLimit = pruningLimit; // same as pruningLimit for now
this.loadingLimit = Math.max(numBlocksToRetain, pruningLimit); // same as pruningLimit for now
}

public void initialize() {
Expand All @@ -79,7 +71,7 @@ private void preloadCache() {
.setMessage("Loading first {} trie logs from database...")
.addArgument(loadingLimit)
.log();
final Stream<byte[]> trieLogs = rootWorldStateStorage.streamTrieLogs(loadingLimit);
final Stream<byte[]> trieLogs = rootWorldStateStorage.streamTrieLogs((int) loadingLimit);
final AtomicLong count = new AtomicLong();
trieLogs.forEach(
hashAsBytes -> {
Expand All @@ -94,6 +86,7 @@ private void preloadCache() {
}
});
LOG.atInfo().log("Loaded {} trie logs from database", count);
printCache();
}

void cacheForLaterPruning(final long blockNumber, final byte[] trieLogKey) {
Expand All @@ -106,42 +99,22 @@ void cacheForLaterPruning(final long blockNumber, final byte[] trieLogKey) {
}

void pruneFromCache() {
final long retainAboveThisBlock = blockchain.getChainHeadBlockNumber() - numBlocksToRetain;
LOG.atTrace()
.setMessage("(chainHeadNumber: {} - numBlocksToRetain: {}) = retainAboveThisBlock: {}")
.addArgument(blockchain.getChainHeadBlockNumber())
.addArgument(numBlocksToRetain)
.addArgument(retainAboveThisBlock)
.log();

final var pruneWindowEntries =
knownTrieLogKeysByDescendingBlockNumber.asMap().entrySet().stream()
.dropWhile((e) -> e.getKey() > retainAboveThisBlock)
.limit(pruningLimit);

final List<Long> blockNumbersToRemove = new ArrayList<>();

final AtomicInteger count = new AtomicInteger();
pruneWindowEntries.forEach(
(e) -> {
for (byte[] trieLogKey : e.getValue()) {
rootWorldStateStorage.pruneTrieLog(trieLogKey);
count.getAndIncrement();
}
blockNumbersToRemove.add(e.getKey());
});
printCache();
}

blockNumbersToRemove.forEach(knownTrieLogKeysByDescendingBlockNumber::removeAll);
LOG.atTrace()
.setMessage("pruned {} trie logs for blocks {}")
.addArgument(count)
.addArgument(blockNumbersToRemove)
.log();
LOG.atDebug()
.setMessage("pruned {} trie logs from {} blocks")
.addArgument(count)
.addArgument(blockNumbersToRemove.size())
.log();
void printCache() {
LOG.atInfo().log(
() ->
knownTrieLogKeysByDescendingBlockNumber.entries().stream()
.map(
entry -> {
final Bytes32 hashBytes = Bytes32.wrap(entry.getValue());
final Hash hash = Hash.wrap(hashBytes);
return String.format(
"\nblockNumber: %s, trieLogKey: %s", entry.getKey(), hash.toHexString());
})
.reduce((a, b) -> a + b)
.orElse("empty"));
}

public static TrieLogPruner noOpTrieLogPruner() {
Expand Down

0 comments on commit 1e1f574

Please sign in to comment.