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 }