github.com/ttpreport/gvisor-ligolo@v0.0.0-20240123134145-a858404967ba/pkg/sentry/pgalloc/evictable_range_set.go (about) 1 package pgalloc 2 3 import ( 4 "bytes" 5 "fmt" 6 ) 7 8 // trackGaps is an optional parameter. 9 // 10 // If trackGaps is 1, the Set will track maximum gap size recursively, 11 // enabling the GapIterator.{Prev,Next}LargeEnoughGap functions. In this 12 // case, Key must be an unsigned integer. 13 // 14 // trackGaps must be 0 or 1. 15 const evictableRangetrackGaps = 0 16 17 var _ = uint8(evictableRangetrackGaps << 7) // Will fail if not zero or one. 18 19 // dynamicGap is a type that disappears if trackGaps is 0. 20 type evictableRangedynamicGap [evictableRangetrackGaps]uint64 21 22 // Get returns the value of the gap. 23 // 24 // Precondition: trackGaps must be non-zero. 25 func (d *evictableRangedynamicGap) Get() uint64 { 26 return d[:][0] 27 } 28 29 // Set sets the value of the gap. 30 // 31 // Precondition: trackGaps must be non-zero. 32 func (d *evictableRangedynamicGap) Set(v uint64) { 33 d[:][0] = v 34 } 35 36 const ( 37 // minDegree is the minimum degree of an internal node in a Set B-tree. 38 // 39 // - Any non-root node has at least minDegree-1 segments. 40 // 41 // - Any non-root internal (non-leaf) node has at least minDegree children. 42 // 43 // - The root node may have fewer than minDegree-1 segments, but it may 44 // only have 0 segments if the tree is empty. 45 // 46 // Our implementation requires minDegree >= 3. Higher values of minDegree 47 // usually improve performance, but increase memory usage for small sets. 48 evictableRangeminDegree = 3 49 50 evictableRangemaxDegree = 2 * evictableRangeminDegree 51 ) 52 53 // A Set is a mapping of segments with non-overlapping Range keys. The zero 54 // value for a Set is an empty set. Set values are not safely movable nor 55 // copyable. Set is thread-compatible. 56 // 57 // +stateify savable 58 type evictableRangeSet struct { 59 root evictableRangenode `state:".(*evictableRangeSegmentDataSlices)"` 60 } 61 62 // IsEmpty returns true if the set contains no segments. 63 func (s *evictableRangeSet) IsEmpty() bool { 64 return s.root.nrSegments == 0 65 } 66 67 // IsEmptyRange returns true iff no segments in the set overlap the given 68 // range. This is semantically equivalent to s.SpanRange(r) == 0, but may be 69 // more efficient. 70 func (s *evictableRangeSet) IsEmptyRange(r EvictableRange) bool { 71 switch { 72 case r.Length() < 0: 73 panic(fmt.Sprintf("invalid range %v", r)) 74 case r.Length() == 0: 75 return true 76 } 77 _, gap := s.Find(r.Start) 78 if !gap.Ok() { 79 return false 80 } 81 return r.End <= gap.End() 82 } 83 84 // Span returns the total size of all segments in the set. 85 func (s *evictableRangeSet) Span() uint64 { 86 var sz uint64 87 for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() { 88 sz += seg.Range().Length() 89 } 90 return sz 91 } 92 93 // SpanRange returns the total size of the intersection of segments in the set 94 // with the given range. 95 func (s *evictableRangeSet) SpanRange(r EvictableRange) uint64 { 96 switch { 97 case r.Length() < 0: 98 panic(fmt.Sprintf("invalid range %v", r)) 99 case r.Length() == 0: 100 return 0 101 } 102 var sz uint64 103 for seg := s.LowerBoundSegment(r.Start); seg.Ok() && seg.Start() < r.End; seg = seg.NextSegment() { 104 sz += seg.Range().Intersect(r).Length() 105 } 106 return sz 107 } 108 109 // FirstSegment returns the first segment in the set. If the set is empty, 110 // FirstSegment returns a terminal iterator. 111 func (s *evictableRangeSet) FirstSegment() evictableRangeIterator { 112 if s.root.nrSegments == 0 { 113 return evictableRangeIterator{} 114 } 115 return s.root.firstSegment() 116 } 117 118 // LastSegment returns the last segment in the set. If the set is empty, 119 // LastSegment returns a terminal iterator. 120 func (s *evictableRangeSet) LastSegment() evictableRangeIterator { 121 if s.root.nrSegments == 0 { 122 return evictableRangeIterator{} 123 } 124 return s.root.lastSegment() 125 } 126 127 // FirstGap returns the first gap in the set. 128 func (s *evictableRangeSet) FirstGap() evictableRangeGapIterator { 129 n := &s.root 130 for n.hasChildren { 131 n = n.children[0] 132 } 133 return evictableRangeGapIterator{n, 0} 134 } 135 136 // LastGap returns the last gap in the set. 137 func (s *evictableRangeSet) LastGap() evictableRangeGapIterator { 138 n := &s.root 139 for n.hasChildren { 140 n = n.children[n.nrSegments] 141 } 142 return evictableRangeGapIterator{n, n.nrSegments} 143 } 144 145 // Find returns the segment or gap whose range contains the given key. If a 146 // segment is found, the returned Iterator is non-terminal and the 147 // returned GapIterator is terminal. Otherwise, the returned Iterator is 148 // terminal and the returned GapIterator is non-terminal. 149 func (s *evictableRangeSet) Find(key uint64) (evictableRangeIterator, evictableRangeGapIterator) { 150 n := &s.root 151 for { 152 153 lower := 0 154 upper := n.nrSegments 155 for lower < upper { 156 i := lower + (upper-lower)/2 157 if r := n.keys[i]; key < r.End { 158 if key >= r.Start { 159 return evictableRangeIterator{n, i}, evictableRangeGapIterator{} 160 } 161 upper = i 162 } else { 163 lower = i + 1 164 } 165 } 166 i := lower 167 if !n.hasChildren { 168 return evictableRangeIterator{}, evictableRangeGapIterator{n, i} 169 } 170 n = n.children[i] 171 } 172 } 173 174 // FindSegment returns the segment whose range contains the given key. If no 175 // such segment exists, FindSegment returns a terminal iterator. 176 func (s *evictableRangeSet) FindSegment(key uint64) evictableRangeIterator { 177 seg, _ := s.Find(key) 178 return seg 179 } 180 181 // LowerBoundSegment returns the segment with the lowest range that contains a 182 // key greater than or equal to min. If no such segment exists, 183 // LowerBoundSegment returns a terminal iterator. 184 func (s *evictableRangeSet) LowerBoundSegment(min uint64) evictableRangeIterator { 185 seg, gap := s.Find(min) 186 if seg.Ok() { 187 return seg 188 } 189 return gap.NextSegment() 190 } 191 192 // UpperBoundSegment returns the segment with the highest range that contains a 193 // key less than or equal to max. If no such segment exists, UpperBoundSegment 194 // returns a terminal iterator. 195 func (s *evictableRangeSet) UpperBoundSegment(max uint64) evictableRangeIterator { 196 seg, gap := s.Find(max) 197 if seg.Ok() { 198 return seg 199 } 200 return gap.PrevSegment() 201 } 202 203 // FindGap returns the gap containing the given key. If no such gap exists 204 // (i.e. the set contains a segment containing that key), FindGap returns a 205 // terminal iterator. 206 func (s *evictableRangeSet) FindGap(key uint64) evictableRangeGapIterator { 207 _, gap := s.Find(key) 208 return gap 209 } 210 211 // LowerBoundGap returns the gap with the lowest range that is greater than or 212 // equal to min. 213 func (s *evictableRangeSet) LowerBoundGap(min uint64) evictableRangeGapIterator { 214 seg, gap := s.Find(min) 215 if gap.Ok() { 216 return gap 217 } 218 return seg.NextGap() 219 } 220 221 // UpperBoundGap returns the gap with the highest range that is less than or 222 // equal to max. 223 func (s *evictableRangeSet) UpperBoundGap(max uint64) evictableRangeGapIterator { 224 seg, gap := s.Find(max) 225 if gap.Ok() { 226 return gap 227 } 228 return seg.PrevGap() 229 } 230 231 // Add inserts the given segment into the set and returns true. If the new 232 // segment can be merged with adjacent segments, Add will do so. If the new 233 // segment would overlap an existing segment, Add returns false. If Add 234 // succeeds, all existing iterators are invalidated. 235 func (s *evictableRangeSet) Add(r EvictableRange, val evictableRangeSetValue) bool { 236 if r.Length() <= 0 { 237 panic(fmt.Sprintf("invalid segment range %v", r)) 238 } 239 gap := s.FindGap(r.Start) 240 if !gap.Ok() { 241 return false 242 } 243 if r.End > gap.End() { 244 return false 245 } 246 s.Insert(gap, r, val) 247 return true 248 } 249 250 // AddWithoutMerging inserts the given segment into the set and returns true. 251 // If it would overlap an existing segment, AddWithoutMerging does nothing and 252 // returns false. If AddWithoutMerging succeeds, all existing iterators are 253 // invalidated. 254 func (s *evictableRangeSet) AddWithoutMerging(r EvictableRange, val evictableRangeSetValue) bool { 255 if r.Length() <= 0 { 256 panic(fmt.Sprintf("invalid segment range %v", r)) 257 } 258 gap := s.FindGap(r.Start) 259 if !gap.Ok() { 260 return false 261 } 262 if r.End > gap.End() { 263 return false 264 } 265 s.InsertWithoutMergingUnchecked(gap, r, val) 266 return true 267 } 268 269 // Insert inserts the given segment into the given gap. If the new segment can 270 // be merged with adjacent segments, Insert will do so. Insert returns an 271 // iterator to the segment containing the inserted value (which may have been 272 // merged with other values). All existing iterators (including gap, but not 273 // including the returned iterator) are invalidated. 274 // 275 // If the gap cannot accommodate the segment, or if r is invalid, Insert panics. 276 // 277 // Insert is semantically equivalent to a InsertWithoutMerging followed by a 278 // Merge, but may be more efficient. Note that there is no unchecked variant of 279 // Insert since Insert must retrieve and inspect gap's predecessor and 280 // successor segments regardless. 281 func (s *evictableRangeSet) Insert(gap evictableRangeGapIterator, r EvictableRange, val evictableRangeSetValue) evictableRangeIterator { 282 if r.Length() <= 0 { 283 panic(fmt.Sprintf("invalid segment range %v", r)) 284 } 285 prev, next := gap.PrevSegment(), gap.NextSegment() 286 if prev.Ok() && prev.End() > r.Start { 287 panic(fmt.Sprintf("new segment %v overlaps predecessor %v", r, prev.Range())) 288 } 289 if next.Ok() && next.Start() < r.End { 290 panic(fmt.Sprintf("new segment %v overlaps successor %v", r, next.Range())) 291 } 292 if prev.Ok() && prev.End() == r.Start { 293 if mval, ok := (evictableRangeSetFunctions{}).Merge(prev.Range(), prev.Value(), r, val); ok { 294 shrinkMaxGap := evictableRangetrackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get() 295 prev.SetEndUnchecked(r.End) 296 prev.SetValue(mval) 297 if shrinkMaxGap { 298 gap.node.updateMaxGapLeaf() 299 } 300 if next.Ok() && next.Start() == r.End { 301 val = mval 302 if mval, ok := (evictableRangeSetFunctions{}).Merge(prev.Range(), val, next.Range(), next.Value()); ok { 303 prev.SetEndUnchecked(next.End()) 304 prev.SetValue(mval) 305 return s.Remove(next).PrevSegment() 306 } 307 } 308 return prev 309 } 310 } 311 if next.Ok() && next.Start() == r.End { 312 if mval, ok := (evictableRangeSetFunctions{}).Merge(r, val, next.Range(), next.Value()); ok { 313 shrinkMaxGap := evictableRangetrackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get() 314 next.SetStartUnchecked(r.Start) 315 next.SetValue(mval) 316 if shrinkMaxGap { 317 gap.node.updateMaxGapLeaf() 318 } 319 return next 320 } 321 } 322 323 return s.InsertWithoutMergingUnchecked(gap, r, val) 324 } 325 326 // InsertWithoutMerging inserts the given segment into the given gap and 327 // returns an iterator to the inserted segment. All existing iterators 328 // (including gap, but not including the returned iterator) are invalidated. 329 // 330 // If the gap cannot accommodate the segment, or if r is invalid, 331 // InsertWithoutMerging panics. 332 func (s *evictableRangeSet) InsertWithoutMerging(gap evictableRangeGapIterator, r EvictableRange, val evictableRangeSetValue) evictableRangeIterator { 333 if r.Length() <= 0 { 334 panic(fmt.Sprintf("invalid segment range %v", r)) 335 } 336 if gr := gap.Range(); !gr.IsSupersetOf(r) { 337 panic(fmt.Sprintf("cannot insert segment range %v into gap range %v", r, gr)) 338 } 339 return s.InsertWithoutMergingUnchecked(gap, r, val) 340 } 341 342 // InsertWithoutMergingUnchecked inserts the given segment into the given gap 343 // and returns an iterator to the inserted segment. All existing iterators 344 // (including gap, but not including the returned iterator) are invalidated. 345 // 346 // Preconditions: 347 // - r.Start >= gap.Start(). 348 // - r.End <= gap.End(). 349 func (s *evictableRangeSet) InsertWithoutMergingUnchecked(gap evictableRangeGapIterator, r EvictableRange, val evictableRangeSetValue) evictableRangeIterator { 350 gap = gap.node.rebalanceBeforeInsert(gap) 351 splitMaxGap := evictableRangetrackGaps != 0 && (gap.node.nrSegments == 0 || gap.Range().Length() == gap.node.maxGap.Get()) 352 copy(gap.node.keys[gap.index+1:], gap.node.keys[gap.index:gap.node.nrSegments]) 353 copy(gap.node.values[gap.index+1:], gap.node.values[gap.index:gap.node.nrSegments]) 354 gap.node.keys[gap.index] = r 355 gap.node.values[gap.index] = val 356 gap.node.nrSegments++ 357 if splitMaxGap { 358 gap.node.updateMaxGapLeaf() 359 } 360 return evictableRangeIterator{gap.node, gap.index} 361 } 362 363 // Remove removes the given segment and returns an iterator to the vacated gap. 364 // All existing iterators (including seg, but not including the returned 365 // iterator) are invalidated. 366 func (s *evictableRangeSet) Remove(seg evictableRangeIterator) evictableRangeGapIterator { 367 368 if seg.node.hasChildren { 369 370 victim := seg.PrevSegment() 371 372 seg.SetRangeUnchecked(victim.Range()) 373 seg.SetValue(victim.Value()) 374 375 nextAdjacentNode := seg.NextSegment().node 376 if evictableRangetrackGaps != 0 { 377 nextAdjacentNode.updateMaxGapLeaf() 378 } 379 return s.Remove(victim).NextGap() 380 } 381 copy(seg.node.keys[seg.index:], seg.node.keys[seg.index+1:seg.node.nrSegments]) 382 copy(seg.node.values[seg.index:], seg.node.values[seg.index+1:seg.node.nrSegments]) 383 evictableRangeSetFunctions{}.ClearValue(&seg.node.values[seg.node.nrSegments-1]) 384 seg.node.nrSegments-- 385 if evictableRangetrackGaps != 0 { 386 seg.node.updateMaxGapLeaf() 387 } 388 return seg.node.rebalanceAfterRemove(evictableRangeGapIterator{seg.node, seg.index}) 389 } 390 391 // RemoveAll removes all segments from the set. All existing iterators are 392 // invalidated. 393 func (s *evictableRangeSet) RemoveAll() { 394 s.root = evictableRangenode{} 395 } 396 397 // RemoveRange removes all segments in the given range. An iterator to the 398 // newly formed gap is returned, and all existing iterators are invalidated. 399 func (s *evictableRangeSet) RemoveRange(r EvictableRange) evictableRangeGapIterator { 400 seg, gap := s.Find(r.Start) 401 if seg.Ok() { 402 seg = s.Isolate(seg, r) 403 gap = s.Remove(seg) 404 } 405 for seg = gap.NextSegment(); seg.Ok() && seg.Start() < r.End; seg = gap.NextSegment() { 406 seg = s.Isolate(seg, r) 407 gap = s.Remove(seg) 408 } 409 return gap 410 } 411 412 // Merge attempts to merge two neighboring segments. If successful, Merge 413 // returns an iterator to the merged segment, and all existing iterators are 414 // invalidated. Otherwise, Merge returns a terminal iterator. 415 // 416 // If first is not the predecessor of second, Merge panics. 417 func (s *evictableRangeSet) Merge(first, second evictableRangeIterator) evictableRangeIterator { 418 if first.NextSegment() != second { 419 panic(fmt.Sprintf("attempt to merge non-neighboring segments %v, %v", first.Range(), second.Range())) 420 } 421 return s.MergeUnchecked(first, second) 422 } 423 424 // MergeUnchecked attempts to merge two neighboring segments. If successful, 425 // MergeUnchecked returns an iterator to the merged segment, and all existing 426 // iterators are invalidated. Otherwise, MergeUnchecked returns a terminal 427 // iterator. 428 // 429 // Precondition: first is the predecessor of second: first.NextSegment() == 430 // second, first == second.PrevSegment(). 431 func (s *evictableRangeSet) MergeUnchecked(first, second evictableRangeIterator) evictableRangeIterator { 432 if first.End() == second.Start() { 433 if mval, ok := (evictableRangeSetFunctions{}).Merge(first.Range(), first.Value(), second.Range(), second.Value()); ok { 434 435 first.SetEndUnchecked(second.End()) 436 first.SetValue(mval) 437 438 return s.Remove(second).PrevSegment() 439 } 440 } 441 return evictableRangeIterator{} 442 } 443 444 // MergeAll attempts to merge all adjacent segments in the set. All existing 445 // iterators are invalidated. 446 func (s *evictableRangeSet) MergeAll() { 447 seg := s.FirstSegment() 448 if !seg.Ok() { 449 return 450 } 451 next := seg.NextSegment() 452 for next.Ok() { 453 if mseg := s.MergeUnchecked(seg, next); mseg.Ok() { 454 seg, next = mseg, mseg.NextSegment() 455 } else { 456 seg, next = next, next.NextSegment() 457 } 458 } 459 } 460 461 // MergeRange attempts to merge all adjacent segments that contain a key in the 462 // specific range. All existing iterators are invalidated. 463 func (s *evictableRangeSet) MergeRange(r EvictableRange) { 464 seg := s.LowerBoundSegment(r.Start) 465 if !seg.Ok() { 466 return 467 } 468 next := seg.NextSegment() 469 for next.Ok() && next.Range().Start < r.End { 470 if mseg := s.MergeUnchecked(seg, next); mseg.Ok() { 471 seg, next = mseg, mseg.NextSegment() 472 } else { 473 seg, next = next, next.NextSegment() 474 } 475 } 476 } 477 478 // MergeAdjacent attempts to merge the segment containing r.Start with its 479 // predecessor, and the segment containing r.End-1 with its successor. 480 func (s *evictableRangeSet) MergeAdjacent(r EvictableRange) { 481 first := s.FindSegment(r.Start) 482 if first.Ok() { 483 if prev := first.PrevSegment(); prev.Ok() { 484 s.Merge(prev, first) 485 } 486 } 487 last := s.FindSegment(r.End - 1) 488 if last.Ok() { 489 if next := last.NextSegment(); next.Ok() { 490 s.Merge(last, next) 491 } 492 } 493 } 494 495 // Split splits the given segment at the given key and returns iterators to the 496 // two resulting segments. All existing iterators (including seg, but not 497 // including the returned iterators) are invalidated. 498 // 499 // If the segment cannot be split at split (because split is at the start or 500 // end of the segment's range, so splitting would produce a segment with zero 501 // length, or because split falls outside the segment's range altogether), 502 // Split panics. 503 func (s *evictableRangeSet) Split(seg evictableRangeIterator, split uint64) (evictableRangeIterator, evictableRangeIterator) { 504 if !seg.Range().CanSplitAt(split) { 505 panic(fmt.Sprintf("can't split %v at %v", seg.Range(), split)) 506 } 507 return s.SplitUnchecked(seg, split) 508 } 509 510 // SplitUnchecked splits the given segment at the given key and returns 511 // iterators to the two resulting segments. All existing iterators (including 512 // seg, but not including the returned iterators) are invalidated. 513 // 514 // Preconditions: seg.Start() < key < seg.End(). 515 func (s *evictableRangeSet) SplitUnchecked(seg evictableRangeIterator, split uint64) (evictableRangeIterator, evictableRangeIterator) { 516 val1, val2 := (evictableRangeSetFunctions{}).Split(seg.Range(), seg.Value(), split) 517 end2 := seg.End() 518 seg.SetEndUnchecked(split) 519 seg.SetValue(val1) 520 seg2 := s.InsertWithoutMergingUnchecked(seg.NextGap(), EvictableRange{split, end2}, val2) 521 522 return seg2.PrevSegment(), seg2 523 } 524 525 // SplitAt splits the segment straddling split, if one exists. SplitAt returns 526 // true if a segment was split and false otherwise. If SplitAt splits a 527 // segment, all existing iterators are invalidated. 528 func (s *evictableRangeSet) SplitAt(split uint64) bool { 529 if seg := s.FindSegment(split); seg.Ok() && seg.Range().CanSplitAt(split) { 530 s.SplitUnchecked(seg, split) 531 return true 532 } 533 return false 534 } 535 536 // Isolate ensures that the given segment's range does not escape r by 537 // splitting at r.Start and r.End if necessary, and returns an updated iterator 538 // to the bounded segment. All existing iterators (including seg, but not 539 // including the returned iterators) are invalidated. 540 func (s *evictableRangeSet) Isolate(seg evictableRangeIterator, r EvictableRange) evictableRangeIterator { 541 if seg.Range().CanSplitAt(r.Start) { 542 _, seg = s.SplitUnchecked(seg, r.Start) 543 } 544 if seg.Range().CanSplitAt(r.End) { 545 seg, _ = s.SplitUnchecked(seg, r.End) 546 } 547 return seg 548 } 549 550 // ApplyContiguous applies a function to a contiguous range of segments, 551 // splitting if necessary. The function is applied until the first gap is 552 // encountered, at which point the gap is returned. If the function is applied 553 // across the entire range, a terminal gap is returned. All existing iterators 554 // are invalidated. 555 // 556 // N.B. The Iterator must not be invalidated by the function. 557 func (s *evictableRangeSet) ApplyContiguous(r EvictableRange, fn func(seg evictableRangeIterator)) evictableRangeGapIterator { 558 seg, gap := s.Find(r.Start) 559 if !seg.Ok() { 560 return gap 561 } 562 for { 563 seg = s.Isolate(seg, r) 564 fn(seg) 565 if seg.End() >= r.End { 566 return evictableRangeGapIterator{} 567 } 568 gap = seg.NextGap() 569 if !gap.IsEmpty() { 570 return gap 571 } 572 seg = gap.NextSegment() 573 if !seg.Ok() { 574 575 return evictableRangeGapIterator{} 576 } 577 } 578 } 579 580 // +stateify savable 581 type evictableRangenode struct { 582 // An internal binary tree node looks like: 583 // 584 // K 585 // / \ 586 // Cl Cr 587 // 588 // where all keys in the subtree rooted by Cl (the left subtree) are less 589 // than K (the key of the parent node), and all keys in the subtree rooted 590 // by Cr (the right subtree) are greater than K. 591 // 592 // An internal B-tree node's indexes work out to look like: 593 // 594 // K0 K1 K2 ... Kn-1 595 // / \/ \/ \ ... / \ 596 // C0 C1 C2 C3 ... Cn-1 Cn 597 // 598 // where n is nrSegments. 599 nrSegments int 600 601 // parent is a pointer to this node's parent. If this node is root, parent 602 // is nil. 603 parent *evictableRangenode 604 605 // parentIndex is the index of this node in parent.children. 606 parentIndex int 607 608 // Flag for internal nodes that is technically redundant with "children[0] 609 // != nil", but is stored in the first cache line. "hasChildren" rather 610 // than "isLeaf" because false must be the correct value for an empty root. 611 hasChildren bool 612 613 // The longest gap within this node. If the node is a leaf, it's simply the 614 // maximum gap among all the (nrSegments+1) gaps formed by its nrSegments keys 615 // including the 0th and nrSegments-th gap possibly shared with its upper-level 616 // nodes; if it's a non-leaf node, it's the max of all children's maxGap. 617 maxGap evictableRangedynamicGap 618 619 // Nodes store keys and values in separate arrays to maximize locality in 620 // the common case (scanning keys for lookup). 621 keys [evictableRangemaxDegree - 1]EvictableRange 622 values [evictableRangemaxDegree - 1]evictableRangeSetValue 623 children [evictableRangemaxDegree]*evictableRangenode 624 } 625 626 // firstSegment returns the first segment in the subtree rooted by n. 627 // 628 // Preconditions: n.nrSegments != 0. 629 func (n *evictableRangenode) firstSegment() evictableRangeIterator { 630 for n.hasChildren { 631 n = n.children[0] 632 } 633 return evictableRangeIterator{n, 0} 634 } 635 636 // lastSegment returns the last segment in the subtree rooted by n. 637 // 638 // Preconditions: n.nrSegments != 0. 639 func (n *evictableRangenode) lastSegment() evictableRangeIterator { 640 for n.hasChildren { 641 n = n.children[n.nrSegments] 642 } 643 return evictableRangeIterator{n, n.nrSegments - 1} 644 } 645 646 func (n *evictableRangenode) prevSibling() *evictableRangenode { 647 if n.parent == nil || n.parentIndex == 0 { 648 return nil 649 } 650 return n.parent.children[n.parentIndex-1] 651 } 652 653 func (n *evictableRangenode) nextSibling() *evictableRangenode { 654 if n.parent == nil || n.parentIndex == n.parent.nrSegments { 655 return nil 656 } 657 return n.parent.children[n.parentIndex+1] 658 } 659 660 // rebalanceBeforeInsert splits n and its ancestors if they are full, as 661 // required for insertion, and returns an updated iterator to the position 662 // represented by gap. 663 func (n *evictableRangenode) rebalanceBeforeInsert(gap evictableRangeGapIterator) evictableRangeGapIterator { 664 if n.nrSegments < evictableRangemaxDegree-1 { 665 return gap 666 } 667 if n.parent != nil { 668 gap = n.parent.rebalanceBeforeInsert(gap) 669 } 670 if n.parent == nil { 671 672 left := &evictableRangenode{ 673 nrSegments: evictableRangeminDegree - 1, 674 parent: n, 675 parentIndex: 0, 676 hasChildren: n.hasChildren, 677 } 678 right := &evictableRangenode{ 679 nrSegments: evictableRangeminDegree - 1, 680 parent: n, 681 parentIndex: 1, 682 hasChildren: n.hasChildren, 683 } 684 copy(left.keys[:evictableRangeminDegree-1], n.keys[:evictableRangeminDegree-1]) 685 copy(left.values[:evictableRangeminDegree-1], n.values[:evictableRangeminDegree-1]) 686 copy(right.keys[:evictableRangeminDegree-1], n.keys[evictableRangeminDegree:]) 687 copy(right.values[:evictableRangeminDegree-1], n.values[evictableRangeminDegree:]) 688 n.keys[0], n.values[0] = n.keys[evictableRangeminDegree-1], n.values[evictableRangeminDegree-1] 689 evictableRangezeroValueSlice(n.values[1:]) 690 if n.hasChildren { 691 copy(left.children[:evictableRangeminDegree], n.children[:evictableRangeminDegree]) 692 copy(right.children[:evictableRangeminDegree], n.children[evictableRangeminDegree:]) 693 evictableRangezeroNodeSlice(n.children[2:]) 694 for i := 0; i < evictableRangeminDegree; i++ { 695 left.children[i].parent = left 696 left.children[i].parentIndex = i 697 right.children[i].parent = right 698 right.children[i].parentIndex = i 699 } 700 } 701 n.nrSegments = 1 702 n.hasChildren = true 703 n.children[0] = left 704 n.children[1] = right 705 706 if evictableRangetrackGaps != 0 { 707 left.updateMaxGapLocal() 708 right.updateMaxGapLocal() 709 } 710 if gap.node != n { 711 return gap 712 } 713 if gap.index < evictableRangeminDegree { 714 return evictableRangeGapIterator{left, gap.index} 715 } 716 return evictableRangeGapIterator{right, gap.index - evictableRangeminDegree} 717 } 718 719 copy(n.parent.keys[n.parentIndex+1:], n.parent.keys[n.parentIndex:n.parent.nrSegments]) 720 copy(n.parent.values[n.parentIndex+1:], n.parent.values[n.parentIndex:n.parent.nrSegments]) 721 n.parent.keys[n.parentIndex], n.parent.values[n.parentIndex] = n.keys[evictableRangeminDegree-1], n.values[evictableRangeminDegree-1] 722 copy(n.parent.children[n.parentIndex+2:], n.parent.children[n.parentIndex+1:n.parent.nrSegments+1]) 723 for i := n.parentIndex + 2; i < n.parent.nrSegments+2; i++ { 724 n.parent.children[i].parentIndex = i 725 } 726 sibling := &evictableRangenode{ 727 nrSegments: evictableRangeminDegree - 1, 728 parent: n.parent, 729 parentIndex: n.parentIndex + 1, 730 hasChildren: n.hasChildren, 731 } 732 n.parent.children[n.parentIndex+1] = sibling 733 n.parent.nrSegments++ 734 copy(sibling.keys[:evictableRangeminDegree-1], n.keys[evictableRangeminDegree:]) 735 copy(sibling.values[:evictableRangeminDegree-1], n.values[evictableRangeminDegree:]) 736 evictableRangezeroValueSlice(n.values[evictableRangeminDegree-1:]) 737 if n.hasChildren { 738 copy(sibling.children[:evictableRangeminDegree], n.children[evictableRangeminDegree:]) 739 evictableRangezeroNodeSlice(n.children[evictableRangeminDegree:]) 740 for i := 0; i < evictableRangeminDegree; i++ { 741 sibling.children[i].parent = sibling 742 sibling.children[i].parentIndex = i 743 } 744 } 745 n.nrSegments = evictableRangeminDegree - 1 746 747 if evictableRangetrackGaps != 0 { 748 n.updateMaxGapLocal() 749 sibling.updateMaxGapLocal() 750 } 751 752 if gap.node != n { 753 return gap 754 } 755 if gap.index < evictableRangeminDegree { 756 return gap 757 } 758 return evictableRangeGapIterator{sibling, gap.index - evictableRangeminDegree} 759 } 760 761 // rebalanceAfterRemove "unsplits" n and its ancestors if they are deficient 762 // (contain fewer segments than required by B-tree invariants), as required for 763 // removal, and returns an updated iterator to the position represented by gap. 764 // 765 // Precondition: n is the only node in the tree that may currently violate a 766 // B-tree invariant. 767 func (n *evictableRangenode) rebalanceAfterRemove(gap evictableRangeGapIterator) evictableRangeGapIterator { 768 for { 769 if n.nrSegments >= evictableRangeminDegree-1 { 770 return gap 771 } 772 if n.parent == nil { 773 774 return gap 775 } 776 777 if sibling := n.prevSibling(); sibling != nil && sibling.nrSegments >= evictableRangeminDegree { 778 copy(n.keys[1:], n.keys[:n.nrSegments]) 779 copy(n.values[1:], n.values[:n.nrSegments]) 780 n.keys[0] = n.parent.keys[n.parentIndex-1] 781 n.values[0] = n.parent.values[n.parentIndex-1] 782 n.parent.keys[n.parentIndex-1] = sibling.keys[sibling.nrSegments-1] 783 n.parent.values[n.parentIndex-1] = sibling.values[sibling.nrSegments-1] 784 evictableRangeSetFunctions{}.ClearValue(&sibling.values[sibling.nrSegments-1]) 785 if n.hasChildren { 786 copy(n.children[1:], n.children[:n.nrSegments+1]) 787 n.children[0] = sibling.children[sibling.nrSegments] 788 sibling.children[sibling.nrSegments] = nil 789 n.children[0].parent = n 790 n.children[0].parentIndex = 0 791 for i := 1; i < n.nrSegments+2; i++ { 792 n.children[i].parentIndex = i 793 } 794 } 795 n.nrSegments++ 796 sibling.nrSegments-- 797 798 if evictableRangetrackGaps != 0 { 799 n.updateMaxGapLocal() 800 sibling.updateMaxGapLocal() 801 } 802 if gap.node == sibling && gap.index == sibling.nrSegments { 803 return evictableRangeGapIterator{n, 0} 804 } 805 if gap.node == n { 806 return evictableRangeGapIterator{n, gap.index + 1} 807 } 808 return gap 809 } 810 if sibling := n.nextSibling(); sibling != nil && sibling.nrSegments >= evictableRangeminDegree { 811 n.keys[n.nrSegments] = n.parent.keys[n.parentIndex] 812 n.values[n.nrSegments] = n.parent.values[n.parentIndex] 813 n.parent.keys[n.parentIndex] = sibling.keys[0] 814 n.parent.values[n.parentIndex] = sibling.values[0] 815 copy(sibling.keys[:sibling.nrSegments-1], sibling.keys[1:]) 816 copy(sibling.values[:sibling.nrSegments-1], sibling.values[1:]) 817 evictableRangeSetFunctions{}.ClearValue(&sibling.values[sibling.nrSegments-1]) 818 if n.hasChildren { 819 n.children[n.nrSegments+1] = sibling.children[0] 820 copy(sibling.children[:sibling.nrSegments], sibling.children[1:]) 821 sibling.children[sibling.nrSegments] = nil 822 n.children[n.nrSegments+1].parent = n 823 n.children[n.nrSegments+1].parentIndex = n.nrSegments + 1 824 for i := 0; i < sibling.nrSegments; i++ { 825 sibling.children[i].parentIndex = i 826 } 827 } 828 n.nrSegments++ 829 sibling.nrSegments-- 830 831 if evictableRangetrackGaps != 0 { 832 n.updateMaxGapLocal() 833 sibling.updateMaxGapLocal() 834 } 835 if gap.node == sibling { 836 if gap.index == 0 { 837 return evictableRangeGapIterator{n, n.nrSegments} 838 } 839 return evictableRangeGapIterator{sibling, gap.index - 1} 840 } 841 return gap 842 } 843 844 p := n.parent 845 if p.nrSegments == 1 { 846 847 left, right := p.children[0], p.children[1] 848 p.nrSegments = left.nrSegments + right.nrSegments + 1 849 p.hasChildren = left.hasChildren 850 p.keys[left.nrSegments] = p.keys[0] 851 p.values[left.nrSegments] = p.values[0] 852 copy(p.keys[:left.nrSegments], left.keys[:left.nrSegments]) 853 copy(p.values[:left.nrSegments], left.values[:left.nrSegments]) 854 copy(p.keys[left.nrSegments+1:], right.keys[:right.nrSegments]) 855 copy(p.values[left.nrSegments+1:], right.values[:right.nrSegments]) 856 if left.hasChildren { 857 copy(p.children[:left.nrSegments+1], left.children[:left.nrSegments+1]) 858 copy(p.children[left.nrSegments+1:], right.children[:right.nrSegments+1]) 859 for i := 0; i < p.nrSegments+1; i++ { 860 p.children[i].parent = p 861 p.children[i].parentIndex = i 862 } 863 } else { 864 p.children[0] = nil 865 p.children[1] = nil 866 } 867 868 if gap.node == left { 869 return evictableRangeGapIterator{p, gap.index} 870 } 871 if gap.node == right { 872 return evictableRangeGapIterator{p, gap.index + left.nrSegments + 1} 873 } 874 return gap 875 } 876 // Merge n and either sibling, along with the segment separating the 877 // two, into whichever of the two nodes comes first. This is the 878 // reverse of the non-root splitting case in 879 // node.rebalanceBeforeInsert. 880 var left, right *evictableRangenode 881 if n.parentIndex > 0 { 882 left = n.prevSibling() 883 right = n 884 } else { 885 left = n 886 right = n.nextSibling() 887 } 888 889 if gap.node == right { 890 gap = evictableRangeGapIterator{left, gap.index + left.nrSegments + 1} 891 } 892 left.keys[left.nrSegments] = p.keys[left.parentIndex] 893 left.values[left.nrSegments] = p.values[left.parentIndex] 894 copy(left.keys[left.nrSegments+1:], right.keys[:right.nrSegments]) 895 copy(left.values[left.nrSegments+1:], right.values[:right.nrSegments]) 896 if left.hasChildren { 897 copy(left.children[left.nrSegments+1:], right.children[:right.nrSegments+1]) 898 for i := left.nrSegments + 1; i < left.nrSegments+right.nrSegments+2; i++ { 899 left.children[i].parent = left 900 left.children[i].parentIndex = i 901 } 902 } 903 left.nrSegments += right.nrSegments + 1 904 copy(p.keys[left.parentIndex:], p.keys[left.parentIndex+1:p.nrSegments]) 905 copy(p.values[left.parentIndex:], p.values[left.parentIndex+1:p.nrSegments]) 906 evictableRangeSetFunctions{}.ClearValue(&p.values[p.nrSegments-1]) 907 copy(p.children[left.parentIndex+1:], p.children[left.parentIndex+2:p.nrSegments+1]) 908 for i := 0; i < p.nrSegments; i++ { 909 p.children[i].parentIndex = i 910 } 911 p.children[p.nrSegments] = nil 912 p.nrSegments-- 913 914 if evictableRangetrackGaps != 0 { 915 left.updateMaxGapLocal() 916 } 917 918 n = p 919 } 920 } 921 922 // updateMaxGapLeaf updates maxGap bottom-up from the calling leaf until no 923 // necessary update. 924 // 925 // Preconditions: n must be a leaf node, trackGaps must be 1. 926 func (n *evictableRangenode) updateMaxGapLeaf() { 927 if n.hasChildren { 928 panic(fmt.Sprintf("updateMaxGapLeaf should always be called on leaf node: %v", n)) 929 } 930 max := n.calculateMaxGapLeaf() 931 if max == n.maxGap.Get() { 932 933 return 934 } 935 oldMax := n.maxGap.Get() 936 n.maxGap.Set(max) 937 if max > oldMax { 938 939 for p := n.parent; p != nil; p = p.parent { 940 if p.maxGap.Get() >= max { 941 942 break 943 } 944 945 p.maxGap.Set(max) 946 } 947 return 948 } 949 950 for p := n.parent; p != nil; p = p.parent { 951 if p.maxGap.Get() > oldMax { 952 953 break 954 } 955 956 parentNewMax := p.calculateMaxGapInternal() 957 if p.maxGap.Get() == parentNewMax { 958 959 break 960 } 961 962 p.maxGap.Set(parentNewMax) 963 } 964 } 965 966 // updateMaxGapLocal updates maxGap of the calling node solely with no 967 // propagation to ancestor nodes. 968 // 969 // Precondition: trackGaps must be 1. 970 func (n *evictableRangenode) updateMaxGapLocal() { 971 if !n.hasChildren { 972 973 n.maxGap.Set(n.calculateMaxGapLeaf()) 974 } else { 975 976 n.maxGap.Set(n.calculateMaxGapInternal()) 977 } 978 } 979 980 // calculateMaxGapLeaf iterates the gaps within a leaf node and calculate the 981 // max. 982 // 983 // Preconditions: n must be a leaf node. 984 func (n *evictableRangenode) calculateMaxGapLeaf() uint64 { 985 max := evictableRangeGapIterator{n, 0}.Range().Length() 986 for i := 1; i <= n.nrSegments; i++ { 987 if current := (evictableRangeGapIterator{n, i}).Range().Length(); current > max { 988 max = current 989 } 990 } 991 return max 992 } 993 994 // calculateMaxGapInternal iterates children's maxGap within an internal node n 995 // and calculate the max. 996 // 997 // Preconditions: n must be a non-leaf node. 998 func (n *evictableRangenode) calculateMaxGapInternal() uint64 { 999 max := n.children[0].maxGap.Get() 1000 for i := 1; i <= n.nrSegments; i++ { 1001 if current := n.children[i].maxGap.Get(); current > max { 1002 max = current 1003 } 1004 } 1005 return max 1006 } 1007 1008 // searchFirstLargeEnoughGap returns the first gap having at least minSize length 1009 // in the subtree rooted by n. If not found, return a terminal gap iterator. 1010 func (n *evictableRangenode) searchFirstLargeEnoughGap(minSize uint64) evictableRangeGapIterator { 1011 if n.maxGap.Get() < minSize { 1012 return evictableRangeGapIterator{} 1013 } 1014 if n.hasChildren { 1015 for i := 0; i <= n.nrSegments; i++ { 1016 if largeEnoughGap := n.children[i].searchFirstLargeEnoughGap(minSize); largeEnoughGap.Ok() { 1017 return largeEnoughGap 1018 } 1019 } 1020 } else { 1021 for i := 0; i <= n.nrSegments; i++ { 1022 currentGap := evictableRangeGapIterator{n, i} 1023 if currentGap.Range().Length() >= minSize { 1024 return currentGap 1025 } 1026 } 1027 } 1028 panic(fmt.Sprintf("invalid maxGap in %v", n)) 1029 } 1030 1031 // searchLastLargeEnoughGap returns the last gap having at least minSize length 1032 // in the subtree rooted by n. If not found, return a terminal gap iterator. 1033 func (n *evictableRangenode) searchLastLargeEnoughGap(minSize uint64) evictableRangeGapIterator { 1034 if n.maxGap.Get() < minSize { 1035 return evictableRangeGapIterator{} 1036 } 1037 if n.hasChildren { 1038 for i := n.nrSegments; i >= 0; i-- { 1039 if largeEnoughGap := n.children[i].searchLastLargeEnoughGap(minSize); largeEnoughGap.Ok() { 1040 return largeEnoughGap 1041 } 1042 } 1043 } else { 1044 for i := n.nrSegments; i >= 0; i-- { 1045 currentGap := evictableRangeGapIterator{n, i} 1046 if currentGap.Range().Length() >= minSize { 1047 return currentGap 1048 } 1049 } 1050 } 1051 panic(fmt.Sprintf("invalid maxGap in %v", n)) 1052 } 1053 1054 // A Iterator is conceptually one of: 1055 // 1056 // - A pointer to a segment in a set; or 1057 // 1058 // - A terminal iterator, which is a sentinel indicating that the end of 1059 // iteration has been reached. 1060 // 1061 // Iterators are copyable values and are meaningfully equality-comparable. The 1062 // zero value of Iterator is a terminal iterator. 1063 // 1064 // Unless otherwise specified, any mutation of a set invalidates all existing 1065 // iterators into the set. 1066 type evictableRangeIterator struct { 1067 // node is the node containing the iterated segment. If the iterator is 1068 // terminal, node is nil. 1069 node *evictableRangenode 1070 1071 // index is the index of the segment in node.keys/values. 1072 index int 1073 } 1074 1075 // Ok returns true if the iterator is not terminal. All other methods are only 1076 // valid for non-terminal iterators. 1077 func (seg evictableRangeIterator) Ok() bool { 1078 return seg.node != nil 1079 } 1080 1081 // Range returns the iterated segment's range key. 1082 func (seg evictableRangeIterator) Range() EvictableRange { 1083 return seg.node.keys[seg.index] 1084 } 1085 1086 // Start is equivalent to Range().Start, but should be preferred if only the 1087 // start of the range is needed. 1088 func (seg evictableRangeIterator) Start() uint64 { 1089 return seg.node.keys[seg.index].Start 1090 } 1091 1092 // End is equivalent to Range().End, but should be preferred if only the end of 1093 // the range is needed. 1094 func (seg evictableRangeIterator) End() uint64 { 1095 return seg.node.keys[seg.index].End 1096 } 1097 1098 // SetRangeUnchecked mutates the iterated segment's range key. This operation 1099 // does not invalidate any iterators. 1100 // 1101 // Preconditions: 1102 // - r.Length() > 0. 1103 // - The new range must not overlap an existing one: 1104 // - If seg.NextSegment().Ok(), then r.end <= seg.NextSegment().Start(). 1105 // - If seg.PrevSegment().Ok(), then r.start >= seg.PrevSegment().End(). 1106 func (seg evictableRangeIterator) SetRangeUnchecked(r EvictableRange) { 1107 seg.node.keys[seg.index] = r 1108 } 1109 1110 // SetRange mutates the iterated segment's range key. If the new range would 1111 // cause the iterated segment to overlap another segment, or if the new range 1112 // is invalid, SetRange panics. This operation does not invalidate any 1113 // iterators. 1114 func (seg evictableRangeIterator) SetRange(r EvictableRange) { 1115 if r.Length() <= 0 { 1116 panic(fmt.Sprintf("invalid segment range %v", r)) 1117 } 1118 if prev := seg.PrevSegment(); prev.Ok() && r.Start < prev.End() { 1119 panic(fmt.Sprintf("new segment range %v overlaps segment range %v", r, prev.Range())) 1120 } 1121 if next := seg.NextSegment(); next.Ok() && r.End > next.Start() { 1122 panic(fmt.Sprintf("new segment range %v overlaps segment range %v", r, next.Range())) 1123 } 1124 seg.SetRangeUnchecked(r) 1125 } 1126 1127 // SetStartUnchecked mutates the iterated segment's start. This operation does 1128 // not invalidate any iterators. 1129 // 1130 // Preconditions: The new start must be valid: 1131 // - start < seg.End() 1132 // - If seg.PrevSegment().Ok(), then start >= seg.PrevSegment().End(). 1133 func (seg evictableRangeIterator) SetStartUnchecked(start uint64) { 1134 seg.node.keys[seg.index].Start = start 1135 } 1136 1137 // SetStart mutates the iterated segment's start. If the new start value would 1138 // cause the iterated segment to overlap another segment, or would result in an 1139 // invalid range, SetStart panics. This operation does not invalidate any 1140 // iterators. 1141 func (seg evictableRangeIterator) SetStart(start uint64) { 1142 if start >= seg.End() { 1143 panic(fmt.Sprintf("new start %v would invalidate segment range %v", start, seg.Range())) 1144 } 1145 if prev := seg.PrevSegment(); prev.Ok() && start < prev.End() { 1146 panic(fmt.Sprintf("new start %v would cause segment range %v to overlap segment range %v", start, seg.Range(), prev.Range())) 1147 } 1148 seg.SetStartUnchecked(start) 1149 } 1150 1151 // SetEndUnchecked mutates the iterated segment's end. This operation does not 1152 // invalidate any iterators. 1153 // 1154 // Preconditions: The new end must be valid: 1155 // - end > seg.Start(). 1156 // - If seg.NextSegment().Ok(), then end <= seg.NextSegment().Start(). 1157 func (seg evictableRangeIterator) SetEndUnchecked(end uint64) { 1158 seg.node.keys[seg.index].End = end 1159 } 1160 1161 // SetEnd mutates the iterated segment's end. If the new end value would cause 1162 // the iterated segment to overlap another segment, or would result in an 1163 // invalid range, SetEnd panics. This operation does not invalidate any 1164 // iterators. 1165 func (seg evictableRangeIterator) SetEnd(end uint64) { 1166 if end <= seg.Start() { 1167 panic(fmt.Sprintf("new end %v would invalidate segment range %v", end, seg.Range())) 1168 } 1169 if next := seg.NextSegment(); next.Ok() && end > next.Start() { 1170 panic(fmt.Sprintf("new end %v would cause segment range %v to overlap segment range %v", end, seg.Range(), next.Range())) 1171 } 1172 seg.SetEndUnchecked(end) 1173 } 1174 1175 // Value returns a copy of the iterated segment's value. 1176 func (seg evictableRangeIterator) Value() evictableRangeSetValue { 1177 return seg.node.values[seg.index] 1178 } 1179 1180 // ValuePtr returns a pointer to the iterated segment's value. The pointer is 1181 // invalidated if the iterator is invalidated. This operation does not 1182 // invalidate any iterators. 1183 func (seg evictableRangeIterator) ValuePtr() *evictableRangeSetValue { 1184 return &seg.node.values[seg.index] 1185 } 1186 1187 // SetValue mutates the iterated segment's value. This operation does not 1188 // invalidate any iterators. 1189 func (seg evictableRangeIterator) SetValue(val evictableRangeSetValue) { 1190 seg.node.values[seg.index] = val 1191 } 1192 1193 // PrevSegment returns the iterated segment's predecessor. If there is no 1194 // preceding segment, PrevSegment returns a terminal iterator. 1195 func (seg evictableRangeIterator) PrevSegment() evictableRangeIterator { 1196 if seg.node.hasChildren { 1197 return seg.node.children[seg.index].lastSegment() 1198 } 1199 if seg.index > 0 { 1200 return evictableRangeIterator{seg.node, seg.index - 1} 1201 } 1202 if seg.node.parent == nil { 1203 return evictableRangeIterator{} 1204 } 1205 return evictableRangesegmentBeforePosition(seg.node.parent, seg.node.parentIndex) 1206 } 1207 1208 // NextSegment returns the iterated segment's successor. If there is no 1209 // succeeding segment, NextSegment returns a terminal iterator. 1210 func (seg evictableRangeIterator) NextSegment() evictableRangeIterator { 1211 if seg.node.hasChildren { 1212 return seg.node.children[seg.index+1].firstSegment() 1213 } 1214 if seg.index < seg.node.nrSegments-1 { 1215 return evictableRangeIterator{seg.node, seg.index + 1} 1216 } 1217 if seg.node.parent == nil { 1218 return evictableRangeIterator{} 1219 } 1220 return evictableRangesegmentAfterPosition(seg.node.parent, seg.node.parentIndex) 1221 } 1222 1223 // PrevGap returns the gap immediately before the iterated segment. 1224 func (seg evictableRangeIterator) PrevGap() evictableRangeGapIterator { 1225 if seg.node.hasChildren { 1226 1227 return seg.node.children[seg.index].lastSegment().NextGap() 1228 } 1229 return evictableRangeGapIterator{seg.node, seg.index} 1230 } 1231 1232 // NextGap returns the gap immediately after the iterated segment. 1233 func (seg evictableRangeIterator) NextGap() evictableRangeGapIterator { 1234 if seg.node.hasChildren { 1235 return seg.node.children[seg.index+1].firstSegment().PrevGap() 1236 } 1237 return evictableRangeGapIterator{seg.node, seg.index + 1} 1238 } 1239 1240 // PrevNonEmpty returns the iterated segment's predecessor if it is adjacent, 1241 // or the gap before the iterated segment otherwise. If seg.Start() == 1242 // Functions.MinKey(), PrevNonEmpty will return two terminal iterators. 1243 // Otherwise, exactly one of the iterators returned by PrevNonEmpty will be 1244 // non-terminal. 1245 func (seg evictableRangeIterator) PrevNonEmpty() (evictableRangeIterator, evictableRangeGapIterator) { 1246 gap := seg.PrevGap() 1247 if gap.Range().Length() != 0 { 1248 return evictableRangeIterator{}, gap 1249 } 1250 return gap.PrevSegment(), evictableRangeGapIterator{} 1251 } 1252 1253 // NextNonEmpty returns the iterated segment's successor if it is adjacent, or 1254 // the gap after the iterated segment otherwise. If seg.End() == 1255 // Functions.MaxKey(), NextNonEmpty will return two terminal iterators. 1256 // Otherwise, exactly one of the iterators returned by NextNonEmpty will be 1257 // non-terminal. 1258 func (seg evictableRangeIterator) NextNonEmpty() (evictableRangeIterator, evictableRangeGapIterator) { 1259 gap := seg.NextGap() 1260 if gap.Range().Length() != 0 { 1261 return evictableRangeIterator{}, gap 1262 } 1263 return gap.NextSegment(), evictableRangeGapIterator{} 1264 } 1265 1266 // A GapIterator is conceptually one of: 1267 // 1268 // - A pointer to a position between two segments, before the first segment, or 1269 // after the last segment in a set, called a *gap*; or 1270 // 1271 // - A terminal iterator, which is a sentinel indicating that the end of 1272 // iteration has been reached. 1273 // 1274 // Note that the gap between two adjacent segments exists (iterators to it are 1275 // non-terminal), but has a length of zero. GapIterator.IsEmpty returns true 1276 // for such gaps. An empty set contains a single gap, spanning the entire range 1277 // of the set's keys. 1278 // 1279 // GapIterators are copyable values and are meaningfully equality-comparable. 1280 // The zero value of GapIterator is a terminal iterator. 1281 // 1282 // Unless otherwise specified, any mutation of a set invalidates all existing 1283 // iterators into the set. 1284 type evictableRangeGapIterator struct { 1285 // The representation of a GapIterator is identical to that of an Iterator, 1286 // except that index corresponds to positions between segments in the same 1287 // way as for node.children (see comment for node.nrSegments). 1288 node *evictableRangenode 1289 index int 1290 } 1291 1292 // Ok returns true if the iterator is not terminal. All other methods are only 1293 // valid for non-terminal iterators. 1294 func (gap evictableRangeGapIterator) Ok() bool { 1295 return gap.node != nil 1296 } 1297 1298 // Range returns the range spanned by the iterated gap. 1299 func (gap evictableRangeGapIterator) Range() EvictableRange { 1300 return EvictableRange{gap.Start(), gap.End()} 1301 } 1302 1303 // Start is equivalent to Range().Start, but should be preferred if only the 1304 // start of the range is needed. 1305 func (gap evictableRangeGapIterator) Start() uint64 { 1306 if ps := gap.PrevSegment(); ps.Ok() { 1307 return ps.End() 1308 } 1309 return evictableRangeSetFunctions{}.MinKey() 1310 } 1311 1312 // End is equivalent to Range().End, but should be preferred if only the end of 1313 // the range is needed. 1314 func (gap evictableRangeGapIterator) End() uint64 { 1315 if ns := gap.NextSegment(); ns.Ok() { 1316 return ns.Start() 1317 } 1318 return evictableRangeSetFunctions{}.MaxKey() 1319 } 1320 1321 // IsEmpty returns true if the iterated gap is empty (that is, the "gap" is 1322 // between two adjacent segments.) 1323 func (gap evictableRangeGapIterator) IsEmpty() bool { 1324 return gap.Range().Length() == 0 1325 } 1326 1327 // PrevSegment returns the segment immediately before the iterated gap. If no 1328 // such segment exists, PrevSegment returns a terminal iterator. 1329 func (gap evictableRangeGapIterator) PrevSegment() evictableRangeIterator { 1330 return evictableRangesegmentBeforePosition(gap.node, gap.index) 1331 } 1332 1333 // NextSegment returns the segment immediately after the iterated gap. If no 1334 // such segment exists, NextSegment returns a terminal iterator. 1335 func (gap evictableRangeGapIterator) NextSegment() evictableRangeIterator { 1336 return evictableRangesegmentAfterPosition(gap.node, gap.index) 1337 } 1338 1339 // PrevGap returns the iterated gap's predecessor. If no such gap exists, 1340 // PrevGap returns a terminal iterator. 1341 func (gap evictableRangeGapIterator) PrevGap() evictableRangeGapIterator { 1342 seg := gap.PrevSegment() 1343 if !seg.Ok() { 1344 return evictableRangeGapIterator{} 1345 } 1346 return seg.PrevGap() 1347 } 1348 1349 // NextGap returns the iterated gap's successor. If no such gap exists, NextGap 1350 // returns a terminal iterator. 1351 func (gap evictableRangeGapIterator) NextGap() evictableRangeGapIterator { 1352 seg := gap.NextSegment() 1353 if !seg.Ok() { 1354 return evictableRangeGapIterator{} 1355 } 1356 return seg.NextGap() 1357 } 1358 1359 // NextLargeEnoughGap returns the iterated gap's first next gap with larger 1360 // length than minSize. If not found, return a terminal gap iterator (does NOT 1361 // include this gap itself). 1362 // 1363 // Precondition: trackGaps must be 1. 1364 func (gap evictableRangeGapIterator) NextLargeEnoughGap(minSize uint64) evictableRangeGapIterator { 1365 if evictableRangetrackGaps != 1 { 1366 panic("set is not tracking gaps") 1367 } 1368 if gap.node != nil && gap.node.hasChildren && gap.index == gap.node.nrSegments { 1369 1370 gap.node = gap.NextSegment().node 1371 gap.index = 0 1372 return gap.nextLargeEnoughGapHelper(minSize) 1373 } 1374 return gap.nextLargeEnoughGapHelper(minSize) 1375 } 1376 1377 // nextLargeEnoughGapHelper is the helper function used by NextLargeEnoughGap 1378 // to do the real recursions. 1379 // 1380 // Preconditions: gap is NOT the trailing gap of a non-leaf node. 1381 func (gap evictableRangeGapIterator) nextLargeEnoughGapHelper(minSize uint64) evictableRangeGapIterator { 1382 1383 for gap.node != nil && 1384 (gap.node.maxGap.Get() < minSize || (!gap.node.hasChildren && gap.index == gap.node.nrSegments)) { 1385 gap.node, gap.index = gap.node.parent, gap.node.parentIndex 1386 } 1387 1388 if gap.node == nil { 1389 return evictableRangeGapIterator{} 1390 } 1391 1392 gap.index++ 1393 for gap.index <= gap.node.nrSegments { 1394 if gap.node.hasChildren { 1395 if largeEnoughGap := gap.node.children[gap.index].searchFirstLargeEnoughGap(minSize); largeEnoughGap.Ok() { 1396 return largeEnoughGap 1397 } 1398 } else { 1399 if gap.Range().Length() >= minSize { 1400 return gap 1401 } 1402 } 1403 gap.index++ 1404 } 1405 gap.node, gap.index = gap.node.parent, gap.node.parentIndex 1406 if gap.node != nil && gap.index == gap.node.nrSegments { 1407 1408 gap.node, gap.index = gap.node.parent, gap.node.parentIndex 1409 } 1410 return gap.nextLargeEnoughGapHelper(minSize) 1411 } 1412 1413 // PrevLargeEnoughGap returns the iterated gap's first prev gap with larger or 1414 // equal length than minSize. If not found, return a terminal gap iterator 1415 // (does NOT include this gap itself). 1416 // 1417 // Precondition: trackGaps must be 1. 1418 func (gap evictableRangeGapIterator) PrevLargeEnoughGap(minSize uint64) evictableRangeGapIterator { 1419 if evictableRangetrackGaps != 1 { 1420 panic("set is not tracking gaps") 1421 } 1422 if gap.node != nil && gap.node.hasChildren && gap.index == 0 { 1423 1424 gap.node = gap.PrevSegment().node 1425 gap.index = gap.node.nrSegments 1426 return gap.prevLargeEnoughGapHelper(minSize) 1427 } 1428 return gap.prevLargeEnoughGapHelper(minSize) 1429 } 1430 1431 // prevLargeEnoughGapHelper is the helper function used by PrevLargeEnoughGap 1432 // to do the real recursions. 1433 // 1434 // Preconditions: gap is NOT the first gap of a non-leaf node. 1435 func (gap evictableRangeGapIterator) prevLargeEnoughGapHelper(minSize uint64) evictableRangeGapIterator { 1436 1437 for gap.node != nil && 1438 (gap.node.maxGap.Get() < minSize || (!gap.node.hasChildren && gap.index == 0)) { 1439 gap.node, gap.index = gap.node.parent, gap.node.parentIndex 1440 } 1441 1442 if gap.node == nil { 1443 return evictableRangeGapIterator{} 1444 } 1445 1446 gap.index-- 1447 for gap.index >= 0 { 1448 if gap.node.hasChildren { 1449 if largeEnoughGap := gap.node.children[gap.index].searchLastLargeEnoughGap(minSize); largeEnoughGap.Ok() { 1450 return largeEnoughGap 1451 } 1452 } else { 1453 if gap.Range().Length() >= minSize { 1454 return gap 1455 } 1456 } 1457 gap.index-- 1458 } 1459 gap.node, gap.index = gap.node.parent, gap.node.parentIndex 1460 if gap.node != nil && gap.index == 0 { 1461 1462 gap.node, gap.index = gap.node.parent, gap.node.parentIndex 1463 } 1464 return gap.prevLargeEnoughGapHelper(minSize) 1465 } 1466 1467 // segmentBeforePosition returns the predecessor segment of the position given 1468 // by n.children[i], which may or may not contain a child. If no such segment 1469 // exists, segmentBeforePosition returns a terminal iterator. 1470 func evictableRangesegmentBeforePosition(n *evictableRangenode, i int) evictableRangeIterator { 1471 for i == 0 { 1472 if n.parent == nil { 1473 return evictableRangeIterator{} 1474 } 1475 n, i = n.parent, n.parentIndex 1476 } 1477 return evictableRangeIterator{n, i - 1} 1478 } 1479 1480 // segmentAfterPosition returns the successor segment of the position given by 1481 // n.children[i], which may or may not contain a child. If no such segment 1482 // exists, segmentAfterPosition returns a terminal iterator. 1483 func evictableRangesegmentAfterPosition(n *evictableRangenode, i int) evictableRangeIterator { 1484 for i == n.nrSegments { 1485 if n.parent == nil { 1486 return evictableRangeIterator{} 1487 } 1488 n, i = n.parent, n.parentIndex 1489 } 1490 return evictableRangeIterator{n, i} 1491 } 1492 1493 func evictableRangezeroValueSlice(slice []evictableRangeSetValue) { 1494 1495 for i := range slice { 1496 evictableRangeSetFunctions{}.ClearValue(&slice[i]) 1497 } 1498 } 1499 1500 func evictableRangezeroNodeSlice(slice []*evictableRangenode) { 1501 for i := range slice { 1502 slice[i] = nil 1503 } 1504 } 1505 1506 // String stringifies a Set for debugging. 1507 func (s *evictableRangeSet) String() string { 1508 return s.root.String() 1509 } 1510 1511 // String stringifies a node (and all of its children) for debugging. 1512 func (n *evictableRangenode) String() string { 1513 var buf bytes.Buffer 1514 n.writeDebugString(&buf, "") 1515 return buf.String() 1516 } 1517 1518 func (n *evictableRangenode) writeDebugString(buf *bytes.Buffer, prefix string) { 1519 if n.hasChildren != (n.nrSegments > 0 && n.children[0] != nil) { 1520 buf.WriteString(prefix) 1521 buf.WriteString(fmt.Sprintf("WARNING: inconsistent value of hasChildren: got %v, want %v\n", n.hasChildren, !n.hasChildren)) 1522 } 1523 for i := 0; i < n.nrSegments; i++ { 1524 if child := n.children[i]; child != nil { 1525 cprefix := fmt.Sprintf("%s- % 3d ", prefix, i) 1526 if child.parent != n || child.parentIndex != i { 1527 buf.WriteString(cprefix) 1528 buf.WriteString(fmt.Sprintf("WARNING: inconsistent linkage to parent: got (%p, %d), want (%p, %d)\n", child.parent, child.parentIndex, n, i)) 1529 } 1530 child.writeDebugString(buf, fmt.Sprintf("%s- % 3d ", prefix, i)) 1531 } 1532 buf.WriteString(prefix) 1533 if n.hasChildren { 1534 if evictableRangetrackGaps != 0 { 1535 buf.WriteString(fmt.Sprintf("- % 3d: %v => %v, maxGap: %d\n", i, n.keys[i], n.values[i], n.maxGap.Get())) 1536 } else { 1537 buf.WriteString(fmt.Sprintf("- % 3d: %v => %v\n", i, n.keys[i], n.values[i])) 1538 } 1539 } else { 1540 buf.WriteString(fmt.Sprintf("- % 3d: %v => %v\n", i, n.keys[i], n.values[i])) 1541 } 1542 } 1543 if child := n.children[n.nrSegments]; child != nil { 1544 child.writeDebugString(buf, fmt.Sprintf("%s- % 3d ", prefix, n.nrSegments)) 1545 } 1546 } 1547 1548 // SegmentDataSlices represents segments from a set as slices of start, end, and 1549 // values. SegmentDataSlices is primarily used as an intermediate representation 1550 // for save/restore and the layout here is optimized for that. 1551 // 1552 // +stateify savable 1553 type evictableRangeSegmentDataSlices struct { 1554 Start []uint64 1555 End []uint64 1556 Values []evictableRangeSetValue 1557 } 1558 1559 // ExportSortedSlices returns a copy of all segments in the given set, in 1560 // ascending key order. 1561 func (s *evictableRangeSet) ExportSortedSlices() *evictableRangeSegmentDataSlices { 1562 var sds evictableRangeSegmentDataSlices 1563 for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() { 1564 sds.Start = append(sds.Start, seg.Start()) 1565 sds.End = append(sds.End, seg.End()) 1566 sds.Values = append(sds.Values, seg.Value()) 1567 } 1568 sds.Start = sds.Start[:len(sds.Start):len(sds.Start)] 1569 sds.End = sds.End[:len(sds.End):len(sds.End)] 1570 sds.Values = sds.Values[:len(sds.Values):len(sds.Values)] 1571 return &sds 1572 } 1573 1574 // ImportSortedSlices initializes the given set from the given slice. 1575 // 1576 // Preconditions: 1577 // - s must be empty. 1578 // - sds must represent a valid set (the segments in sds must have valid 1579 // lengths that do not overlap). 1580 // - The segments in sds must be sorted in ascending key order. 1581 func (s *evictableRangeSet) ImportSortedSlices(sds *evictableRangeSegmentDataSlices) error { 1582 if !s.IsEmpty() { 1583 return fmt.Errorf("cannot import into non-empty set %v", s) 1584 } 1585 gap := s.FirstGap() 1586 for i := range sds.Start { 1587 r := EvictableRange{sds.Start[i], sds.End[i]} 1588 if !gap.Range().IsSupersetOf(r) { 1589 return fmt.Errorf("segment overlaps a preceding segment or is incorrectly sorted: [%d, %d) => %v", sds.Start[i], sds.End[i], sds.Values[i]) 1590 } 1591 gap = s.InsertWithoutMerging(gap, r, sds.Values[i]).NextGap() 1592 } 1593 return nil 1594 } 1595 1596 // segmentTestCheck returns an error if s is incorrectly sorted, does not 1597 // contain exactly expectedSegments segments, or contains a segment which 1598 // fails the passed check. 1599 // 1600 // This should be used only for testing, and has been added to this package for 1601 // templating convenience. 1602 func (s *evictableRangeSet) segmentTestCheck(expectedSegments int, segFunc func(int, EvictableRange, evictableRangeSetValue) error) error { 1603 havePrev := false 1604 prev := uint64(0) 1605 nrSegments := 0 1606 for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() { 1607 next := seg.Start() 1608 if havePrev && prev >= next { 1609 return fmt.Errorf("incorrect order: key %d (segment %d) >= key %d (segment %d)", prev, nrSegments-1, next, nrSegments) 1610 } 1611 if segFunc != nil { 1612 if err := segFunc(nrSegments, seg.Range(), seg.Value()); err != nil { 1613 return err 1614 } 1615 } 1616 prev = next 1617 havePrev = true 1618 nrSegments++ 1619 } 1620 if nrSegments != expectedSegments { 1621 return fmt.Errorf("incorrect number of segments: got %d, wanted %d", nrSegments, expectedSegments) 1622 } 1623 return nil 1624 } 1625 1626 // countSegments counts the number of segments in the set. 1627 // 1628 // Similar to Check, this should only be used for testing. 1629 func (s *evictableRangeSet) countSegments() (segments int) { 1630 for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() { 1631 segments++ 1632 } 1633 return segments 1634 } 1635 func (s *evictableRangeSet) saveRoot() *evictableRangeSegmentDataSlices { 1636 return s.ExportSortedSlices() 1637 } 1638 1639 func (s *evictableRangeSet) loadRoot(sds *evictableRangeSegmentDataSlices) { 1640 if err := s.ImportSortedSlices(sds); err != nil { 1641 panic(err) 1642 } 1643 }