github.com/biogo/store@v0.0.0-20201120204734-aad293a2328f/interval/int_interval.go (about) 1 // Copyright ©2012 The bíogo Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package interval 6 7 import ( 8 "github.com/biogo/store/llrb" 9 ) 10 11 // An IntOverlapper can determine whether it overlaps an integer range. 12 type IntOverlapper interface { 13 // Overlap returns a boolean indicating whether the receiver overlaps a range. 14 Overlap(IntRange) bool 15 } 16 17 // An IntRange is a type that describes the basic characteristics of an interval over the 18 // integer number line. 19 type IntRange struct { 20 Start, End int 21 } 22 23 // An IntInterface is a type that can be inserted into a IntTree. 24 type IntInterface interface { 25 IntOverlapper 26 Range() IntRange 27 ID() uintptr // Returns a unique ID for the element. 28 } 29 30 // A IntNode represents a node in an IntTree. 31 type IntNode struct { 32 Elem IntInterface 33 Interval IntRange 34 Range IntRange 35 Left, Right *IntNode 36 Color llrb.Color 37 } 38 39 // A IntTree manages the root node of an integer line interval tree. 40 // Public methods are exposed through this type. 41 type IntTree struct { 42 Root *IntNode // Root node of the tree. 43 Count int // Number of elements stored. 44 } 45 46 // Helper methods 47 48 // color returns the effect color of a IntNode. A nil node returns black. 49 func (n *IntNode) color() llrb.Color { 50 if n == nil { 51 return llrb.Black 52 } 53 return n.Color 54 } 55 56 // intMaxRange returns the furthest right position held by the subtree 57 // rooted at root, assuming that the left and right nodes have correct 58 // range extents. 59 func intMaxRange(root, left, right *IntNode) int { 60 end := root.Interval.End 61 if left != nil && left.Range.End > end { 62 end = left.Range.End 63 } 64 if right != nil && right.Range.End > end { 65 end = right.Range.End 66 } 67 return end 68 } 69 70 // (a,c)b -rotL-> ((a,)b,)c 71 func (n *IntNode) rotateLeft() (root *IntNode) { 72 // Assumes: n has a right child. 73 root = n.Right 74 n.Right = root.Left 75 root.Left = n 76 root.Color = n.Color 77 n.Color = llrb.Red 78 79 root.Left.Range.End = intMaxRange(root.Left, root.Left.Left, root.Left.Right) 80 if root.Left == nil { 81 root.Range.Start = root.Interval.Start 82 } else { 83 root.Range.Start = root.Left.Range.Start 84 } 85 root.Range.End = intMaxRange(root, root.Left, root.Right) 86 87 return 88 } 89 90 // (a,c)b -rotR-> (,(,c)b)a 91 func (n *IntNode) rotateRight() (root *IntNode) { 92 // Assumes: n has a left child. 93 root = n.Left 94 n.Left = root.Right 95 root.Right = n 96 root.Color = n.Color 97 n.Color = llrb.Red 98 99 if root.Right.Left == nil { 100 root.Right.Range.Start = root.Right.Interval.Start 101 } else { 102 root.Right.Range.Start = root.Right.Left.Range.Start 103 } 104 root.Right.Range.End = intMaxRange(root.Right, root.Right.Left, root.Right.Right) 105 root.Range.End = intMaxRange(root, root.Left, root.Right) 106 107 return 108 } 109 110 // (aR,cR)bB -flipC-> (aB,cB)bR | (aB,cB)bR -flipC-> (aR,cR)bB 111 func (n *IntNode) flipColors() { 112 // Assumes: n has two children. 113 n.Color = !n.Color 114 n.Left.Color = !n.Left.Color 115 n.Right.Color = !n.Right.Color 116 } 117 118 // fixUp ensures that black link balance is correct, that red nodes lean left, 119 // and that 4 nodes are split in the case of BU23 and properly balanced in TD234. 120 func (n *IntNode) fixUp(fast bool) *IntNode { 121 if !fast { 122 n.adjustRange() 123 } 124 if n.Right.color() == llrb.Red { 125 if Mode == TD234 && n.Right.Left.color() == llrb.Red { 126 n.Right = n.Right.rotateRight() 127 } 128 n = n.rotateLeft() 129 } 130 if n.Left.color() == llrb.Red && n.Left.Left.color() == llrb.Red { 131 n = n.rotateRight() 132 } 133 if Mode == BU23 && n.Left.color() == llrb.Red && n.Right.color() == llrb.Red { 134 n.flipColors() 135 } 136 137 return n 138 } 139 140 // adjustRange sets the Range to the maximum extent of the childrens' Range 141 // spans and the node's Elem span. 142 func (n *IntNode) adjustRange() { 143 if n.Left == nil { 144 n.Range.Start = n.Interval.Start 145 } else { 146 n.Range.Start = n.Left.Range.Start 147 } 148 n.Range.End = intMaxRange(n, n.Left, n.Right) 149 } 150 151 func (n *IntNode) moveRedLeft() *IntNode { 152 n.flipColors() 153 if n.Right.Left.color() == llrb.Red { 154 n.Right = n.Right.rotateRight() 155 n = n.rotateLeft() 156 n.flipColors() 157 if Mode == TD234 && n.Right.Right.color() == llrb.Red { 158 n.Right = n.Right.rotateLeft() 159 } 160 } 161 return n 162 } 163 164 func (n *IntNode) moveRedRight() *IntNode { 165 n.flipColors() 166 if n.Left.Left.color() == llrb.Red { 167 n = n.rotateRight() 168 n.flipColors() 169 } 170 return n 171 } 172 173 // Len returns the number of intervals stored in the IntTree. 174 func (t *IntTree) Len() int { 175 return t.Count 176 } 177 178 // Get returns a slice of IntInterfaces that overlap q in the IntTree according 179 // to q.Overlap(). 180 func (t *IntTree) Get(q IntOverlapper) (o []IntInterface) { 181 if t.Root != nil && q.Overlap(t.Root.Range) { 182 t.Root.doMatch(func(e IntInterface) (done bool) { o = append(o, e); return }, q) 183 } 184 return 185 } 186 187 // AdjustRanges fixes range fields for all IntNodes in the IntTree. This must be called 188 // before Get or DoMatching* is used if fast insertion or deletion has been performed. 189 func (t *IntTree) AdjustRanges() { 190 if t.Root == nil { 191 return 192 } 193 t.Root.adjustRanges() 194 } 195 196 func (n *IntNode) adjustRanges() { 197 if n.Left != nil { 198 n.Left.adjustRanges() 199 } 200 if n.Right != nil { 201 n.Right.adjustRanges() 202 } 203 n.adjustRange() 204 } 205 206 // Insert inserts the IntInterface e into the IntTree. Insertions may replace 207 // existing stored intervals. 208 func (t *IntTree) Insert(e IntInterface, fast bool) (err error) { 209 if r := e.Range(); r.Start > r.End { 210 return ErrInvertedRange 211 } 212 var d int 213 t.Root, d = t.Root.insert(e, e.Range(), e.ID(), fast) 214 t.Count += d 215 t.Root.Color = llrb.Black 216 return 217 } 218 219 func (n *IntNode) insert(e IntInterface, r IntRange, id uintptr, fast bool) (root *IntNode, d int) { 220 if n == nil { 221 return &IntNode{Elem: e, Interval: r, Range: r}, 1 222 } else if n.Elem == nil { 223 n.Elem = e 224 n.Interval = r 225 if !fast { 226 n.adjustRange() 227 } 228 return n, 1 229 } 230 231 if Mode == TD234 { 232 if n.Left.color() == llrb.Red && n.Right.color() == llrb.Red { 233 n.flipColors() 234 } 235 } 236 237 switch c := r.Start - n.Interval.Start; { 238 case c == 0: 239 switch { 240 case id == n.Elem.ID(): 241 n.Elem = e 242 n.Interval = r 243 if !fast { 244 n.Range.End = r.End 245 } 246 case id < n.Elem.ID(): 247 n.Left, d = n.Left.insert(e, r, id, fast) 248 default: 249 n.Right, d = n.Right.insert(e, r, id, fast) 250 } 251 case c < 0: 252 n.Left, d = n.Left.insert(e, r, id, fast) 253 default: 254 n.Right, d = n.Right.insert(e, r, id, fast) 255 } 256 257 if n.Right.color() == llrb.Red && n.Left.color() == llrb.Black { 258 n = n.rotateLeft() 259 } 260 if n.Left.color() == llrb.Red && n.Left.Left.color() == llrb.Red { 261 n = n.rotateRight() 262 } 263 264 if Mode == BU23 { 265 if n.Left.color() == llrb.Red && n.Right.color() == llrb.Red { 266 n.flipColors() 267 } 268 } 269 270 if !fast { 271 n.adjustRange() 272 } 273 root = n 274 275 return 276 } 277 278 // DeleteMin deletes the left-most interval. 279 func (t *IntTree) DeleteMin(fast bool) { 280 if t.Root == nil { 281 return 282 } 283 var d int 284 t.Root, d = t.Root.deleteMin(fast) 285 t.Count += d 286 if t.Root == nil { 287 return 288 } 289 t.Root.Color = llrb.Black 290 } 291 292 func (n *IntNode) deleteMin(fast bool) (root *IntNode, d int) { 293 if n.Left == nil { 294 return nil, -1 295 } 296 if n.Left.color() == llrb.Black && n.Left.Left.color() == llrb.Black { 297 n = n.moveRedLeft() 298 } 299 n.Left, d = n.Left.deleteMin(fast) 300 if n.Left == nil { 301 n.Range.Start = n.Elem.Range().Start 302 } 303 304 root = n.fixUp(fast) 305 306 return 307 } 308 309 // DeleteMax deletes the right-most interval. 310 func (t *IntTree) DeleteMax(fast bool) { 311 if t.Root == nil { 312 return 313 } 314 var d int 315 t.Root, d = t.Root.deleteMax(fast) 316 t.Count += d 317 if t.Root == nil { 318 return 319 } 320 t.Root.Color = llrb.Black 321 } 322 323 func (n *IntNode) deleteMax(fast bool) (root *IntNode, d int) { 324 if n.Left != nil && n.Left.color() == llrb.Red { 325 n = n.rotateRight() 326 } 327 if n.Right == nil { 328 return nil, -1 329 } 330 if n.Right.color() == llrb.Black && n.Right.Left.color() == llrb.Black { 331 n = n.moveRedRight() 332 } 333 n.Right, d = n.Right.deleteMax(fast) 334 if n.Right == nil { 335 n.Range.End = n.Elem.Range().End 336 } 337 338 root = n.fixUp(fast) 339 340 return 341 } 342 343 // Delete deletes the element e if it exists in the IntTree. 344 func (t *IntTree) Delete(e IntInterface, fast bool) (err error) { 345 if r := e.Range(); r.Start > r.End { 346 return ErrInvertedRange 347 } 348 if t.Root == nil || !e.Overlap(t.Root.Range) { 349 return 350 } 351 var d int 352 t.Root, d = t.Root.delete(e.Range().Start, e.ID(), fast) 353 t.Count += d 354 if t.Root == nil { 355 return 356 } 357 t.Root.Color = llrb.Black 358 return 359 } 360 361 func (n *IntNode) delete(m int, id uintptr, fast bool) (root *IntNode, d int) { 362 if p := m - n.Interval.Start; p < 0 || (p == 0 && id < n.Elem.ID()) { 363 if n.Left != nil { 364 if n.Left.color() == llrb.Black && n.Left.Left.color() == llrb.Black { 365 n = n.moveRedLeft() 366 } 367 n.Left, d = n.Left.delete(m, id, fast) 368 if n.Left == nil { 369 n.Range.Start = n.Interval.Start 370 } 371 } 372 } else { 373 if n.Left.color() == llrb.Red { 374 n = n.rotateRight() 375 } 376 if n.Right == nil && id == n.Elem.ID() { 377 return nil, -1 378 } 379 if n.Right != nil { 380 if n.Right.color() == llrb.Black && n.Right.Left.color() == llrb.Black { 381 n = n.moveRedRight() 382 } 383 if id == n.Elem.ID() { 384 m := n.Right.min() 385 n.Elem = m.Elem 386 n.Interval = m.Interval 387 n.Right, d = n.Right.deleteMin(fast) 388 } else { 389 n.Right, d = n.Right.delete(m, id, fast) 390 } 391 if n.Right == nil { 392 n.Range.End = n.Interval.End 393 } 394 } 395 } 396 397 root = n.fixUp(fast) 398 399 return 400 } 401 402 // Return the left-most interval stored in the tree. 403 func (t *IntTree) Min() IntInterface { 404 if t.Root == nil { 405 return nil 406 } 407 return t.Root.min().Elem 408 } 409 410 func (n *IntNode) min() *IntNode { 411 for ; n.Left != nil; n = n.Left { 412 } 413 return n 414 } 415 416 // Return the right-most interval stored in the tree. 417 func (t *IntTree) Max() IntInterface { 418 if t.Root == nil { 419 return nil 420 } 421 return t.Root.max().Elem 422 } 423 424 func (n *IntNode) max() *IntNode { 425 for ; n.Right != nil; n = n.Right { 426 } 427 return n 428 } 429 430 // Floor returns the largest value equal to or less than the query q according to 431 // q.Start().Compare(), with ties broken by comparison of ID() values. 432 func (t *IntTree) Floor(q IntInterface) (o IntInterface, err error) { 433 if t.Root == nil { 434 return 435 } 436 n := t.Root.floor(q.Range().Start, q.ID()) 437 if n == nil { 438 return 439 } 440 return n.Elem, nil 441 } 442 443 func (n *IntNode) floor(m int, id uintptr) *IntNode { 444 if n == nil { 445 return nil 446 } 447 switch c := m - n.Interval.Start; { 448 case c == 0: 449 switch { 450 case id == n.Elem.ID(): 451 return n 452 case id < n.Elem.ID(): 453 return n.Left.floor(m, id) 454 default: 455 if r := n.Right.floor(m, id); r != nil { 456 return r 457 } 458 } 459 case c < 0: 460 return n.Left.floor(m, id) 461 default: 462 if r := n.Right.floor(m, id); r != nil { 463 return r 464 } 465 } 466 return n 467 } 468 469 // Ceil returns the smallest value equal to or greater than the query q according to 470 // q.Start().Compare(), with ties broken by comparison of ID() values. 471 func (t *IntTree) Ceil(q IntInterface) (o IntInterface, err error) { 472 if t.Root == nil { 473 return 474 } 475 n := t.Root.ceil(q.Range().Start, q.ID()) 476 if n == nil { 477 return 478 } 479 return n.Elem, nil 480 } 481 482 func (n *IntNode) ceil(m int, id uintptr) *IntNode { 483 if n == nil { 484 return nil 485 } 486 switch c := m - n.Interval.Start; { 487 case c == 0: 488 switch { 489 case id == n.Elem.ID(): 490 return n 491 case id > n.Elem.ID(): 492 return n.Right.ceil(m, id) 493 default: 494 if l := n.Left.ceil(m, id); l != nil { 495 return l 496 } 497 } 498 case c > 0: 499 return n.Right.ceil(m, id) 500 default: 501 if l := n.Left.ceil(m, id); l != nil { 502 return l 503 } 504 } 505 return n 506 } 507 508 // An IntOperation is a function that operates on an IntInterface. If done is returned true, the 509 // IntOperation is indicating that no further work needs to be done and so the Do function should 510 // traverse no further. 511 type IntOperation func(IntInterface) (done bool) 512 513 // Do performs fn on all intervals stored in the tree. A boolean is returned indicating whether the 514 // Do traversal was interrupted by an IntOperation returning true. If fn alters stored intervals' 515 // end points, future tree operation behaviors are undefined. 516 func (t *IntTree) Do(fn IntOperation) bool { 517 if t.Root == nil { 518 return false 519 } 520 return t.Root.do(fn) 521 } 522 523 func (n *IntNode) do(fn IntOperation) (done bool) { 524 if n.Left != nil { 525 done = n.Left.do(fn) 526 if done { 527 return 528 } 529 } 530 done = fn(n.Elem) 531 if done { 532 return 533 } 534 if n.Right != nil { 535 done = n.Right.do(fn) 536 } 537 return 538 } 539 540 // DoReverse performs fn on all intervals stored in the tree, but in reverse of sort order. A boolean 541 // is returned indicating whether the Do traversal was interrupted by an IntOperation returning true. 542 // If fn alters stored intervals' end points, future tree operation behaviors are undefined. 543 func (t *IntTree) DoReverse(fn IntOperation) bool { 544 if t.Root == nil { 545 return false 546 } 547 return t.Root.doReverse(fn) 548 } 549 550 func (n *IntNode) doReverse(fn IntOperation) (done bool) { 551 if n.Right != nil { 552 done = n.Right.doReverse(fn) 553 if done { 554 return 555 } 556 } 557 done = fn(n.Elem) 558 if done { 559 return 560 } 561 if n.Left != nil { 562 done = n.Left.doReverse(fn) 563 } 564 return 565 } 566 567 // DoMatch performs fn on all intervals stored in the tree that match q according to Overlap, with 568 // q.Overlap() used to guide tree traversal, so DoMatching() will out perform Do() with a called 569 // conditional function if the condition is based on sort order, but can not be reliably used if 570 // the condition is independent of sort order. A boolean is returned indicating whether the Do 571 // traversal was interrupted by an IntOperation returning true. If fn alters stored intervals' end 572 // points, future tree operation behaviors are undefined. 573 func (t *IntTree) DoMatching(fn IntOperation, q IntOverlapper) bool { 574 if t.Root != nil && q.Overlap(t.Root.Range) { 575 return t.Root.doMatch(fn, q) 576 } 577 return false 578 } 579 580 func (n *IntNode) doMatch(fn IntOperation, q IntOverlapper) (done bool) { 581 if n.Left != nil && q.Overlap(n.Left.Range) { 582 done = n.Left.doMatch(fn, q) 583 if done { 584 return 585 } 586 } 587 if q.Overlap(n.Interval) { 588 done = fn(n.Elem) 589 if done { 590 return 591 } 592 } 593 if n.Right != nil && q.Overlap(n.Right.Range) { 594 done = n.Right.doMatch(fn, q) 595 } 596 return 597 } 598 599 // DoMatchReverse performs fn on all intervals stored in the tree that match q according to Overlap, 600 // with q.Overlap() used to guide tree traversal, so DoMatching() will out perform Do() with a called 601 // conditional function if the condition is based on sort order, but can not be reliably used if 602 // the condition is independent of sort order. A boolean is returned indicating whether the Do 603 // traversal was interrupted by an IntOperation returning true. If fn alters stored intervals' end 604 // points, future tree operation behaviors are undefined. 605 func (t *IntTree) DoMatchingReverse(fn IntOperation, q IntOverlapper) bool { 606 if t.Root != nil && q.Overlap(t.Root.Range) { 607 return t.Root.doMatch(fn, q) 608 } 609 return false 610 } 611 612 func (n *IntNode) doMatchReverse(fn IntOperation, q IntOverlapper) (done bool) { 613 if n.Right != nil && q.Overlap(n.Right.Range) { 614 done = n.Right.doMatchReverse(fn, q) 615 if done { 616 return 617 } 618 } 619 if q.Overlap(n.Interval) { 620 done = fn(n.Elem) 621 if done { 622 return 623 } 624 } 625 if n.Left != nil && q.Overlap(n.Left.Range) { 626 done = n.Left.doMatchReverse(fn, q) 627 } 628 return 629 }