github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/interval/interval.go (about) 1 // Copyright ©2012 The bíogo Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Portions of this file are additionally subject to the following 6 // license and copyright. 7 // 8 // Copyright 2016 The Cockroach Authors. 9 // 10 // Use of this software is governed by the Business Source License 11 // included in the file licenses/BSL.txt. 12 // 13 // As of the Change Date specified in that file, in accordance with 14 // the Business Source License, use of this software will be governed 15 // by the Apache License, Version 2.0, included in the file 16 // licenses/APL.txt. 17 18 // This code originated in the github.com/biogo/store/interval package. 19 20 // Package interval provides two implementations for an interval tree. One is 21 // based on an augmented Left-Leaning Red Black tree. The other is based on an 22 // augmented BTree. 23 package interval 24 25 import ( 26 "bytes" 27 "fmt" 28 29 "github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil" 30 "github.com/cockroachdb/errors" 31 ) 32 33 // ErrInvertedRange is returned if an interval is used where the start value is greater 34 // than the end value. 35 var ErrInvertedRange = errors.Newf("interval: inverted range") 36 37 // ErrEmptyRange is returned if an interval is used where the start value is equal 38 // to the end value. 39 var ErrEmptyRange = errors.Newf("interval: empty range") 40 41 // ErrNilRange is returned if an interval is used where both the start value and 42 // the end value are nil. This is a specialization of ErrEmptyRange. 43 var ErrNilRange = errors.Newf("interval: nil range") 44 45 func rangeError(r Range) error { 46 switch r.Start.Compare(r.End) { 47 case 1: 48 return ErrInvertedRange 49 case 0: 50 if len(r.Start) == 0 && len(r.End) == 0 { 51 return ErrNilRange 52 } 53 return ErrEmptyRange 54 default: 55 return nil 56 } 57 } 58 59 // A Range is a type that describes the basic characteristics of an interval. 60 type Range struct { 61 Start, End Comparable 62 } 63 64 // Equal returns whether the two ranges are equal. 65 func (r Range) Equal(other Range) bool { 66 return r.Start.Equal(other.Start) && r.End.Equal(other.End) 67 } 68 69 // String implements the Stringer interface. 70 func (r Range) String() string { 71 return fmt.Sprintf("{%x-%x}", r.Start, r.End) 72 } 73 74 // Overlapper specifies the overlapping relationship. 75 type Overlapper interface { 76 // Overlap checks whether two ranges overlap. 77 Overlap(Range, Range) bool 78 } 79 80 type inclusiveOverlapper struct{} 81 82 // Overlap checks where a and b overlap in the inclusive way. 83 func (overlapper inclusiveOverlapper) Overlap(a Range, b Range) bool { 84 return overlapsInclusive(a, b) 85 } 86 87 func overlapsInclusive(a Range, b Range) bool { 88 return a.Start.Compare(b.End) <= 0 && b.Start.Compare(a.End) <= 0 89 } 90 91 // InclusiveOverlapper defines overlapping as a pair of ranges that share a segment of the keyspace 92 // in the inclusive way. "inclusive" means that both start and end keys treated as inclusive values. 93 var InclusiveOverlapper = inclusiveOverlapper{} 94 95 type exclusiveOverlapper struct{} 96 97 // Overlap checks where a and b overlap in the exclusive way. 98 func (overlapper exclusiveOverlapper) Overlap(a Range, b Range) bool { 99 return overlapsExclusive(a, b) 100 } 101 102 func overlapsExclusive(a Range, b Range) bool { 103 return a.Start.Compare(b.End) < 0 && b.Start.Compare(a.End) < 0 104 } 105 106 // ExclusiveOverlapper defines overlapping as a pair of ranges that share a segment of the keyspace 107 // in the exclusive. "exclusive" means that the start keys are treated as inclusive and the end keys 108 // are treated as exclusive. 109 var ExclusiveOverlapper = exclusiveOverlapper{} 110 111 // An Interface is a type that can be inserted into an interval tree. 112 type Interface interface { 113 Range() Range 114 // Returns a unique ID for the element. 115 // TODO(nvanbenschoten): Should this be changed to an int64? 116 ID() uintptr 117 } 118 119 // Compare returns a value indicating the sort order relationship between a and b. The comparison is 120 // performed lexicographically on (a.Range().Start, a.ID()) and (b.Range().Start, b.ID()) tuples 121 // where Range().Start is more significant that ID(). 122 // 123 // Given c = Compare(a, b): 124 // 125 // c == -1 if (a.Range().Start, a.ID()) < (b.Range().Start, b.ID()); 126 // c == 0 if (a.Range().Start, a.ID()) == (b.Range().Start, b.ID()); and 127 // c == 1 if (a.Range().Start, a.ID()) > (b.Range().Start, b.ID()). 128 // 129 // "c == 0" is equivalent to "Equal(a, b) == true". 130 func Compare(a, b Interface) int { 131 startCmp := a.Range().Start.Compare(b.Range().Start) 132 if startCmp != 0 { 133 return startCmp 134 } 135 aID := a.ID() 136 bID := b.ID() 137 if aID < bID { 138 return -1 139 } else if aID > bID { 140 return 1 141 } else { 142 return 0 143 } 144 } 145 146 // Equal returns a boolean indicating whether the given Interfaces are equal to each other. If 147 // "Equal(a, b) == true", "a.Range().End == b.Range().End" must hold. Otherwise, the interval tree 148 // behavior is undefined. "Equal(a, b) == true" is equivalent to "Compare(a, b) == 0". But the 149 // former has measurably better performance than the latter. So Equal should be used when only 150 // equality state is needed. 151 func Equal(a, b Interface) bool { 152 return a.ID() == b.ID() && a.Range().Start.Equal(b.Range().Start) 153 } 154 155 // A Comparable is a type that describes the ends of a Range. 156 type Comparable []byte 157 158 // Compare returns a value indicating the sort order relationship between the 159 // receiver and the parameter. 160 // 161 // Given c = a.Compare(b): 162 // 163 // c == -1 if a < b; 164 // c == 0 if a == b; and 165 // c == 1 if a > b. 166 func (c Comparable) Compare(o Comparable) int { 167 return bytes.Compare(c, o) 168 } 169 170 // Equal returns a boolean indicating if the given comparables are equal to 171 // each other. Note that this has measurably better performance than 172 // Compare() == 0, so it should be used when only equality state is needed. 173 func (c Comparable) Equal(o Comparable) bool { 174 return bytes.Equal(c, o) 175 } 176 177 // An Operation is a function that operates on an Interface. If done is returned true, the 178 // Operation is indicating that no further work needs to be done and so the DoMatching function 179 // should traverse no further. 180 type Operation func(Interface) (done bool) 181 182 // Tree is an interval tree. For all the functions which have a fast argument, 183 // fast being true means a fast operation which does not adjust node ranges. If 184 // fast is false, node ranges are adjusted. 185 type Tree interface { 186 // AdjustRanges fixes range fields for all nodes in the tree. This must be 187 // called before Get, Do or DoMatching* is used if fast insertion or deletion 188 // has been performed. 189 AdjustRanges() 190 // Len returns the number of intervals stored in the Tree. 191 Len() int 192 // Get returns a slice of Interfaces that overlap r in the tree. The slice is 193 // sorted nondecreasingly by interval start. 194 Get(r Range) []Interface 195 // GetWithOverlapper returns a slice of Interfaces that overlap r in the tree 196 // using the provided overlapper function. The slice is sorted nondecreasingly 197 // by interval start. 198 GetWithOverlapper(r Range, overlapper Overlapper) []Interface 199 // Insert inserts the Interface e into the tree. Insertions may replace an 200 // existing Interface which is equal to the Interface e. 201 Insert(e Interface, fast bool) error 202 // Delete deletes the Interface e if it exists in the tree. The deleted 203 // Interface is equal to the Interface e. 204 Delete(e Interface, fast bool) error 205 // Do performs fn on all intervals stored in the tree. The traversal is done 206 // in the nondecreasing order of interval start. A boolean is returned 207 // indicating whether the traversal was interrupted by an Operation returning 208 // true. If fn alters stored intervals' sort relationships, future tree 209 // operation behaviors are undefined. 210 Do(fn Operation) bool 211 // DoMatching performs fn on all intervals stored in the tree that overlaps r. 212 // The traversal is done in the nondecreasing order of interval start. A 213 // boolean is returned indicating whether the traversal was interrupted by an 214 // Operation returning true. If fn alters stored intervals' sort 215 // relationships, future tree operation behaviors are undefined. 216 DoMatching(fn Operation, r Range) bool 217 // Iterator creates an iterator to iterate over all intervals stored in the 218 // tree, in-order. 219 Iterator() TreeIterator 220 // Clear this tree. 221 Clear() 222 // Clone clones the tree, returning a copy. 223 Clone() Tree 224 } 225 226 // TreeIterator iterates over all intervals stored in the interval tree, in-order. 227 type TreeIterator interface { 228 // Next returns the current interval stored in the interval tree and moves 229 // the iterator to the next interval. The method returns false if no intervals 230 // remain in the interval tree. 231 Next() (Interface, bool) 232 } 233 234 var useBTreeImpl = envutil.EnvOrDefaultBool("COCKROACH_INTERVAL_BTREE", false) 235 236 // NewTree creates a new interval tree with the given overlapper function. It 237 // uses the augmented Left-Leaning Red Black tree implementation unless the 238 // envvar COCKROACH_INTERVAL_BTREE is set. 239 func NewTree(overlapper Overlapper) Tree { 240 if useBTreeImpl { 241 return newBTree(overlapper) 242 } 243 return newLLRBTree(overlapper) 244 }