-
Notifications
You must be signed in to change notification settings - Fork 175
/
vertex.go
88 lines (75 loc) · 2.06 KB
/
vertex.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package forest
import (
"errors"
"fmt"
"github.com/onflow/flow-go/model/flow"
)
type Vertex interface {
// VertexID returns the vertex's ID (in most cases its hash)
VertexID() flow.Identifier
// Level returns the vertex's level
Level() uint64
// Parent returns the parent's (level, ID)
Parent() (flow.Identifier, uint64)
}
// VertexToString returns a string representation of the vertex.
func VertexToString(v Vertex) string {
parentID, parentLevel := v.Parent()
return fmt.Sprintf("<id=%x level=%d parent_id=%d parent_level=%d>", v.VertexID(), v.Level(), parentID, parentLevel)
}
// VertexIterator is a stateful iterator for VertexList.
// Internally operates directly on the Vertex Containers
// It has one-element look ahead for skipping empty vertex containers.
type VertexIterator struct {
data VertexList
idx int
next Vertex
}
func (it *VertexIterator) preLoad() {
for it.idx < len(it.data) {
v := it.data[it.idx].vertex
it.idx++
if v != nil {
it.next = v
return
}
}
it.next = nil
}
// NextVertex returns the next Vertex or nil if there is none
func (it *VertexIterator) NextVertex() Vertex {
res := it.next
it.preLoad()
return res
}
// HasNext returns true if and only if there is a next Vertex
func (it *VertexIterator) HasNext() bool {
return it.next != nil
}
func newVertexIterator(vertexList VertexList) VertexIterator {
it := VertexIterator{
data: vertexList,
}
it.preLoad()
return it
}
// InvalidVertexError indicates that a proposed vertex is invalid for insertion to the forest.
type InvalidVertexError struct {
// Vertex is the invalid vertex
Vertex Vertex
// msg provides additional context
msg string
}
func (err InvalidVertexError) Error() string {
return fmt.Sprintf("invalid vertex %s: %s", VertexToString(err.Vertex), err.msg)
}
func IsInvalidVertexError(err error) bool {
var target InvalidVertexError
return errors.As(err, &target)
}
func NewInvalidVertexErrorf(vertex Vertex, msg string, args ...interface{}) InvalidVertexError {
return InvalidVertexError{
Vertex: vertex,
msg: fmt.Sprintf(msg, args...),
}
}