diff options
| author | Thibaut Horel <thibaut.horel@gmail.com> | 2016-05-04 23:10:15 -0400 |
|---|---|---|
| committer | Thibaut Horel <thibaut.horel@gmail.com> | 2016-05-04 23:10:15 -0400 |
| commit | 27ff4c4aa4988c65caf6093b9dcc3c00f6c00743 (patch) | |
| tree | b22a3d12bbb32f1df4a757591304d576c00bf318 /merkle.go | |
| parent | 5185b1ea87c04fcfe6d96797ac7a0d363bf1c4de (diff) | |
| download | pos-27ff4c4aa4988c65caf6093b9dcc3c00f6c00743.tar.gz | |
Add batch proof extraction: sorting helps more than batching, will have to investigate page faults
Diffstat (limited to 'merkle.go')
| -rw-r--r-- | merkle.go | 39 |
1 files changed, 38 insertions, 1 deletions
@@ -85,7 +85,7 @@ func (m *BFSMerkle) Build() []byte { func (m *BFSMerkle) Proof(id int64) [][]byte { proof := make([][]byte, m.height) proof[0] = make([]byte, hashSize) - m.Read(proof[0], id) + m.ReadAt(proof[0], id*hashSize) for i := 1; id > 0; i++ { proof[i] = make([]byte, hashSize) if id&1 == 0 { @@ -98,6 +98,43 @@ func (m *BFSMerkle) Proof(id int64) [][]byte { return proof } +func (m *BFSMerkle) Proofs(ids []int64) [][][]byte { + proofs := make([][][]byte, len(ids)) + for i, id := range ids { + proofs[i] = m.Proof(id) + } + return proofs +} + +func (m *BFSMerkle) BatchProofs(ids []int64) [][][]byte { + proofs := make([][][]byte, len(ids)) + tids := make([]int64, len(ids)) + copy(tids, ids) + var id int64 + + // pre-allocating proofs + first step + for i := range proofs { + proofs[i] = make([][]byte, m.height) + proofs[i][0] = make([]byte, hashSize) + m.ReadAt(proofs[i][0], tids[i]*hashSize) + } + + // constructing proofs level by level + for height := int64(1); height < m.height; height++ { + for i := range proofs { + proofs[i][height] = make([]byte, hashSize) + id = tids[i] + if id&1 == 0 { + m.ReadAt(proofs[i][height], (id-1)*hashSize) + } else { + m.ReadAt(proofs[i][height], (id+1)*hashSize) + } + tids[i] = (id - 1) >> 1 + } + } + return proofs +} + // nodes are stored in depth-first post order type PostMerkle struct { height int64 |
