-
Notifications
You must be signed in to change notification settings - Fork 4
/
position.go
65 lines (54 loc) · 1.14 KB
/
position.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package merkle
import "fmt"
type Position struct {
Index uint64
Height uint
}
func (p Position) String() string {
return fmt.Sprintf("<h: %d i: %b>", p.Height, p.Index)
}
func (p Position) sibling() Position {
return Position{
Index: p.Index ^ 1,
Height: p.Height,
}
}
func (p Position) isAncestorOf(other Position) bool {
if p.Height < other.Height {
return false
}
return p.Index == (other.Index >> (p.Height - other.Height))
}
func (p Position) isRightSibling() bool {
return p.Index%2 == 1
}
func (p Position) parent() Position {
return Position{
Index: p.Index >> 1,
Height: p.Height + 1,
}
}
func (p Position) leftChild() Position {
return Position{
Index: p.Index << 1,
Height: p.Height - 1,
}
}
type positionsStack struct {
positions []Position
}
func (s *positionsStack) Push(v Position) {
s.positions = append(s.positions, v)
}
// Check the top of the stack for equality and pop the element if it's equal.
func (s *positionsStack) PopIfEqual(p Position) bool {
l := len(s.positions)
if l == 0 {
return false
}
if s.positions[l-1] == p {
s.positions = s.positions[:l-1]
return true
}
return false
}