Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
ExportCommand.class,
SortedExportCommand.class,
CompactionCommand.class,
ApplyBlocksCommand.class
ApplyBlocksCommand.class,
Validate2Command.class
},
description = "CLI tool with validation and introspection modes.")
public class StateOperatorCommand implements Runnable {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.statevalidation.poc.listener;

import com.hedera.statevalidation.poc.util.ValidationException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

// update logging format
public class LoggingValidationListener implements ValidationListener {

private static final Logger log = LogManager.getLogger(LoggingValidationListener.class);

@Override
public void onValidationStarted(String tag) {
log.debug(framedString(tag + " started"));
}

@Override
public void onValidationCompleted(String tag) {
log.debug(framedString(tag + " finished"));
}

@Override
public void onValidationFailed(ValidationException error) {
log.debug(framedString(error.getValidatorTag() + " failed"));
}

private String framedString(String stringToFrame) {
String frame = " ".repeat(stringToFrame.length() + 6);
return String.format("\n%s\n %s \n%s", frame, stringToFrame, frame);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.statevalidation.poc.listener;

import com.hedera.statevalidation.poc.util.ValidationException;

/**
* Listener for validation lifecycle events.
*
* <p><b>Thread Safety:</b> Implementations must be thread-safe as callbacks
* may be invoked concurrently from multiple processor threads.
*/
public interface ValidationListener {

default void onValidationStarted(String tag) {}

default void onValidationCompleted(String tag) {}

default void onValidationFailed(ValidationException error) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.statevalidation.poc.model;

import java.util.concurrent.atomic.AtomicLong;

/**
* Thread-safe container for collecting validation statistics across different data types.
*/
public final class DataStats {

private final StatGroup p2kv = new StatGroup();
private final StatGroup p2h = new StatGroup();
private final StatGroup k2p = new StatGroup();

public StatGroup getP2kv() {
return p2kv;
}

public StatGroup getP2h() {
return p2h;
}

public StatGroup getK2p() {
return k2p;
}

// --- Aggregations ---

public long getTotalSpaceSize() {
return p2h.getSpaceSize() + p2kv.getSpaceSize() + k2p.getSpaceSize();
}

public long getTotalItemCount() {
return p2h.getItemCount() + p2kv.getItemCount() + k2p.getItemCount();
}

public long getObsoleteSpaceSize() {
return p2h.getObsoleteSpaceSize() + p2kv.getObsoleteSpaceSize() + k2p.getObsoleteSpaceSize();
}

public long getObsoleteItemCount() {
return p2h.getObsoleteItemCount() + p2kv.getObsoleteItemCount() + k2p.getObsoleteItemCount();
}

public boolean hasErrorReads() {
return p2kv.hasErrors() || p2h.hasErrors() || k2p.hasErrors();
}

@Override
public String toString() {
return String.format(
"""
Total Data Stats:
Total items: %,d
Total space: %,d bytes
Obsolete items: %,d
Obsolete space: %,d bytes""",
getTotalItemCount(), getTotalSpaceSize(), getObsoleteItemCount(), getObsoleteSpaceSize());
}

/**
* Grouping of statistics for a single data type.
*/
public static final class StatGroup {
private final AtomicLong spaceSize = new AtomicLong();
private final AtomicLong itemCount = new AtomicLong();
private final AtomicLong obsoleteSpaceSize = new AtomicLong();
private final AtomicLong obsoleteItemCount = new AtomicLong();
private final AtomicLong parseErrorCount = new AtomicLong();
private final AtomicLong invalidLocationCount = new AtomicLong();

public void addSpaceSize(long bytes) {
spaceSize.addAndGet(bytes);
}

public void incrementItemCount() {
itemCount.incrementAndGet();
}

public void addObsoleteSpaceSize(long bytes) {
obsoleteSpaceSize.addAndGet(bytes);
}

public void incrementObsoleteItemCount() {
obsoleteItemCount.incrementAndGet();
}

public void incrementParseErrorCount() {
parseErrorCount.incrementAndGet();
}

public void incrementInvalidLocationCount() {
invalidLocationCount.incrementAndGet();
}

public long getSpaceSize() {
return spaceSize.get();
}

public long getItemCount() {
return itemCount.get();
}

public long getObsoleteSpaceSize() {
return obsoleteSpaceSize.get();
}

public long getObsoleteItemCount() {
return obsoleteItemCount.get();
}

public long getParseErrorCount() {
return parseErrorCount.get();
}

public long getInvalidLocationCount() {
return invalidLocationCount.get();
}

public boolean hasErrors() {
return parseErrorCount.get() > 0 || invalidLocationCount.get() > 0;
}

// Helper for the parent toString
public String toStringContent() {
return String.format(
"""
Total items: %,d
Total space: %,d bytes
Obsolete items: %,d
Obsolete space: %,d bytes
Parse errors: %,d
Invalid locations: %,d""",
getItemCount(),
getSpaceSize(),
getObsoleteItemCount(),
getObsoleteSpaceSize(),
getParseErrorCount(),
getInvalidLocationCount());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.statevalidation.poc.model;

import com.hedera.pbj.runtime.io.buffer.Bytes;

public record ItemData(Type type, Bytes bytes, long location) {

public enum Type {
P2KV,
P2H,
K2P,
TERMINATOR
}

public static ItemData poisonPill() {
return new ItemData(Type.TERMINATOR, Bytes.EMPTY, -1L);
}

public boolean isPoisonPill() {
return type == Type.TERMINATOR;
}
}
Loading
Loading