diff --git a/rvgo/fast/radix.go b/rvgo/fast/radix.go index 7c05715..965b8f9 100644 --- a/rvgo/fast/radix.go +++ b/rvgo/fast/radix.go @@ -14,68 +14,86 @@ const ( ) type RadixNodeLevel1 struct { - Children [1 << BF1]*RadixNodeLevel2 - Hashes [1 << BF1][32]byte - HashCache [1 << BF1]bool + Children [1 << BF1]*RadixNodeLevel2 + Hashes [1 << BF1][32]byte + HashExists [(1 << BF1) / 64]uint64 + HashValid [(1 << BF1) / 64]uint64 } type RadixNodeLevel2 struct { - Children [1 << BF2]*RadixNodeLevel3 - Hashes [1 << BF2][32]byte - HashCache [1 << BF2]bool + Children [1 << BF2]*RadixNodeLevel3 + Hashes [1 << BF2][32]byte + HashExists [(1 << BF2) / 64]uint64 + HashValid [(1 << BF2) / 64]uint64 } type RadixNodeLevel3 struct { - Children [1 << BF3]*RadixNodeLevel4 - Hashes [1 << BF3][32]byte - HashCache [1 << BF3]bool + Children [1 << BF3]*RadixNodeLevel4 + Hashes [1 << BF3][32]byte + HashExists [(1 << BF3) / 64]uint64 + HashValid [(1 << BF3) / 64]uint64 } type RadixNodeLevel4 struct { - Children [1 << BF4]*RadixNodeLevel5 - Hashes [1 << BF4][32]byte - HashCache [1 << BF4]bool + Children [1 << BF4]*RadixNodeLevel5 + Hashes [1 << BF4][32]byte + HashExists [(1 << BF4) / 64]uint64 + HashValid [(1 << BF4) / 64]uint64 } type RadixNodeLevel5 struct { - Hashes [1 << BF5][32]byte - HashCache [1 << BF5]bool + Hashes [1 << BF5][32]byte + HashExists [(1 << BF5) / 64]uint64 + HashValid [(1 << BF5) / 64]uint64 } func (n *RadixNodeLevel1) invalidateHashes(branch uint64) { branch = (branch + 1< 0; index /= 2 { - n.HashCache[index] = false - n.Hashes[index] = [32]byte{} + for index := branch; index > 0; index >>= 1 { + hashIndex := index >> 6 + hashBit := index & 63 + n.HashExists[hashIndex] |= 1 << hashBit + n.HashValid[hashIndex] &= ^(1 << hashBit) } } func (n *RadixNodeLevel2) invalidateHashes(branch uint64) { branch = (branch + 1< 0; index /= 2 { - n.HashCache[index] = false - n.Hashes[index] = [32]byte{} + for index := branch; index > 0; index >>= 1 { + hashIndex := index >> 6 + hashBit := index & 63 + n.HashExists[hashIndex] |= 1 << hashBit + n.HashValid[hashIndex] &= ^(1 << hashBit) } } func (n *RadixNodeLevel3) invalidateHashes(branch uint64) { branch = (branch + 1< 0; index /= 2 { - n.HashCache[index] = false - n.Hashes[index] = [32]byte{} + for index := branch; index > 0; index >>= 1 { + hashIndex := index >> 6 + hashBit := index & 63 + n.HashExists[hashIndex] |= 1 << hashBit + n.HashValid[hashIndex] &= ^(1 << hashBit) + } } func (n *RadixNodeLevel4) invalidateHashes(branch uint64) { branch = (branch + 1< 0; index /= 2 { - n.HashCache[index] = false - n.Hashes[index] = [32]byte{} + for index := branch; index > 0; index >>= 1 { + hashIndex := index >> 6 + hashBit := index & 63 + n.HashExists[hashIndex] |= 1 << hashBit + n.HashValid[hashIndex] &= ^(1 << hashBit) + } } func (n *RadixNodeLevel5) invalidateHashes(branch uint64) { branch = (branch + 1< 0; index /= 2 { - n.HashCache[index] = false - n.Hashes[index] = [32]byte{} + for index := branch; index > 0; index >>= 1 { + hashIndex := index >> 6 + hashBit := index & 63 + n.HashExists[hashIndex] |= 1 << hashBit + n.HashValid[hashIndex] &= ^(1 << hashBit) + } } @@ -123,62 +141,63 @@ func (m *Memory) Invalidate(addr uint64) { } func (m *Memory) MerkleizeNodeLevel1(node *RadixNodeLevel1, addr, gindex uint64) [32]byte { - if gindex > 2*1<> 6 + hashBit := gindex & 63 + + if (node.HashExists[hashIndex] & (1 << hashBit)) != 0 { + if (node.HashValid[hashIndex] & (1 << hashBit)) != 0 { return node.Hashes[gindex] + } else { + left := m.MerkleizeNodeLevel1(node, addr, gindex<<1) + right := m.MerkleizeNodeLevel1(node, addr, (gindex<<1)|1) + + r := HashPair(left, right) + node.Hashes[gindex] = r + //node.HashExists[hashIndex] |= 1 << hashBit + node.HashValid[hashIndex] |= 1 << hashBit + return r } - } - - left := m.MerkleizeNodeLevel1(node, addr, gindex<<1) - right := m.MerkleizeNodeLevel1(node, addr, (gindex<<1)|1) - - r := HashPair(left, right) - node.Hashes[gindex] = r - node.HashCache[gindex] = true - return r - } else { - childIndex := gindex - 1< 2*1<> 6 + hashBit := gindex & 63 + + if (node.HashExists[hashIndex] & (1 << hashBit)) != 0 { + if (node.HashValid[hashIndex] & (1 << hashBit)) != 0 { return node.Hashes[gindex] + } else { + left := m.MerkleizeNodeLevel2(node, addr, gindex<<1) + right := m.MerkleizeNodeLevel2(node, addr, (gindex<<1)|1) + + r := HashPair(left, right) + node.Hashes[gindex] = r + node.HashValid[hashIndex] |= 1 << hashBit + return r } + } else { + return zeroHashes[64-5+1-(depth+BF1)] } - - left := m.MerkleizeNodeLevel2(node, addr, gindex<<1) - right := m.MerkleizeNodeLevel2(node, addr, (gindex<<1)|1) - - r := HashPair(left, right) - node.Hashes[gindex] = r - node.HashCache[gindex] = true - return r } childIndex := gindex - 1< 2*1<> 6 + hashBit := gindex & 63 + + if (node.HashExists[hashIndex] & (1 << hashBit)) != 0 { + if (node.HashValid[hashIndex] & (1 << hashBit)) != 0 { return node.Hashes[gindex] + } else { + left := m.MerkleizeNodeLevel3(node, addr, gindex<<1) + right := m.MerkleizeNodeLevel3(node, addr, (gindex<<1)|1) + r := HashPair(left, right) + node.Hashes[gindex] = r + node.HashValid[hashIndex] |= 1 << hashBit + return r } + } else { + return zeroHashes[64-5+1-(depth+BF1+BF2)] } - - left := m.MerkleizeNodeLevel3(node, addr, gindex<<1) - right := m.MerkleizeNodeLevel3(node, addr, (gindex<<1)|1) - r := HashPair(left, right) - node.Hashes[gindex] = r - node.HashCache[gindex] = true - return r } childIndex := gindex - 1< 2*1<> 6 + hashBit := gindex & 63 + if (node.HashExists[hashIndex] & (1 << hashBit)) != 0 { + if (node.HashValid[hashIndex] & (1 << hashBit)) != 0 { return node.Hashes[gindex] + } else { + left := m.MerkleizeNodeLevel4(node, addr, gindex<<1) + right := m.MerkleizeNodeLevel4(node, addr, (gindex<<1)|1) + + r := HashPair(left, right) + node.Hashes[gindex] = r + node.HashValid[hashIndex] |= 1 << hashBit + return r } + } else { + return zeroHashes[64-5+1-(depth+BF1+BF2+BF3)] } - left := m.MerkleizeNodeLevel4(node, addr, gindex<<1) - right := m.MerkleizeNodeLevel4(node, addr, (gindex<<1)|1) - - r := HashPair(left, right) - node.Hashes[gindex] = r - node.HashCache[gindex] = true - return r } childIndex := gindex - 1<> 6 + hashBit := gindex & 63 + + if (node.HashExists[hashIndex] & (1 << hashBit)) != 0 { + if (node.HashValid[hashIndex] & (1 << hashBit)) != 0 { return node.Hashes[gindex] + } else { + left := m.MerkleizeNodeLevel5(node, addr, gindex<<1) + right := m.MerkleizeNodeLevel5(node, addr, (gindex<<1)|1) + r := HashPair(left, right) + node.Hashes[gindex] = r + node.HashValid[hashIndex] |= 1 << hashBit + return r } + } else { + return zeroHashes[64-5+1-(depth+40)] } - - left := m.MerkleizeNodeLevel5(node, addr, gindex<<1) - right := m.MerkleizeNodeLevel5(node, addr, (gindex<<1)|1) - r := HashPair(left, right) - node.Hashes[gindex] = r - node.HashCache[gindex] = true - return r - } func (m *Memory) GenerateProof1(node *RadixNodeLevel1, addr, target uint64) [][32]byte { var proofs [][32]byte - for idx := target + 1< 1; idx /= 2 { + for idx := target + 1< 1; idx >>= 1 { sibling := idx ^ 1 proofs = append(proofs, m.MerkleizeNodeLevel1(node, addr, sibling)) } @@ -301,7 +322,7 @@ func (m *Memory) GenerateProof1(node *RadixNodeLevel1, addr, target uint64) [][3 func (m *Memory) GenerateProof2(node *RadixNodeLevel2, addr, target uint64) [][32]byte { var proofs [][32]byte - for idx := target + 1< 1; idx /= 2 { + for idx := target + 1< 1; idx >>= 1 { sibling := idx ^ 1 proofs = append(proofs, m.MerkleizeNodeLevel2(node, addr, sibling)) } @@ -312,7 +333,7 @@ func (m *Memory) GenerateProof2(node *RadixNodeLevel2, addr, target uint64) [][3 func (m *Memory) GenerateProof3(node *RadixNodeLevel3, addr, target uint64) [][32]byte { var proofs [][32]byte - for idx := target + 1< 1; idx /= 2 { + for idx := target + 1< 1; idx >>= 1 { sibling := idx ^ 1 proofs = append(proofs, m.MerkleizeNodeLevel3(node, addr, sibling)) } @@ -322,7 +343,7 @@ func (m *Memory) GenerateProof3(node *RadixNodeLevel3, addr, target uint64) [][3 func (m *Memory) GenerateProof4(node *RadixNodeLevel4, addr, target uint64) [][32]byte { var proofs [][32]byte - for idx := target + 1< 1; idx /= 2 { + for idx := target + 1< 1; idx >>= 1 { sibling := idx ^ 1 proofs = append(proofs, m.MerkleizeNodeLevel4(node, addr, sibling)) } @@ -333,7 +354,7 @@ func (m *Memory) GenerateProof4(node *RadixNodeLevel4, addr, target uint64) [][3 func (m *Memory) GenerateProof5(node *RadixNodeLevel5, addr, target uint64) [][32]byte { var proofs [][32]byte - for idx := target + 1< 1; idx /= 2 { + for idx := target + 1< 1; idx >>= 1 { sibling := idx ^ 1 proofs = append(proofs, m.MerkleizeNodeLevel5(node, addr, sibling)) } @@ -411,7 +432,7 @@ func (m *Memory) MerkleProof(addr uint64) [ProofLen * 32]byte { proofIndex = 0 if p, ok := m.pages[pageIndex]; ok { proofs[proofIndex] = p.MerkleizeSubtree(pageGindex) - for idx := pageGindex; idx > 1; idx /= 2 { + for idx := pageGindex; idx > 1; idx >>= 1 { sibling := idx ^ 1 proofIndex++ proofs[proofIndex] = p.MerkleizeSubtree(uint64(sibling))