Skip to content

Commit a5b1865

Browse files
committed
build the tree iteratively
1 parent 9d03540 commit a5b1865

File tree

4 files changed

+26
-20
lines changed

4 files changed

+26
-20
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ Add *merkle-tree* as a dependency to your project.
99
* Gradle
1010

1111
```
12-
implementation 'ascelion.public:merkle-tree:1.0.2'
12+
implementation 'ascelion.public:merkle-tree:1.0.4'
1313
```
1414

1515
* Maven
1616
````
1717
<dependency>
1818
<groupId>ascelion.public</groupId>
1919
<artifactId>merkle-tree</artifactId>
20-
<version>1.0.2</version>
20+
<version>1.0.4</version>
2121
</dependency>
2222
````
2323

impl/src/main/java/ascelion/merkle/TreeBuilder.java

+20-14
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ int count() {
110110
}
111111

112112
// the hash function
113-
public final UnaryOperator<T> hashFn;
113+
private final UnaryOperator<T> hashFn;
114114
// the concatenation function
115115
private final BinaryOperator<T> concatFn;
116116
// supplier for the value of filler
@@ -266,6 +266,16 @@ public TreeRoot<T> build(Collection<TreeLeaf<T, ?>> leaves) {
266266
return root;
267267
}
268268

269+
/**
270+
* Calculates the hash of the input value using the hash operator of this builder.
271+
*
272+
* @param value the value to be hashed.
273+
* @return the hash value of the input value.
274+
*/
275+
public T hash(T value) {
276+
return this.hashFn.apply(value);
277+
}
278+
269279
/**
270280
* Checks whether a hash chain is valid using the operators of this builder instance.
271281
*
@@ -291,9 +301,9 @@ public boolean isValid(List<T> chain, int index, BiPredicate<T, T> eq) {
291301
final T next = chain.get(k);
292302

293303
if ((index & 1) == 0) {
294-
hash = this.hashFn.apply(this.concatFn.apply(hash, next));
304+
hash = hash(this.concatFn.apply(hash, next));
295305
} else {
296-
hash = this.hashFn.apply(this.concatFn.apply(next, hash));
306+
hash = hash(this.concatFn.apply(next, hash));
297307
}
298308

299309
index >>>= 1;
@@ -302,21 +312,17 @@ public boolean isValid(List<T> chain, int index, BiPredicate<T, T> eq) {
302312
return eq.test(hash, chain.get(chain.size() - 1));
303313
}
304314

305-
private Root<T> doBuild(TreeNode<T>[] leaves) {
315+
private Root<T> doBuild(TreeNode<T>[] nodes) {
306316
// expecting a power of two
307-
assert bitCount(leaves.length) == 1;
317+
assert bitCount(nodes.length) == 1;
308318

309-
if (leaves.length == 2) {
310-
return newNode(leaves[0], leaves[1], true);
311-
}
312-
313-
final TreeNode<T>[] parents = new TreeNode[leaves.length / 2];
314-
315-
for (int i = 0; i < leaves.length; i += 2) {
316-
parents[i / 2] = newNode(leaves[i], leaves[i + 1], false);
319+
for (int count = nodes.length; count > 2; count /= 2) {
320+
for (int i = 0; i < count; i += 2) {
321+
nodes[i / 2] = newNode(nodes[i], nodes[i + 1], false);
322+
}
317323
}
318324

319-
return doBuild(parents);
325+
return newNode(nodes[0], nodes[1], true);
320326
}
321327

322328
private <N extends TreeNode<T>> N newNode(TreeNode<T> left, TreeNode<T> right, boolean root) {

impl/src/main/java/ascelion/merkle/help/DataSlice.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static public TreeRoot<byte[]> buildTree(TreeBuilder<byte[]> bld, int size, Inpu
4343
byte[] data;
4444

4545
while ((data = readNBytes(ist, size)).length > 0) {
46-
bld.collect(new DataSlice(bld.hashFn.apply(data), data));
46+
bld.collect(new DataSlice(bld.hash(data), data));
4747
}
4848

4949
return bld.build();
@@ -68,7 +68,7 @@ static public TreeRoot<byte[]> buildTree(TreeBuilder<byte[]> bld, int size, Byte
6868

6969
buf.get(data, 0, data.length);
7070

71-
bld.collect(new DataSlice(bld.hashFn.apply(data), data));
71+
bld.collect(new DataSlice(bld.hash(data), data));
7272

7373
buf.clear();
7474
}

impl/src/main/java/overview.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ <h2 id="usage">Usage</h2>
1212
<li>Gradle</li>
1313
</ul>
1414

15-
<pre><code> implementation 'ascelion.public:merkle-tree:1.0.2'
15+
<pre><code> implementation 'ascelion.public:merkle-tree:1.0.4'
1616
</code></pre>
1717

1818
<ul>
@@ -22,7 +22,7 @@ <h2 id="usage">Usage</h2>
2222
<pre><code class="` language-`"> &lt;dependency&gt;
2323
&lt;groupId&gt;ascelion.public&lt;/groupId&gt;
2424
&lt;artifactId&gt;merkle-tree&lt;/artifactId&gt;
25-
&lt;version&gt;1.0.2&lt;/version&gt;
25+
&lt;version&gt;1.0.4&lt;/version&gt;
2626
&lt;/dependency&gt;
2727
</code></pre>
2828

0 commit comments

Comments
 (0)