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