diff --git oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tooling/ConsistencyChecker.java oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tooling/ConsistencyChecker.java index 8d02e7d..81dea25 100644 --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tooling/ConsistencyChecker.java +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tooling/ConsistencyChecker.java @@ -82,6 +82,10 @@ public class ConsistencyChecker implements Closeable { private final ReadOnlyFileStore store; private final long debugInterval; + + private int nodeCount; + + private int propertyCount; /** * Run a consistency check. @@ -108,7 +112,8 @@ public class ConsistencyChecker implements Closeable { JournalReader journal = new JournalReader(new File(directory, journalFileName)); ConsistencyChecker checker = new ConsistencyChecker(directory, debugInterval, ioStatistics) ) { - Set badPaths = newHashSet(); + Set paths = newHashSet(); + paths.add("/"); String latestGoodRevision = null; int revisionCount = 0; @@ -117,18 +122,15 @@ public class ConsistencyChecker implements Closeable { try { print("Checking revision {}", revision); revisionCount++; - String badPath = checker.check(revision, badPaths, binLen); - if (badPath == null && fullTraversal) { - badPath = checker.traverse(revision, binLen); - } + String badPath = checker.check(revision, paths, binLen, fullTraversal); if (badPath == null) { print("Found latest good revision {}", revision); print("Searched through {} revisions", revisionCount); latestGoodRevision = revision; } else { - badPaths.add(badPath); - print("Broken revision {}", revision); + print("Broken revision {} at path {}", revision, badPath); } + print("Traversed {} nodes and {} properties", checker.nodeCount, checker.propertyCount); } catch (IllegalArgumentException e) { print("Skipping invalid record id {}", revision); } @@ -173,15 +175,20 @@ public class ConsistencyChecker implements Closeable { * Check whether the nodes and all its properties of all given * {@code paths} are consistent at the given {@code revision}. * - * @param revision revision to check - * @param paths paths to check - * @param binLen number of bytes to read from binary properties. -1 for all. + * @param revision revision to check + * @param paths paths to check + * @param binLen number of bytes to read from binary properties. -1 for all. + * @param fullTraversal whether a full traversal of repository will be employed * @return Path of the first inconsistency detected or {@code null} if none. */ - public String check(String revision, Set paths, long binLen) { + public String check(String revision, Set paths, long binLen, boolean fullTraversal) { store.setRevision(revision); + nodeCount = 0; + propertyCount = 0; + NodeState root = SegmentNodeStoreBuilders.builder(store).build().getRoot(); + for (String path : paths) { - String err = checkPath(path, binLen); + String err = checkPath(root, path, binLen, fullTraversal); if (err != null) { return err; } @@ -189,17 +196,16 @@ public class ConsistencyChecker implements Closeable { return null; } - private String checkPath(String path, long binLen) { + private String checkPath(NodeState root, String path, long binLen, boolean fullTraversal) { try { print("Checking {}", path); - NodeState root = SegmentNodeStoreBuilders.builder(store).build().getRoot(); String parentPath = getParentPath(path); String name = getName(path); NodeState parent = getNode(root, parentPath); if (!denotesRoot(path) && parent.hasChildNode(name)) { - return traverse(parent.getChildNode(name), path, false, binLen); + return traverse(parent.getChildNode(name), path, fullTraversal, binLen); } else { - return traverse(parent, parentPath, false, binLen); + return traverse(parent, parentPath, fullTraversal, binLen); } } catch (RuntimeException e) { print("Error while checking {}: {}", path, e.getMessage()); @@ -207,29 +213,6 @@ public class ConsistencyChecker implements Closeable { } } - private int nodeCount; - private int propertyCount; - - /** - * Travers the given {@code revision} - * @param revision revision to travers - * @param binLen number of bytes to read from binary properties. -1 for all. - */ - public String traverse(String revision, long binLen) { - try { - store.setRevision(revision); - nodeCount = 0; - propertyCount = 0; - String result = traverse(SegmentNodeStoreBuilders.builder(store).build() - .getRoot(), "/", true, binLen); - print("Traversed {} nodes and {} properties", nodeCount, propertyCount); - return result; - } catch (RuntimeException e) { - print("Error while traversing {}", revision, e.getMessage()); - return "/"; - } - } - private String traverse(NodeState node, String path, boolean deep, long binLen) { try { debug("Traversing {}", path);