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  }