Skip to content

Commit

Permalink
improved BinTree and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
h6x0r committed Aug 19, 2024
1 parent 4954fba commit 7872dca
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 55 deletions.
55 changes: 21 additions & 34 deletions cell/src/main/java/org/ton/java/cell/BinTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.util.Deque;
import java.util.List;

import static java.util.Objects.isNull;

public class BinTree {
ShardDescr value;
BinTree left;
Expand Down Expand Up @@ -37,65 +39,50 @@ private static BinTree buildTree(Deque<ShardDescr> cells) {
}

public Cell toCell() {
return toCellHelper(this);
}

private Cell toCellHelper(BinTree node) {
if (node == null || node.value == null) {
if (this.value == null && this.left == null && this.right == null) {
return CellBuilder.beginCell().endCell();
}

CellBuilder cb = CellBuilder.beginCell();
cb.storeBit(true);
cb.storeRef(CellBuilder.beginCell()
.storeBit(false)
.storeCell(node.value.toCell())
.endCell());

if (node.left != null || node.right != null) {
cb.storeRef(addToBinTree(node.left, node.right));
}

return cb.endCell();
List<ShardDescr> listView = this.toList();
return addToBinTree(listView, null);
}

private Cell addToBinTree(BinTree left, BinTree right) {
if (right != null) {
private static Cell addToBinTree(List<ShardDescr> cells, Cell left) {
if (!cells.isEmpty()) {
CellBuilder cb = CellBuilder.beginCell();
cb.storeBit(true);
cb.storeRef(CellBuilder.beginCell()
.storeBit(false)
.storeCell(left != null ? toCellHelper(left) : CellBuilder.beginCell().endCell())
.storeCell(isNull(left) ? cells.remove(0).toCell() : left)
.endCell());
cb.storeRef(toCellHelper(right));
if (!cells.isEmpty()) {
cb.storeRef(addToBinTree(cells, cells.remove(0).toCell()));
}
return cb.endCell();
} else {
CellBuilder cb = CellBuilder.beginCell();
cb.storeCell(left != null ? toCellHelper(left) : CellBuilder.beginCell().endCell());
cb.storeBit(false);
cb.storeCell(left);
return cb.endCell();
}
}

public static BinTree deserialize(CellSlice cs) {
if (cs.bits.getLength() == 0 || cs.isExotic()) {
if (cs.isExotic() || cs.bits.getLength() == 0) {
return null;
}

if (cs.loadBit()) {
BinTree left = null;
BinTree right = null;

BinTree root = new BinTree();
if (cs.loadBit() || !cs.refs.isEmpty()) {
if (!cs.refs.isEmpty()) {
left = deserialize(CellSlice.beginParse(cs.loadRef()));
root.left = deserialize(CellSlice.beginParse(cs.loadRef()));
}
if (!cs.refs.isEmpty()) {
right = deserialize(CellSlice.beginParse(cs.loadRef()));
root.right = deserialize(CellSlice.beginParse(cs.loadRef()));
}

return new BinTree(null, left, right);
return root;
} else {
ShardDescr value = ShardDescr.deserialize(cs);
return new BinTree(value);
root.value = ShardDescr.deserialize(cs);
return root;
}
}

Expand Down
84 changes: 63 additions & 21 deletions cell/src/test/java/org/ton/java/hashmaps/TestBinTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ private ShardDescr createShardDescr(int seqno) {
.build();
}

private void printLog(Object o) {
log.info("ShardDescr: {}", o);
}

@Test
public void testBinTreeDeque() {
ShardDescr shardDescr1 = createShardDescr(1);
Expand All @@ -75,7 +79,7 @@ public void testBinTreeDeque() {
List<ShardDescr> bt = BinTree.deserialize(CellSlice.beginParse(c)).toList();

for (ShardDescr cc : bt) {
log.info("ShardDescr: {}", cc);
printLog(cc);
}

assertThat(bt.size()).isEqualTo(5);
Expand All @@ -88,35 +92,63 @@ public void testBinTree() {
ShardDescr shardDescr3 = createShardDescr(3);
ShardDescr shardDescr4 = createShardDescr(4);
ShardDescr shardDescr5 = createShardDescr(5);
ShardDescr shardDescr6 = createShardDescr(6);
ShardDescr shardDescr7 = createShardDescr(7);
ShardDescr shardDescr8 = createShardDescr(8);
ShardDescr shardDescr9 = createShardDescr(9);
ShardDescr shardDescr10 = createShardDescr(10);

BinTree tree10 = new BinTree(shardDescr10);
BinTree tree9 = new BinTree(shardDescr9, tree10, null);
BinTree tree8 = new BinTree(shardDescr8);
BinTree tree7 = new BinTree(shardDescr7, tree8, tree9);
BinTree tree6 = new BinTree(shardDescr6);
BinTree tree5 = new BinTree(shardDescr5, tree6, tree7);
BinTree tree4 = new BinTree(shardDescr4, null, tree5);
BinTree tree3 = new BinTree(shardDescr3);
BinTree tree2 = new BinTree(shardDescr2, tree3, null);

BinTree root = new BinTree(shardDescr1, tree2, tree4);

Deque<ShardDescr> cells = new ArrayDeque<>();
cells.add(shardDescr1);
cells.add(shardDescr2);
cells.add(shardDescr3);
cells.add(shardDescr4);
cells.add(shardDescr5);
cells.add(shardDescr6);
cells.add(shardDescr7);
cells.add(shardDescr8);
cells.add(shardDescr9);
cells.add(shardDescr10);

Cell c = BinTree.fromDeque(cells).toCell();

log.info("ShardDescr: {}", c);
Cell cRootFromDeque = BinTree.fromDeque(cells).toCell();
Cell cRoot = root.toCell();

BinTree tree = BinTree.deserialize(CellSlice.beginParse(c));
BinTree tree = BinTree.deserialize(CellSlice.beginParse(cRootFromDeque));
BinTree rootFromCell = BinTree.deserialize(CellSlice.beginParse(cRoot));
assertThat(tree).isNotNull();
assertThat(root).isNotNull();

List<ShardDescr> deserializedTree = tree.toList();
for (ShardDescr cc : tree.toList()) {
log.info("ShardDescr: {}", cc);
List<ShardDescr> deserializedRoot = rootFromCell.toList();
for (int i = 0; i < 10; i++) {
assertThat(deserializedRoot.get(i).getSeqNo()).isEqualTo(deserializedTree.get(i).getSeqNo());
printLog(deserializedTree.get(i));
}

assertThat(deserializedTree.size()).isEqualTo(5);
assertThat(deserializedTree.size()).isEqualTo(10);
assertThat(deserializedRoot.size()).isEqualTo(10);
}

@Test
public void testBinTreeEmpty() {
Deque<ShardDescr> cells = new ArrayDeque<>();
BinTree tree = BinTree.fromDeque(cells);
BinTree root = new BinTree();

assertThat(tree).isEqualTo(null);
assertThat(tree).isNull();
assertThat(root).isNotNull();
}


Expand All @@ -127,15 +159,20 @@ public void testBinTreeOne() {
Deque<ShardDescr> cells = new ArrayDeque<>();
cells.add(shardDescr1);

Cell c = BinTree.fromDeque(cells).toCell();
BinTree root = new BinTree(shardDescr1);

List<ShardDescr> bt = BinTree.deserialize(CellSlice.beginParse(c)).toList();
Cell cTree = BinTree.fromDeque(cells).toCell();
Cell cRoot = root.toCell();

for (ShardDescr cc : bt) {
log.info("ShardDescr: {}", cc);
List<ShardDescr> deserializedTree = BinTree.deserialize(CellSlice.beginParse(cTree)).toList();
List<ShardDescr> deserializedRoot = BinTree.deserialize(CellSlice.beginParse(cRoot)).toList();

for (ShardDescr cc : deserializedTree) {
printLog(cc);
}

assertThat(bt.size()).isEqualTo(1);
assertThat(deserializedTree.size()).isEqualTo(1);
assertThat(deserializedRoot.size()).isEqualTo(1);
}

@Test
Expand All @@ -147,15 +184,20 @@ public void testBinTreeTwo() {
cells.add(shardDescr1);
cells.add(shardDescr2);

Cell c = BinTree.fromDeque(cells).toCell();
BinTree root = new BinTree(shardDescr1, new BinTree(shardDescr1), null);

List<ShardDescr> bt = BinTree.deserialize(CellSlice.beginParse(c)).toList();
Cell cTree = BinTree.fromDeque(cells).toCell();
Cell cRoot = root.toCell();

for (ShardDescr cc : bt) {
log.info("ShardDescr: {}", cc);
List<ShardDescr> deserializedTree = BinTree.deserialize(CellSlice.beginParse(cTree)).toList();
List<ShardDescr> deserializedRoot = BinTree.deserialize(CellSlice.beginParse(cRoot)).toList();

for (ShardDescr cc : deserializedTree) {
printLog(cc);
}

assertThat(bt.size()).isEqualTo(2);
assertThat(deserializedTree.size()).isEqualTo(2);
assertThat(deserializedRoot.size()).isEqualTo(2);
}

@Test
Expand All @@ -171,12 +213,12 @@ public void testBinTreeThree() {

Cell c = BinTree.fromDeque(cells).toCell();

log.info("ShardDescr: {}", c);
printLog(c);

List<ShardDescr> bt = BinTree.deserialize(CellSlice.beginParse(c)).toList();

for (ShardDescr cc : bt) {
log.info("ShardDescr: {}", cc);
printLog(cc);
}

assertThat(bt.size()).isEqualTo(3);
Expand Down

0 comments on commit 7872dca

Please sign in to comment.