diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSink.java b/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSink.java index 388311ec9..4324b87e3 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSink.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSink.java @@ -1,7 +1,6 @@ package org.briarproject.bramble.api.io; import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.tree.TreeHash; import java.util.List; @@ -18,10 +17,4 @@ public interface BlockSink { */ void setPath(HashingId h, int blockNumber, List path) throws DbException; - - /** - * Sets the permanent ID of the message with the given temporary ID. The - * temporary ID is no longer valid once this method has been called. - */ - void setMessageId(HashingId h, MessageId m) throws DbException; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/LeafNode.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/LeafNode.java index 68d81d1a2..f7ee5b3e4 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/LeafNode.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/LeafNode.java @@ -1,8 +1,21 @@ package org.briarproject.bramble.api.sync.tree; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +@NotNullByDefault public class LeafNode extends TreeNode { public LeafNode(TreeHash hash, int blockNumber) { super(hash, 0, blockNumber, blockNumber); } + + @Override + public TreeNode getLeftChild() { + throw new UnsupportedOperationException(); + } + + @Override + public TreeNode getRightChild() { + throw new UnsupportedOperationException(); + } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/ParentNode.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/ParentNode.java index 8d529bb9e..6e2973b26 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/ParentNode.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/ParentNode.java @@ -1,9 +1,26 @@ package org.briarproject.bramble.api.sync.tree; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +@NotNullByDefault public class ParentNode extends TreeNode { + private final TreeNode left, right; + public ParentNode(TreeHash hash, TreeNode left, TreeNode right) { super(hash, Math.max(left.getHeight(), right.getHeight()) + 1, left.getFirstBlockNumber(), right.getLastBlockNumber()); + this.left = left; + this.right = right; + } + + @Override + public TreeNode getLeftChild() { + return left; + } + + @Override + public TreeNode getRightChild() { + return right; } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/StreamHasher.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/StreamHasher.java index 9e72cb4ff..4b9212238 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/StreamHasher.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/StreamHasher.java @@ -4,8 +4,6 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.io.BlockSink; import org.briarproject.bramble.api.io.HashingId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.MessageId; import java.io.IOException; import java.io.InputStream; @@ -16,8 +14,8 @@ public interface StreamHasher { /** * Reads the given input stream, divides the data into blocks, stores * the blocks and the resulting hash tree using the given block sink and - * temporary ID, and returns the message ID. + * temporary ID, and returns the hash tree. */ - MessageId hash(InputStream in, BlockSink sink, HashingId h, GroupId g, - long timestamp) throws IOException, DbException; + TreeNode hash(InputStream in, BlockSink sink, HashingId h) + throws IOException, DbException; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/TreeNode.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/TreeNode.java index d5104f645..8d6a9f4d6 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/TreeNode.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/tree/TreeNode.java @@ -1,6 +1,9 @@ package org.briarproject.bramble.api.sync.tree; -public class TreeNode { +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +@NotNullByDefault +public abstract class TreeNode { private final TreeHash hash; private final int height, firstBlockNumber, lastBlockNumber; @@ -28,4 +31,8 @@ public class TreeNode { public int getLastBlockNumber() { return lastBlockNumber; } + + public abstract TreeNode getLeftChild(); + + public abstract TreeNode getRightChild(); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/tree/StreamHasherImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/tree/StreamHasherImpl.java index d30545bee..6a6aa2f94 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/sync/tree/StreamHasherImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/tree/StreamHasherImpl.java @@ -4,16 +4,14 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.io.BlockSink; import org.briarproject.bramble.api.io.HashingId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.MessageFactory; -import org.briarproject.bramble.api.sync.MessageId; -import org.briarproject.bramble.api.sync.tree.LeafNode; import org.briarproject.bramble.api.sync.tree.StreamHasher; import org.briarproject.bramble.api.sync.tree.TreeHash; import org.briarproject.bramble.api.sync.tree.TreeHasher; +import org.briarproject.bramble.api.sync.tree.TreeNode; import java.io.IOException; import java.io.InputStream; +import java.util.LinkedList; import javax.annotation.concurrent.Immutable; import javax.inject.Inject; @@ -27,21 +25,19 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MAX_BLOCK_LENGTH; class StreamHasherImpl implements StreamHasher { private final TreeHasher treeHasher; - private final MessageFactory messageFactory; private final Provider hashTreeProvider; @Inject - StreamHasherImpl(TreeHasher treeHasher, MessageFactory messageFactory, + StreamHasherImpl(TreeHasher treeHasher, Provider hashTreeProvider) { this.treeHasher = treeHasher; - this.messageFactory = messageFactory; this.hashTreeProvider = hashTreeProvider; } @Override - public MessageId hash(InputStream in, BlockSink sink, HashingId h, - GroupId g, long timestamp) throws IOException, DbException { - HashTree hashTree = hashTreeProvider.get(); + public TreeNode hash(InputStream in, BlockSink sink, HashingId h) + throws IOException, DbException { + HashTree tree = hashTreeProvider.get(); byte[] block = new byte[MAX_BLOCK_LENGTH]; int read; for (int blockNumber = 0; (read = read(in, block)) > 0; blockNumber++) { @@ -49,14 +45,11 @@ class StreamHasherImpl implements StreamHasher { if (read == block.length) data = block; else data = copyOfRange(block, 0, read); sink.putBlock(h, blockNumber, data); - LeafNode leaf = treeHasher.hashBlock(blockNumber, data); - hashTree.addLeaf(leaf); + tree.addLeaf(treeHasher.hashBlock(blockNumber, data)); } - // TODO: Set paths on block sink - TreeHash rootHash = hashTree.getRoot().getHash(); - MessageId m = messageFactory.getMessageId(g, timestamp, rootHash); - sink.setMessageId(h, m); - return m; + TreeNode root = tree.getRoot(); + setPaths(sink, h, root, new LinkedList<>()); + return root; } /** @@ -73,4 +66,20 @@ class StreamHasherImpl implements StreamHasher { } return offset; } + + private void setPaths(BlockSink sink, HashingId h, TreeNode node, + LinkedList path) throws DbException { + if (node.getHeight() == 0) { + // We've reached a leaf - store the path + sink.setPath(h, node.getFirstBlockNumber(), path); + } else { + // Add the right child's hash to the path and traverse the left + path.addFirst(node.getRightChild().getHash()); + setPaths(sink, h, node.getLeftChild(), path); + // Add the left child's hash to the path and traverse the right + path.removeFirst(); + path.addFirst(node.getLeftChild().getHash()); + setPaths(sink, h, node.getRightChild(), path); + } + } }