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  }