code.vegaprotocol.io/vega@v0.79.0/datanode/networkhistory/segment/contiguous_history.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package segment
    17  
    18  type blockSpanner interface {
    19  	GetFromHeight() int64
    20  	GetToHeight() int64
    21  }
    22  
    23  // ContiguousHistory is a list of ordered contiguous segments.
    24  type ContiguousHistory[T blockSpanner] struct {
    25  	HeightFrom int64
    26  	HeightTo   int64
    27  	Segments   []T
    28  }
    29  
    30  // NewChunkFromSegment returns a chunk containing a single segment.
    31  func NewChunkFromSegment[T blockSpanner](segment T) ContiguousHistory[T] {
    32  	return ContiguousHistory[T]{
    33  		HeightFrom: segment.GetFromHeight(),
    34  		HeightTo:   segment.GetToHeight(),
    35  		Segments:   []T{segment},
    36  	}
    37  }
    38  
    39  // Add attempts to insert new segment to the chunk, either at the beginning or at the end.
    40  // It returns true if the segment was added, false if the new segment doesn't lead or follow our current range.
    41  func (c *ContiguousHistory[T]) Add(new T) bool {
    42  	if len(c.Segments) == 0 {
    43  		c.Segments = []T{new}
    44  		c.HeightFrom = new.GetFromHeight()
    45  		c.HeightTo = new.GetToHeight()
    46  		return true
    47  	}
    48  
    49  	if new.GetToHeight() == c.HeightFrom-1 {
    50  		c.Segments = append([]T{new}, c.Segments...)
    51  		c.HeightFrom = new.GetFromHeight()
    52  		return true
    53  	}
    54  
    55  	if new.GetFromHeight() == c.HeightTo+1 {
    56  		c.Segments = append(c.Segments, new)
    57  		c.HeightTo = new.GetToHeight()
    58  		return true
    59  	}
    60  
    61  	return false
    62  }
    63  
    64  // Slice returns a new chunk containing the segments which partially or fully fall into the specified range.
    65  func (c ContiguousHistory[T]) Slice(from int64, to int64) ContiguousHistory[T] {
    66  	var new ContiguousHistory[T]
    67  
    68  	for _, segment := range c.Segments {
    69  		if segment.GetToHeight() < from {
    70  			continue
    71  		}
    72  		if segment.GetFromHeight() > to {
    73  			continue
    74  		}
    75  
    76  		new.Add(segment)
    77  	}
    78  	return new
    79  }