public MerkleTree(Vector<Indexable> v) { nodeMap = new HashMap<Integer, MerkleTreeNode>(); this.store = v; int exp = 0; while ((int) Math.pow(2, exp) < store.size()) { exp++; } for (int i = store.size(); i < (int) Math.pow(2, exp); i++) { store.add(i, null); } Vector<MerkleTreeNode> hashes = new Vector<MerkleTreeNode>(); for (int i = 0; i < store.size(); i++) { if (store.get(i) != null) { MerkleTreeNode temp = new MerkleTreeNode(store.get(i).getBytes(), i); nodeMap.put(i, temp); hashes.add(temp); } else { MerkleTreeNode temp = new MerkleTreeNode(i); nodeMap.put(i, temp); hashes.add(temp); } } while (hashes.size() > 1) { Vector<MerkleTreeNode> temp = new Vector<MerkleTreeNode>(); for (int i = 0; i < hashes.size(); i += 2) { temp.add(MerkleTreeNode.combineDigestFactory(hashes.get(i), hashes.get(i + 1))); } hashes = temp; } root = hashes.get(0); }
private MerkleTreeNode update(MerkleTreeNode node) { MerkleTreeNode retNode = null; if (!node.dirty) { retNode = node; } else { retNode = MerkleTreeNode.combineDigestFactory(update(node.leftChild), update(node.rightChild)); } return retNode; }
public void updateLeafData(int index, Indexable b) { // Check to see if we need to grow tree if (index <= root.max) { // node already exists, simply update store.set(index, b); MerkleTreeNode node = nodeMap.get(index); MerkleTreeNode newNode = new MerkleTreeNode(b.getBytes(), index); newNode.parent = node.parent; if (newNode.parent.leftChild == node) { newNode.parent.leftChild = newNode; } else { newNode.parent.rightChild = newNode; } markChainDirty(newNode); } else { // node is beyond our scope, grow tree while (index > root.max) { Vector<Indexable> vec = new Vector<Indexable>(); int origSize = store.size(); for (int i = origSize; i < 2 * origSize; i++) { if (i == index) { vec.add(i - origSize, b); } else { vec.add(i - origSize, null); } } MerkleTree newtree = new MerkleTree(vec); root = MerkleTreeNode.combineDigestFactory(root, newtree.root); for (int i = origSize; i < 2 * origSize; i++) { MerkleTreeNode tempNode = newtree.nodeMap.get(i - origSize); tempNode.max += origSize; tempNode.min += origSize; nodeMap.put(i, tempNode); store.add(i, newtree.store.get(i - origSize)); } } } }