github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/forest/vertex.go (about) 1 package forest 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/onflow/flow-go/model/flow" 8 ) 9 10 type Vertex interface { 11 // VertexID returns the vertex's ID (in most cases its hash) 12 VertexID() flow.Identifier 13 // Level returns the vertex's level 14 Level() uint64 15 // Parent returns the parent's (level, ID) 16 Parent() (flow.Identifier, uint64) 17 } 18 19 // VertexToString returns a string representation of the vertex. 20 func VertexToString(v Vertex) string { 21 parentID, parentLevel := v.Parent() 22 return fmt.Sprintf("<id=%x level=%d parent_id=%d parent_level=%d>", v.VertexID(), v.Level(), parentID, parentLevel) 23 } 24 25 // VertexIterator is a stateful iterator for VertexList. 26 // Internally operates directly on the Vertex Containers 27 // It has one-element look ahead for skipping empty vertex containers. 28 type VertexIterator struct { 29 data VertexList 30 idx int 31 next Vertex 32 } 33 34 func (it *VertexIterator) preLoad() { 35 for it.idx < len(it.data) { 36 v := it.data[it.idx].vertex 37 it.idx++ 38 if v != nil { 39 it.next = v 40 return 41 } 42 } 43 it.next = nil 44 } 45 46 // NextVertex returns the next Vertex or nil if there is none 47 func (it *VertexIterator) NextVertex() Vertex { 48 res := it.next 49 it.preLoad() 50 return res 51 } 52 53 // HasNext returns true if and only if there is a next Vertex 54 func (it *VertexIterator) HasNext() bool { 55 return it.next != nil 56 } 57 58 func newVertexIterator(vertexList VertexList) VertexIterator { 59 it := VertexIterator{ 60 data: vertexList, 61 } 62 it.preLoad() 63 return it 64 } 65 66 // InvalidVertexError indicates that a proposed vertex is invalid for insertion to the forest. 67 type InvalidVertexError struct { 68 // Vertex is the invalid vertex 69 Vertex Vertex 70 // msg provides additional context 71 msg string 72 } 73 74 func (err InvalidVertexError) Error() string { 75 return fmt.Sprintf("invalid vertex %s: %s", VertexToString(err.Vertex), err.msg) 76 } 77 78 func IsInvalidVertexError(err error) bool { 79 var target InvalidVertexError 80 return errors.As(err, &target) 81 } 82 83 func NewInvalidVertexErrorf(vertex Vertex, msg string, args ...interface{}) InvalidVertexError { 84 return InvalidVertexError{ 85 Vertex: vertex, 86 msg: fmt.Sprintf(msg, args...), 87 } 88 }