use of com.jd.blockchain.ledger.merkletree.TreeOptions in project jdchain-core by blockchain-jd-com.
the class MerkleSortTreePerformanceTest method testPerformace1.
private void testPerformace1(int round, int count) {
System.out.printf("------------- Performance test: MerkleSortTree --------------\r\n", round, count);
TreeOptions options = TreeOptions.build().setDefaultHashAlgorithm(ClassicAlgorithm.SHA256.code());
Bytes prefix = Bytes.fromString(LedgerTestUtils.LEDGER_KEY_PREFIX);
MemoryKVStorage storage = new MemoryKVStorage();
Random rand = new Random();
byte[] value = new byte[128];
rand.nextBytes(value);
long startTs = System.currentTimeMillis();
MerkleSortTree<byte[]> merkleTree = MerkleSortTree.createBytesTree(options, prefix, storage);
long key;
for (int r = 0; r < round; r++) {
for (int i = 0; i < count; i++) {
key = ((long) r << 32) | i;
merkleTree.set(key, value);
}
merkleTree.commit();
}
long elapsedTs = System.currentTimeMillis() - startTs;
long totalCount = count * round;
double tps = round * 1000.0D / elapsedTs;
double kps = round * count * 1000.0D / elapsedTs;
System.out.printf("--[Performance]:: TotalKeys=%s; Round=%s; Count=%s; Times=%sms; TPS=%.2f; KPS=%.2f\r\n\r\n", totalCount, round, count, elapsedTs, tps, kps);
}
use of com.jd.blockchain.ledger.merkletree.TreeOptions in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreePerformanceTest method testPerformace1.
private static void testPerformace1(int round, int count) {
System.out.printf("------------- Performance test: MerkleHashSortTree --------------\r\n", round, count);
TreeOptions setting = TreeOptions.build().setDefaultHashAlgorithm(ClassicAlgorithm.SHA256.code());
Bytes prefix = Bytes.fromString(LedgerTestUtils.LEDGER_KEY_PREFIX);
MemoryKVStorage storage = new MemoryKVStorage();
Random rand = new Random();
byte[] value = new byte[128];
rand.nextBytes(value);
long startTs = System.currentTimeMillis();
MerkleHashSortTree merkleTree = new MerkleHashSortTree(setting, prefix, storage);
String key;
for (int r = 0; r < round; r++) {
for (int i = 0; i < count; i++) {
key = "KEY-" + r + "-" + i;
merkleTree.setData(key, 0, value);
}
merkleTree.commit();
}
long elapsedTs = System.currentTimeMillis() - startTs;
long totalCount = count * round;
double tps = round * 1000.0D / elapsedTs;
double kps = round * count * 1000.0D / elapsedTs;
System.out.printf("--[Performance]:: TotalKeys=%s; Round=%s; Count=%s; Times=%sms; TPS=%.2f; KPS=%.2f\r\n\r\n", totalCount, round, count, elapsedTs, tps, kps);
}
use of com.jd.blockchain.ledger.merkletree.TreeOptions in project jdchain-core by blockchain-jd-com.
the class MerkleSortTreeTest method testCommitAndCancel.
@Test
public void testCommitAndCancel() {
int count1 = 48;
byte[][] datas1 = generateRandomData(count1);
long[] ids1 = generateRandomIDs(count1);
Set<Long> excludingIds = createIdSet(ids1);
int count2 = 32;
byte[][] datas2 = generateRandomData(count2);
long[] ids2 = generateRandomIDs(count2, excludingIds, true);
TreeOptions options = createTreeOptions();
MemoryKVStorage storage = new MemoryKVStorage();
MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
long expectedMaxId1 = Arrays.stream(ids1).max().getAsLong();
assertEquals(0, mst.getCount());
assertNull(mst.getRootHash());
assertEquals(-1L, mst.getMaxId());
addDatas(ids1, datas1, mst);
// 未提交之前总数不会发生变化;
assertEquals(0, mst.getCount());
assertNull(mst.getRootHash());
// “最大编码”会实时更新;
assertNotNull(mst.getMaxId());
assertEquals(expectedMaxId1, mst.getMaxId());
// 迭代器不包含未提交的数据;预期迭代器为空;
SkippingIterator<MerkleValue<byte[]>> iter = mst.bytesIterator();
assertEquals(0, iter.getTotalCount());
// 提交之后才更新属性;
mst.commit();
assertEquals(count1, mst.getCount());
assertNotNull(mst.getRootHash());
assertNotNull(mst.getMaxId());
assertEquals(expectedMaxId1, mst.getMaxId());
assertDataEquals(mst, ids1, datas1);
// 预期提交后,迭代器反映出最新提交的数据;
Map<Long, byte[]> dataMap = new HashMap<Long, byte[]>();
mapIdValues(ids1, datas1, dataMap);
iter = mst.iterator();
long[] sortedIds1 = ids1;
Arrays.sort(sortedIds1);
assertIteratorSortedAndEquals(iter, count1, sortedIds1, dataMap);
// 测试写入数据后回滚操作是否符合预期;
long expectedMaxId2 = Arrays.stream(ids2).max().getAsLong();
expectedMaxId2 = Math.max(expectedMaxId1, expectedMaxId2);
HashDigest rootHash1 = mst.getRootHash();
// 写入数据,但并不提交;
addDatas(ids2, datas2, mst);
// 预期未提交之前,根哈希不会变化;
assertEquals(rootHash1, mst.getRootHash());
// 预期未提交之前,总数不会变化;
assertEquals(count1, mst.getCount());
// 预期“最大编码”属性是实时变化的;
assertEquals(expectedMaxId2, mst.getMaxId());
// 预期未提交之前,预期迭代器不会变化;
iter = mst.iterator();
assertIteratorSortedAndEquals(iter, count1, sortedIds1, dataMap);
// 回滚之后,预期所有的属性恢复到上一次提交的结果;
mst.cancel();
// 预期“根哈希”维持上次提交之后的结果;
assertEquals(rootHash1, mst.getRootHash());
// 预期“总数”维持上次提交之后的结果;
assertEquals(count1, mst.getCount());
// 预期“最大编码”属性恢复到上次提交之后的结果;
assertEquals(expectedMaxId1, mst.getMaxId());
// 预期迭代器不会变化,维持上次提交之后的结果;
iter = mst.iterator();
assertIteratorSortedAndEquals(iter, count1, sortedIds1, dataMap);
}
use of com.jd.blockchain.ledger.merkletree.TreeOptions in project jdchain-core by blockchain-jd-com.
the class MerkleSortTreeTest method testCounts.
@Test
public void testCounts() {
TreeOptions options = createTreeOptions();
MemoryKVStorage storage = new MemoryKVStorage();
MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
HashSet<Long> excludingIDs = new HashSet<Long>();
int count1 = (int) power(MerkleSortTree.DEFAULT_DEGREE, 2);
byte[][] datas1 = generateRandomData(count1);
long[] ids1 = generateRandomIDs(count1, excludingIDs, true);
addDatasAndCommit(ids1, datas1, mst);
int count2 = (int) power(MerkleSortTree.DEFAULT_DEGREE, 3);
byte[][] datas2 = generateRandomData(count2);
long[] ids2 = generateRandomIDs(count2, excludingIDs, true);
addDatasAndCommit(ids2, datas2, mst);
// 合并前两次产生的数据,验证默克尔树中是否已经写入相同的数据;
long[] ids = ArrayUtils.concat(ids1, ids2);
byte[][] datas = ArrayUtils.concat(datas1, datas2, byte[].class);
assertDataEquals(mst, ids, datas);
// 从存储中重新加载默克尔树,验证默克尔树中是否已经写入相同的数据;
HashDigest rootHash = mst.getRootHash();
mst = MerkleSortTree.createBytesTree(rootHash, options, DEFAULT_MKL_KEY_PREFIX, storage);
assertDataEquals(mst, ids, datas);
// 对重新加载的默克尔树持续写入,验证重复加载后持续写入的正确性;
int count3 = 1023;
byte[][] datas3 = generateRandomData(count3);
long[] ids3 = generateRandomIDs(count3, excludingIDs, true);
addDatasAndCommit(ids3, datas3, mst);
ids = ArrayUtils.concat(ids, ids3);
datas = ArrayUtils.concat(datas, datas3, byte[].class);
assertDataEquals(mst, ids, datas);
}
use of com.jd.blockchain.ledger.merkletree.TreeOptions in project jdchain-core by blockchain-jd-com.
the class MerkleSortTreeTest method testIdConfliction.
/**
* 测试插入同一个 ID 的冲突表现是否符合预期;
*/
@Test
public void testIdConfliction() {
TreeOptions options = createTreeOptions();
MemoryKVStorage storage = new MemoryKVStorage();
MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
// 验证空的迭代器;
SkippingIterator<MerkleValue<byte[]>> iter = mst.bytesIterator();
assertEquals(0, iter.getTotalCount());
assertEquals(-1, iter.getCursor());
assertFalse(iter.hasNext());
assertNull(iter.next());
// 加入数据,验证顺序数据插入的生成的迭代器;
int count = 10;
byte[][] datas = generateRandomData(count);
long[] ids = generateSeqenceIDs(0, count);
addDatasAndCommit(ids, datas, mst);
;
// 预期默认的 MerkleSortedTree 实现下,写入相同 id 的数据会引发移除;
MerkleTreeKeyExistException keyExistException = null;
try {
mst.set(8, datas[0]);
} catch (MerkleTreeKeyExistException e) {
keyExistException = e;
}
assertNotNull(keyExistException);
}
Aggregations