Skip to content

Commit

Permalink
feat(tools): add db compare
Browse files Browse the repository at this point in the history
  • Loading branch information
halibobo1205 committed Sep 9, 2024
1 parent 481141a commit 4156b73
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions plugins/src/main/java/org/tron/plugins/Db.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
DbQuery.class,
DbBlockScan.class,
DbCheckSum.class,
DbCompare.class,
},
commandListHeading = "%nCommands:%n%nThe most commonly used db commands are:%n"
)
Expand Down
135 changes: 135 additions & 0 deletions plugins/src/main/java/org/tron/plugins/DbCompare.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package org.tron.plugins;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.concurrent.Callable;
import lombok.extern.slf4j.Slf4j;
import org.rocksdb.RocksDBException;
import org.tron.plugins.utils.ByteArray;
import org.tron.plugins.utils.DBUtils;
import org.tron.plugins.utils.db.DBInterface;
import org.tron.plugins.utils.db.DBIterator;
import org.tron.plugins.utils.db.DbTool;
import picocli.CommandLine;

@Slf4j(topic = "compare")
@CommandLine.Command(name = "compare",
description = "compare data between two path for db.",
exitCodeListHeading = "Exit Codes:%n",
exitCodeList = {
"0:Successful",
"n:compare diff find,please check toolkit.log"})
public class DbCompare implements Callable<Integer> {

@CommandLine.Spec
static CommandLine.Model.CommandSpec spec;
@CommandLine.Parameters(index = "0",
description = " ful input path for base")
private File base;
@CommandLine.Parameters(index = "1",
description = "ful input path for compare")
private File compare;
@CommandLine.Option(names = {"-h", "--help"}, help = true, description = "display a help message")
private boolean help;

@Override
public Integer call() throws Exception {
if (help) {
spec.commandLine().usage(System.out);
return 0;
}
if (!base.exists()) {
logger.info(" {} does not exist.", base);
spec.commandLine().getErr().println(spec.commandLine().getColorScheme()
.errorText(String.format("%s does not exist.", base)));
return 404;
}
if (!compare.exists()) {
logger.info(" {} does not exist.", compare);
spec.commandLine().getErr().println(spec.commandLine().getColorScheme()
.errorText(String.format("%s does not exist.", compare)));
return 404;
}

Comparison service = new DbComparison(base.toPath(), compare.toPath());
return service.doCompare() ? 0 : 1;

}

interface Comparison {
boolean doCompare() throws Exception;
}

static class DbComparison implements Comparison {

private final Path basePath;
private final Path dstPath;
private final String name;

public DbComparison(Path srcDir, Path dstDir) {
this.basePath = srcDir.getParent();
this.dstPath = dstDir.getParent();
this.name = srcDir.getFileName().toString();
}

@Override
public boolean doCompare() throws Exception {
return compare();
}



private boolean compare() throws RocksDBException, IOException {
try (
DBInterface base = DbTool.getDB(this.basePath, this.name);
DBIterator baseIterator = base.iterator();
DBInterface dst = DbTool.getDB(this.dstPath, this.name);
DBIterator dstIterator = dst.iterator()) {

// check
logger.info("compare {} start", this.name);
spec.commandLine().getOut().println("compare " + this.name + " start");
baseIterator.seekToFirst();
dstIterator.seekToFirst();
for (; baseIterator.hasNext() && dstIterator.hasNext();
baseIterator.next(), dstIterator.next()) {
byte[] baseValue = baseIterator.getValue();
byte[] baseKey = baseIterator.getKey();
byte[] key = dstIterator.getKey();
byte[] value = dstIterator.getValue();
if (!Arrays.equals(baseKey, key) || !Arrays.equals(baseValue, value)) {
spec.commandLine().getOut().format("%s\t%s\t%s\t%s\t%s.", name,
ByteArray.toHexString(baseKey), ByteArray.toHexString(key),
ByteArray.toHexString(baseValue), ByteArray.toHexString(value)).println();
logger.info("{}\t{}\t{}\t{}\t{}", name,
ByteArray.toHexString(baseKey), ByteArray.toHexString(key),
ByteArray.toHexString(baseValue), ByteArray.toHexString(value));
}
}
for (; baseIterator.hasNext(); baseIterator.next()) {
byte[] key = baseIterator.getKey();
byte[] value = baseIterator.getValue();
String dbName = DBUtils.simpleDecode(key);
spec.commandLine().getOut().format("b\t%s\t%s\t%s.", dbName,
ByteArray.toHexString(key), ByteArray.toHexString(value)).println();
logger.info("b\t{}\t{}\t{}", dbName,
ByteArray.toHexString(key), ByteArray.toHexString(value));
}
for (; dstIterator.hasNext(); dstIterator.next()) {
byte[] key = dstIterator.getKey();
byte[] value = dstIterator.getValue();
String dbName = DBUtils.simpleDecode(key);
spec.commandLine().getOut().format("d\t%s\t%s\t%s.", dbName,
ByteArray.toHexString(key), ByteArray.toHexString(value)).println();
logger.info("d\t{}\t{}\t{}", dbName,
ByteArray.toHexString(key), ByteArray.toHexString(value));
}
}
logger.info("compare {} end", this.name);
spec.commandLine().getOut().println("compare " + this.name + " end");
return true;
}
}
}

0 comments on commit 4156b73

Please sign in to comment.