github.com/biogo/store@v0.0.0-20201120204734-aad293a2328f/interval/interval_test.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  	"flag"
     9  	"fmt"
    10  	"math/rand"
    11  	"os"
    12  	"strings"
    13  	"testing"
    14  	"unsafe"
    15  
    16  	"gopkg.in/check.v1"
    17  
    18  	"github.com/biogo/store/llrb"
    19  )
    20  
    21  var (
    22  	printTree = flag.Bool("trees", false, "Print failing tree in Newick format.")
    23  	genDot    = flag.Bool("dot", false, "Generate dot code for failing trees.")
    24  	dotLimit  = flag.Int("dotmax", 100, "Maximum size for tree output for dot format.")
    25  )
    26  
    27  // Integrity checks - translated from http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
    28  
    29  // Is this tree a BST?
    30  func (t *Tree) isBST() bool {
    31  	if t == nil {
    32  		return true
    33  	}
    34  	return t.Root.isBST(t.Min(), t.Max())
    35  }
    36  
    37  // Are all the values in the BST rooted at x between min and max,
    38  // and does the same property hold for both subtrees?
    39  func (n *Node) isBST(min, max Interface) bool {
    40  	if n == nil {
    41  		return true
    42  	}
    43  	if n.Elem.Start().Compare(min.Start()) < 0 || n.Elem.Start().Compare(max.Start()) > 0 {
    44  		return false
    45  	}
    46  	return n.Left.isBST(min, n.Elem) || n.Right.isBST(n.Elem, max)
    47  }
    48  
    49  // Test BU and TD234 invariants.
    50  func (t *Tree) is23_234() bool {
    51  	if t == nil {
    52  		return true
    53  	}
    54  	return t.Root.is23_234()
    55  }
    56  func (n *Node) is23_234() bool {
    57  	if n == nil {
    58  		return true
    59  	}
    60  	if Mode == BU23 {
    61  		// If the node has two children, only one of them may be red.
    62  		// The other must be black...
    63  		if (n.Left != nil) && (n.Right != nil) {
    64  			if n.Left.color() == llrb.Red && n.Right.color() == llrb.Red {
    65  				return false
    66  			}
    67  		}
    68  		// and the red node should really should be the left one.
    69  		if n.Right.color() == llrb.Red {
    70  			return false
    71  		}
    72  	} else if Mode == TD234 {
    73  		// This test is altered from that shown in the java since the trees
    74  		// shown in the paper do not conform to the test as it existed and the
    75  		// current situation does not break the 2-3-4 definition of the LLRB.
    76  		if n.Right.color() == llrb.Red && n.Left.color() == llrb.Black {
    77  			return false
    78  		}
    79  	} else {
    80  		panic("cannot reach")
    81  	}
    82  	if n.color() == llrb.Red && n.Left.color() == llrb.Red {
    83  		return false
    84  	}
    85  	return n.Left.is23_234() && n.Right.is23_234()
    86  }
    87  
    88  // Do all paths from root to leaf have same number of black edges?
    89  func (t *Tree) isBalanced() bool {
    90  	if t == nil {
    91  		return true
    92  	}
    93  	var black int // number of black links on path from root to min
    94  	for x := t.Root; x != nil; x = x.Left {
    95  		if x.color() == llrb.Black {
    96  			black++
    97  		}
    98  	}
    99  	return t.Root.isBalanced(black)
   100  }
   101  
   102  // Does every path from the root to a leaf have the given number
   103  // of black links?
   104  func (n *Node) isBalanced(black int) bool {
   105  	if n == nil && black == 0 {
   106  		return true
   107  	} else if n == nil && black != 0 {
   108  		return false
   109  	}
   110  	if n.color() == llrb.Black {
   111  		black--
   112  	}
   113  	return n.Left.isBalanced(black) && n.Right.isBalanced(black)
   114  }
   115  
   116  // Does every node correctly annotate the range of its children.
   117  func (t *Tree) isRanged() bool {
   118  	if t == nil {
   119  		return true
   120  	}
   121  	return t.Root.isRanged()
   122  }
   123  func (n *Node) isRanged() bool {
   124  	if n == nil {
   125  		return true
   126  	}
   127  	e, r := n.Elem, n.Range
   128  	m := n.bounding(&overlap{start: e.Start().(compInt), end: e.End().(compInt)})
   129  	return m.Start().Compare(r.Start()) == 0 && m.End().Compare(r.End()) == 0 &&
   130  		n.Left.isRanged() &&
   131  		n.Right.isRanged()
   132  }
   133  func (n *Node) bounding(m Mutable) Mutable {
   134  	m.SetStart(min(n.Elem.Start(), m.Start()))
   135  	m.SetEnd(max(n.Elem.End(), m.End()))
   136  	if n.Left != nil {
   137  		m = n.Left.bounding(m)
   138  	}
   139  	if n.Right != nil {
   140  		m = n.Right.bounding(m)
   141  	}
   142  	return m
   143  }
   144  
   145  // Test helpers
   146  
   147  type overRune rune
   148  
   149  func (or overRune) Compare(b Comparable) int {
   150  	return int(or) - int(b.(overRune))
   151  }
   152  func (or overRune) Overlap(b Range) bool {
   153  	return or == b.(overRune)
   154  }
   155  func (or overRune) ID() uintptr           { return uintptr(or) } // Not semantically satisfying interface, but not used.
   156  func (or overRune) Start() Comparable     { return or }
   157  func (or overRune) End() Comparable       { return or }
   158  func (or overRune) SetStart(_ Comparable) {}
   159  func (or overRune) SetEnd(_ Comparable)   {}
   160  func (or overRune) NewMutable() Mutable   { return or }
   161  
   162  type compInt int
   163  
   164  func (or compInt) Compare(b Comparable) int {
   165  	return int(or - b.(compInt))
   166  }
   167  
   168  type overlap struct {
   169  	start, end compInt
   170  	id         uintptr
   171  }
   172  
   173  func (o *overlap) Overlap(b Range) bool {
   174  	bc := b.(*overlap)
   175  	return o.end > bc.start && o.start < bc.end
   176  }
   177  func (o *overlap) ID() uintptr           { return o.id }
   178  func (o *overlap) Start() Comparable     { return o.start }
   179  func (o *overlap) End() Comparable       { return o.end }
   180  func (o *overlap) SetStart(c Comparable) { o.start = c.(compInt) }
   181  func (o *overlap) SetEnd(c Comparable)   { o.end = c.(compInt) }
   182  func (o *overlap) NewMutable() Mutable   { return &overlap{o.start, o.end, o.id} }
   183  func (o *overlap) String() string        { return fmt.Sprintf("[%d,%d)", o.start, o.end) }
   184  
   185  // Build a tree from a simplified Newick format returning the root node.
   186  // Single letter node names only, no error checking and all nodes are full or leaf.
   187  func makeTree(desc string) (n *Node) {
   188  	var build func([]rune) (*Node, int)
   189  	build = func(desc []rune) (cn *Node, i int) {
   190  		if len(desc) == 0 || desc[0] == ';' {
   191  			return nil, 0
   192  		}
   193  
   194  		var c int
   195  		cn = &Node{}
   196  		for {
   197  			b := desc[i]
   198  			i++
   199  			if b == '(' {
   200  				cn.Left, c = build(desc[i:])
   201  				i += c
   202  				continue
   203  			}
   204  			if b == ',' {
   205  				cn.Right, c = build(desc[i:])
   206  				i += c
   207  				continue
   208  			}
   209  			if b == ')' {
   210  				if cn.Left == nil && cn.Right == nil {
   211  					return nil, i
   212  				}
   213  				continue
   214  			}
   215  			if b != ';' {
   216  				cn.Elem = overRune(b)
   217  				cn.Range = overRune(b)
   218  			}
   219  			return cn, i
   220  		}
   221  
   222  		panic("cannot reach")
   223  	}
   224  
   225  	n, _ = build([]rune(desc))
   226  	if n.Left == nil && n.Right == nil {
   227  		n = nil
   228  	}
   229  
   230  	return
   231  }
   232  
   233  // Return a Newick format description of a tree defined by a node
   234  func (n *Node) describeTree(char, color bool) string {
   235  	s := []rune(nil)
   236  
   237  	var follow func(*Node)
   238  	follow = func(n *Node) {
   239  		children := n.Left != nil || n.Right != nil
   240  		if children {
   241  			s = append(s, '(')
   242  		}
   243  		if n.Left != nil {
   244  			follow(n.Left)
   245  		}
   246  		if children {
   247  			s = append(s, ',')
   248  		}
   249  		if n.Right != nil {
   250  			follow(n.Right)
   251  		}
   252  		if children {
   253  			s = append(s, ')')
   254  		}
   255  		if n.Elem != nil {
   256  			if char {
   257  				s = append(s, rune(n.Elem.(overRune)))
   258  			} else {
   259  				s = append(s, []rune(fmt.Sprintf("%d", n.Elem))...)
   260  			}
   261  			if color {
   262  				s = append(s, []rune(fmt.Sprintf(" %v", n.color()))...)
   263  			}
   264  		}
   265  	}
   266  	if n == nil {
   267  		s = []rune("()")
   268  	} else {
   269  		follow(n)
   270  	}
   271  	s = append(s, ';')
   272  
   273  	return string(s)
   274  }
   275  
   276  func min(a, b Comparable) Comparable {
   277  	if a.Compare(b) < 0 {
   278  		return a
   279  	}
   280  	return b
   281  }
   282  
   283  func max(a, b Comparable) Comparable {
   284  	if a.Compare(b) > 0 {
   285  		return a
   286  	}
   287  	return b
   288  }
   289  
   290  // Tests
   291  func Test(t *testing.T) { check.TestingT(t) }
   292  
   293  type S struct{}
   294  
   295  var _ = check.Suite(&S{})
   296  
   297  func (s *S) SetUpSuite(c *check.C) {
   298  	mode := []string{TD234: "Top-Down 2-3-4", BU23: "Bottom-Up 2-3"}
   299  	fmt.Printf("Testing %s Left-Leaning Red Black Tree interval tree package.\n", mode[Mode])
   300  }
   301  
   302  func (s *S) TestMakeAndDescribeTree(c *check.C) {
   303  	c.Check((*Node)(nil).describeTree(true, false), check.Equals, "();")
   304  	for _, desc := range []string{
   305  		"();",
   306  		"((a,c)b,(e,g)f)d;",
   307  	} {
   308  		t := makeTree(desc)
   309  		c.Check(t.describeTree(true, false), check.Equals, desc)
   310  	}
   311  }
   312  
   313  // ((a,c)b,(e,g)f)d -rotL-> (((a,c)b,e)d,g)f
   314  func (s *S) TestRotateLeft(c *check.C) {
   315  	orig := "((a,c)b,(e,g)f)d;"
   316  	rot := "(((a,c)b,e)d,g)f;"
   317  
   318  	tree := makeTree(orig)
   319  
   320  	tree = tree.rotateLeft()
   321  	c.Check(tree.describeTree(true, false), check.Equals, rot)
   322  
   323  	rotTree := makeTree(rot)
   324  	c.Check(tree, check.DeepEquals, rotTree)
   325  }
   326  
   327  // ((a,c)b,(e,g)f)d -rotR-> (a,(c,(e,g)f)d)b
   328  func (s *S) TestRotateRight(c *check.C) {
   329  	orig := "((a,c)b,(e,g)f)d;"
   330  	rot := "(a,(c,(e,g)f)d)b;"
   331  
   332  	tree := makeTree(orig)
   333  
   334  	tree = tree.rotateRight()
   335  	c.Check(tree.describeTree(true, false), check.Equals, rot)
   336  
   337  	rotTree := makeTree(rot)
   338  	c.Check(tree, check.DeepEquals, rotTree)
   339  }
   340  
   341  func (s *S) TestNilOperations(c *check.C) {
   342  	t := &Tree{}
   343  	c.Check(t.Min(), check.Equals, nil)
   344  	c.Check(t.Max(), check.Equals, nil)
   345  	if Mode == TD234 {
   346  		return
   347  	}
   348  	t.DeleteMin(false)
   349  	c.Check(*t, check.Equals, Tree{})
   350  	t.DeleteMax(false)
   351  	c.Check(*t, check.Equals, Tree{})
   352  }
   353  
   354  func (s *S) TestRange(c *check.C) {
   355  	t := &Tree{}
   356  	for i, iv := range []*overlap{
   357  		{0, 2, 0},
   358  		{2, 4, 0},
   359  		{1, 6, 0},
   360  		{3, 4, 0},
   361  		{1, 3, 0},
   362  		{4, 6, 0},
   363  		{5, 8, 0},
   364  		{6, 8, 0},
   365  		{5, 9, 0},
   366  	} {
   367  		t.Insert(iv, false)
   368  		ok := c.Check(t.isRanged(), check.Equals, true, check.Commentf("insertion %d: %v", i, iv))
   369  		if !ok && *genDot && t.Len() <= *dotLimit {
   370  			err := t.dotFile(fmt.Sprintf("TestRange_%d", i), "")
   371  			if err != nil {
   372  				c.Errorf("Dot file write failed: %v", err)
   373  			}
   374  		}
   375  	}
   376  }
   377  
   378  func (s *S) TestInsertion(c *check.C) {
   379  	var (
   380  		min, max = compInt(0), compInt(1000)
   381  		t        = &Tree{}
   382  		length   = compInt(100)
   383  	)
   384  	for i := min; i <= max; i++ {
   385  		t.Insert(&overlap{start: i, end: i + length}, false)
   386  		c.Check(t.Len(), check.Equals, int(i+1))
   387  		failed := false
   388  		failed = failed || !c.Check(t.isBST(), check.Equals, true)
   389  		failed = failed || !c.Check(t.is23_234(), check.Equals, true)
   390  		failed = failed || !c.Check(t.isBalanced(), check.Equals, true)
   391  		failed = failed || !c.Check(t.isRanged(), check.Equals, true)
   392  		if failed {
   393  			if *printTree {
   394  				c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   395  			}
   396  			if *genDot && t.Len() <= *dotLimit {
   397  				err := t.dotFile(fmt.Sprintf("TestInsertion_after_ins_%d", i), "")
   398  				if err != nil {
   399  					c.Errorf("Dot file write failed: %v", err)
   400  				}
   401  			}
   402  			c.Fatal("Cannot continue test: invariant contradiction")
   403  		}
   404  	}
   405  	c.Check(t.Min().Start(), check.DeepEquals, min)
   406  	c.Check(t.Max().Start(), check.DeepEquals, max)
   407  }
   408  
   409  func (s *S) TestFastInsertion(c *check.C) {
   410  	var (
   411  		min, max = compInt(0), compInt(1000)
   412  		t        = &Tree{}
   413  		length   = compInt(100)
   414  	)
   415  	for i := min; i <= max; i++ {
   416  		t.Insert(&overlap{start: i, end: i + length}, true)
   417  		c.Check(t.Len(), check.Equals, int(i+1))
   418  		c.Check(t.isBST(), check.Equals, true)
   419  		c.Check(t.is23_234(), check.Equals, true)
   420  		c.Check(t.isBalanced(), check.Equals, true)
   421  	}
   422  	t.AdjustRanges()
   423  	c.Check(t.isRanged(), check.Equals, true)
   424  	c.Check(t.Min().Start(), check.DeepEquals, min)
   425  	c.Check(t.Max().Start(), check.DeepEquals, max)
   426  }
   427  
   428  func (s *S) TestDeletion(c *check.C) {
   429  	var (
   430  		min, max = compInt(0), compInt(1000)
   431  		e        = int(max-min) + 1
   432  		t        = &Tree{}
   433  		length   = compInt(1)
   434  	)
   435  	for i := min; i <= max; i++ {
   436  		t.Insert(&overlap{start: i, end: i + length, id: uintptr(i)}, false)
   437  	}
   438  	for i := min; i <= max; i++ {
   439  		var dotString string
   440  		if o := t.Get(&overlap{start: i, end: i + length}); o != nil {
   441  			e--
   442  		}
   443  		if *genDot && t.Len() <= *dotLimit {
   444  			dotString = t.dot(fmt.Sprintf("TestDeletion_before_del_%d", i))
   445  		}
   446  		t.Delete(&overlap{start: i, end: i + length, id: uintptr(i)}, false)
   447  		c.Check(t.Len(), check.Equals, e)
   448  		if i < max {
   449  			failed := false
   450  			failed = failed || !c.Check(t.isBST(), check.Equals, true)
   451  			failed = failed || !c.Check(t.is23_234(), check.Equals, true)
   452  			failed = failed || !c.Check(t.isBalanced(), check.Equals, true)
   453  			failed = failed || !c.Check(t.isRanged(), check.Equals, true)
   454  			if failed {
   455  				if *printTree {
   456  					c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   457  				}
   458  				if *genDot && t.Len() < *dotLimit {
   459  					var err error
   460  					err = (*Tree)(nil).dotFile(fmt.Sprintf("TestDeletion_before_del_%d", i), dotString)
   461  					if err != nil {
   462  						c.Errorf("Dot file write failed: %v", err)
   463  					}
   464  					err = t.dotFile(fmt.Sprintf("TestDeletion_after_del_%d", i), "")
   465  					if err != nil {
   466  						c.Errorf("Dot file write failed: %v", err)
   467  					}
   468  				}
   469  				c.Fatal("Cannot continue test: invariant contradiction")
   470  			}
   471  		}
   472  	}
   473  	c.Check(*t, check.Equals, Tree{})
   474  }
   475  
   476  func (s *S) TestFastDeletion(c *check.C) {
   477  	var (
   478  		min, max = compInt(0), compInt(1000)
   479  		t        = &Tree{}
   480  		length   = compInt(1)
   481  	)
   482  	for i := min; i <= max; i++ {
   483  		t.Insert(&overlap{start: i, end: i + length, id: uintptr(i)}, false)
   484  	}
   485  	for i := min; i <= max; i++ {
   486  		t.Delete(&overlap{start: i, end: i + length, id: uintptr(i)}, true)
   487  		c.Check(t.isBST(), check.Equals, true)
   488  		c.Check(t.is23_234(), check.Equals, true)
   489  		c.Check(t.isBalanced(), check.Equals, true)
   490  		if i == max/2 {
   491  			t.AdjustRanges()
   492  			c.Check(t.isRanged(), check.Equals, true)
   493  		}
   494  	}
   495  	c.Check(*t, check.Equals, Tree{})
   496  }
   497  
   498  func (s *S) TestGet(c *check.C) {
   499  	var (
   500  		min, max = compInt(0), compInt(1000)
   501  		t        = &Tree{}
   502  	)
   503  	for i := min; i <= max; i++ {
   504  		if i&1 == 0 {
   505  			t.Insert(&overlap{start: i, end: i + 1}, false)
   506  		}
   507  	}
   508  	for i := min; i <= max; i++ {
   509  		if i&1 == 0 {
   510  			o := t.Get(&overlap{start: i, end: i + 1})
   511  			c.Check(len(o), check.Equals, 1)                                // Check inserted elements are present.
   512  			c.Check(o[0], check.DeepEquals, &overlap{start: i, end: i + 1}) // Check inserted elements are correct.
   513  		} else {
   514  			o := t.Get(&overlap{start: i, end: i + 1})
   515  			c.Check(o, check.DeepEquals, []Interface(nil)) // Check inserted elements are absent.
   516  		}
   517  	}
   518  }
   519  
   520  func (s *S) TestFloor(c *check.C) {
   521  	min, max := compInt(0), compInt(1000)
   522  	t := &Tree{}
   523  	for i := min; i <= max; i++ {
   524  		if i&1 == 0 { // Insert even numbers only.
   525  			t.Insert(&overlap{start: i, end: i + 1}, false)
   526  		}
   527  	}
   528  	for i := min; i <= max; i++ {
   529  		l, _ := t.Floor(&overlap{start: i, end: i + 1})
   530  		if i&1 == 0 {
   531  			c.Check(l, check.DeepEquals, &overlap{start: i, end: i + 1}) // Check even Floors are themselves.
   532  		} else {
   533  			c.Check(l, check.DeepEquals, &overlap{start: i - 1, end: i}) // Check odd Floors are the previous number.
   534  		}
   535  	}
   536  	l, _ := t.Floor(&overlap{start: min - 1, end: min})
   537  	c.Check(l, check.DeepEquals, Interface(nil))
   538  }
   539  
   540  func (s *S) TestCeil(c *check.C) {
   541  	min, max := compInt(0), compInt(1000)
   542  	t := &Tree{}
   543  	for i := min; i <= max; i++ {
   544  		if i&1 == 1 { // Insert odd numbers only.
   545  			t.Insert(&overlap{start: i, end: i + 1}, false)
   546  		}
   547  	}
   548  	for i := min; i < max; i++ {
   549  		u, _ := t.Ceil(&overlap{start: i, end: i + 1})
   550  		if i&1 == 1 {
   551  			c.Check(u, check.DeepEquals, &overlap{start: i, end: i + 1}) // Check odd Ceils are themselves.
   552  		} else {
   553  			c.Check(u, check.DeepEquals, &overlap{start: i + 1, end: i + 2}) // Check even Ceils are the next number.
   554  		}
   555  	}
   556  	u, _ := t.Ceil(&overlap{start: max, end: max + 2})
   557  	c.Check(u, check.DeepEquals, Comparable(nil))
   558  }
   559  
   560  func (s *S) TestRandomlyInsertedGet(c *check.C) {
   561  	var (
   562  		count, max = 1000, 1000
   563  		t          = &Tree{}
   564  		length     = compInt(100)
   565  		verify     = map[overlap]struct{}{}
   566  		verified   = map[overlap]struct{}{}
   567  	)
   568  	for i := 0; i < count; i++ {
   569  		s := compInt(rand.Intn(max))
   570  		v := overlap{start: s, end: s + length}
   571  		t.Insert(&v, false)
   572  		verify[v] = struct{}{}
   573  	}
   574  	// Random fetch order.
   575  	for v := range verify {
   576  		o := t.Get(&v)
   577  		c.Check(len(o), check.Not(check.Equals), 0) // Check inserted elements are present.
   578  		for _, iv := range o {
   579  			vr := *iv.(*overlap)
   580  			_, ok := verify[vr]
   581  			c.Check(ok, check.Equals, true, check.Commentf("%v should exist", vr))
   582  			if ok {
   583  				verified[vr] = struct{}{}
   584  			}
   585  		}
   586  	}
   587  	c.Check(len(verify), check.Equals, len(verified))
   588  	for v := range verify {
   589  		_, ok := verified[v]
   590  		c.Check(ok, check.Equals, true, check.Commentf("%v should exist", v))
   591  	}
   592  
   593  	// Check all possible insertions.
   594  	for s := compInt(0); s <= compInt(max); s++ {
   595  		v := overlap{start: s, end: s + length}
   596  		o := t.Get(&v)
   597  		if _, ok := verify[v]; ok {
   598  			c.Check(len(o), check.Not(check.Equals), 0) // Check inserted elements are present.
   599  		}
   600  	}
   601  }
   602  
   603  func (s *S) TestRandomInsertion(c *check.C) {
   604  	var (
   605  		count, max = 1000, 1000
   606  		t          = &Tree{}
   607  		length     = compInt(100)
   608  	)
   609  	for i := 0; i < count; i++ {
   610  		s := compInt(rand.Intn(max))
   611  		v := overlap{start: s, end: s + length}
   612  		t.Insert(&v, false)
   613  		failed := false
   614  		failed = failed || !c.Check(t.isBST(), check.Equals, true)
   615  		failed = failed || !c.Check(t.is23_234(), check.Equals, true)
   616  		failed = failed || !c.Check(t.isBalanced(), check.Equals, true)
   617  		failed = failed || !c.Check(t.isRanged(), check.Equals, true)
   618  		if failed {
   619  			if *printTree {
   620  				c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   621  			}
   622  			if *genDot && t.Len() <= *dotLimit {
   623  				err := t.dotFile(fmt.Sprintf("TestRandomInsertion_after_ins_%d_%d", v.start, v.end), "")
   624  				if err != nil {
   625  					c.Errorf("Dot file write failed: %v", err)
   626  				}
   627  			}
   628  			c.Fatal("Cannot continue test: invariant contradiction")
   629  		}
   630  	}
   631  }
   632  
   633  func (s *S) TestRandomDeletion(c *check.C) {
   634  	var (
   635  		count, max = 14, 3
   636  		r          = make([]overlap, count)
   637  		t          = &Tree{}
   638  		length     = compInt(1)
   639  	)
   640  	for i := range r {
   641  		s := compInt(rand.Intn(max))
   642  		r[i] = overlap{start: s, end: s + length, id: uintptr(i)}
   643  		t.Insert(&r[i], false)
   644  	}
   645  	for i, v := range r {
   646  		var dotString string
   647  		if *genDot && t.Len() <= *dotLimit {
   648  			dotString = t.dot(fmt.Sprintf("TestRandomDeletion_before_del_%d_%d_%d", i, v.start, v.end))
   649  		}
   650  		t.Delete(&v, false)
   651  		if t != nil {
   652  			failed := false
   653  			failed = failed || !c.Check(t.isBST(), check.Equals, true)
   654  			failed = failed || !c.Check(t.is23_234(), check.Equals, true)
   655  			failed = failed || !c.Check(t.isBalanced(), check.Equals, true)
   656  			failed = failed || !c.Check(t.isRanged(), check.Equals, true)
   657  			if failed {
   658  				if *printTree {
   659  					c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   660  				}
   661  				if *genDot && t.Len() <= *dotLimit {
   662  					var err error
   663  					err = (*Tree)(nil).dotFile(fmt.Sprintf("TestRandomDeletion_before_del_%d_%d_%d", i, v.start, v.end), dotString)
   664  					if err != nil {
   665  						c.Errorf("Dot file write failed: %v", err)
   666  					}
   667  					err = t.dotFile(fmt.Sprintf("TestRandomDeletion_after_del_%d_%d_%d", i, v.start, v.end), "")
   668  					if err != nil {
   669  						c.Errorf("Dot file write failed: %v", err)
   670  					}
   671  				}
   672  				c.Fatal("Cannot continue test: invariant contradiction")
   673  			}
   674  		}
   675  	}
   676  	c.Check(*t, check.DeepEquals, Tree{})
   677  }
   678  
   679  func (s *S) TestDeleteMinMax(c *check.C) {
   680  	var (
   681  		min, max = compInt(0), compInt(10)
   682  		t        = &Tree{}
   683  		length   = compInt(1)
   684  		dI       int
   685  	)
   686  	for i := min; i <= max; i++ {
   687  		v := overlap{start: i, end: i + length}
   688  		t.Insert(&v, false)
   689  		dI = t.Len()
   690  	}
   691  	c.Check(dI, check.Equals, int(max-min+1))
   692  	for i, m := 0, int(max); i < m/2; i++ {
   693  		var failed bool
   694  		t.DeleteMin(false)
   695  		dI--
   696  		c.Check(t.Len(), check.Equals, dI)
   697  		min++
   698  		failed = !c.Check(t.Min(), check.DeepEquals, &overlap{start: min, end: min + length})
   699  		failed = failed || !c.Check(t.isBST(), check.Equals, true)
   700  		failed = failed || !c.Check(t.is23_234(), check.Equals, true)
   701  		failed = failed || !c.Check(t.isBalanced(), check.Equals, true)
   702  		failed = failed || !c.Check(t.isRanged(), check.Equals, true)
   703  		if failed {
   704  			if *printTree {
   705  				c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   706  			}
   707  			if *genDot && t.Len() <= *dotLimit {
   708  				err := t.dotFile(fmt.Sprintf("TestDeleteMinMax_after_delmin_%d", i), "")
   709  				if err != nil {
   710  					c.Errorf("Dot file write failed: %v", err)
   711  				}
   712  			}
   713  			c.Fatal("Cannot continue test: invariant contradiction")
   714  		}
   715  		t.DeleteMax(false)
   716  		dI--
   717  		c.Check(t.Len(), check.Equals, dI)
   718  		max--
   719  		failed = !c.Check(t.Max(), check.DeepEquals, &overlap{start: max, end: max + length})
   720  		failed = failed || !c.Check(t.isBST(), check.Equals, true)
   721  		failed = failed || !c.Check(t.is23_234(), check.Equals, true)
   722  		failed = failed || !c.Check(t.isBalanced(), check.Equals, true)
   723  		failed = failed || !c.Check(t.isRanged(), check.Equals, true)
   724  		if failed {
   725  			if *printTree {
   726  				c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   727  			}
   728  			if *genDot && t.Len() <= *dotLimit {
   729  				err := t.dotFile(fmt.Sprintf("TestDeleteMinMax_after_delmax_%d", i), "")
   730  				if err != nil {
   731  					c.Errorf("Dot file write failed: %v", err)
   732  				}
   733  			}
   734  			c.Fatal("Cannot continue test: invariant contradiction")
   735  		}
   736  	}
   737  }
   738  
   739  // Check for correct child range calculation when the left child
   740  // extends beyond the right child.
   741  func (s *S) TestRangeBug(c *check.C) {
   742  	var t Tree
   743  	for i, e := range []*overlap{
   744  		{start: 0, end: 10},
   745  		{start: 1, end: 5},
   746  		{start: 1, end: 5},
   747  	} {
   748  		e.id = uintptr(i)
   749  		err := t.Insert(e, false)
   750  		c.Assert(err, check.Equals, nil)
   751  	}
   752  	c.Check(t.isRanged(), check.Equals, true)
   753  }
   754  
   755  // Issue 15 is another case of a range invariant update bug.
   756  // https://code.google.com/p/biogo/issues/detail?id=15
   757  func (s *S) TestIssue15(c *check.C) {
   758  	ranges := []*overlap{
   759  		{start: 5, end: 6},
   760  		{start: 7, end: 8},
   761  		{start: 9, end: 10},
   762  		{start: 0, end: 4},
   763  		{start: 0, end: 1},
   764  		{start: 0, end: 1},
   765  		{start: 0, end: 1},
   766  	}
   767  
   768  	var t Tree
   769  	for i, iv := range ranges {
   770  		iv.id = uintptr(i)
   771  		err := t.Insert(iv, false)
   772  		c.Assert(err, check.Equals, nil)
   773  
   774  		failed := !c.Check(t.isRanged(), check.Equals, true)
   775  		if failed {
   776  			if *printTree {
   777  				c.Logf("Failing tree: %s\n\n", t.Root.describeTree(false, true))
   778  			}
   779  			if *genDot && t.Len() <= *dotLimit {
   780  				err := t.dotFile(fmt.Sprintf("Issue15Test_%02d", i), "")
   781  				if err != nil {
   782  					c.Errorf("Dot file write failed: %v", err)
   783  				}
   784  			}
   785  		}
   786  	}
   787  
   788  	got := t.Get(&overlap{start: 2, end: 3})
   789  	c.Check(len(got), check.Equals, 1, check.Commentf("Expected one overlap, got %d", len(got)))
   790  }
   791  
   792  func (s *S) TestInsertBug(c *check.C) {
   793  	var t Tree
   794  	for i := 10; i > 0; i-- {
   795  		t.Insert(&overlap{start: 0, end: 1, id: uintptr(i)}, false)
   796  	}
   797  	c.Check(t.Len(), check.Equals, 10, check.Commentf("Expected 10 entries, got %d", t.Len()))
   798  	for i := 1; i <= 10; i++ {
   799  		t.Delete(&overlap{start: 0, end: 1, id: uintptr(i)}, false)
   800  	}
   801  	c.Check(t.Len(), check.Equals, 0, check.Commentf("Expected 0 entries, got %d", t.Len()))
   802  }
   803  
   804  func (t *Tree) dot(label string) string {
   805  	if t == nil {
   806  		return ""
   807  	}
   808  	var (
   809  		arrows = map[llrb.Color]string{llrb.Red: "none", llrb.Black: "normal"}
   810  		s      []string
   811  		follow func(*Node)
   812  	)
   813  	follow = func(n *Node) {
   814  		id := uintptr(unsafe.Pointer(n))
   815  		c := fmt.Sprintf("%d[label = \"<Left> |<Elem> interval:%v\\nrange:%v\\nid:%d|<Right>\"];",
   816  			id, n.Elem, n.Range, n.Elem.ID())
   817  		if n.Left != nil {
   818  			c += fmt.Sprintf("\n\t\tedge [color=%v,arrowhead=%s]; \"%d\":Left -> \"%d\":Elem;",
   819  				n.Left.color(), arrows[n.Left.color()], id, uintptr(unsafe.Pointer(n.Left)))
   820  			follow(n.Left)
   821  		}
   822  		if n.Right != nil {
   823  			c += fmt.Sprintf("\n\t\tedge [color=%v,arrowhead=%s]; \"%d\":Right -> \"%d\":Elem;",
   824  				n.Right.color(), arrows[n.Right.color()], id, uintptr(unsafe.Pointer(n.Right)))
   825  			follow(n.Right)
   826  		}
   827  		s = append(s, c)
   828  	}
   829  	if t.Root != nil {
   830  		follow(t.Root)
   831  	}
   832  	return fmt.Sprintf("digraph %s {\n\tnode [shape=record,height=0.1];\n\t%s\n}\n",
   833  		label,
   834  		strings.Join(s, "\n\t"),
   835  	)
   836  }
   837  
   838  func (t *Tree) dotFile(label, dotString string) (err error) {
   839  	if t == nil && dotString == "" {
   840  		return
   841  	}
   842  	f, err := os.Create(label + ".dot")
   843  	if err != nil {
   844  		return
   845  	}
   846  	defer f.Close()
   847  	if dotString == "" {
   848  		fmt.Fprintf(f, t.dot(label))
   849  	} else {
   850  		fmt.Fprintf(f, dotString)
   851  	}
   852  	return
   853  }
   854  
   855  // Benchmarks
   856  
   857  func BenchmarkInsert(b *testing.B) {
   858  	var (
   859  		t      = &Tree{}
   860  		length = compInt(10)
   861  		N      = compInt(b.N)
   862  	)
   863  	for i := compInt(0); i < N; i++ {
   864  		s := N - i
   865  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   866  	}
   867  }
   868  
   869  func BenchmarkFastInsert(b *testing.B) {
   870  	var (
   871  		t      = &Tree{}
   872  		length = compInt(10)
   873  		N      = compInt(b.N)
   874  	)
   875  	for i := compInt(0); i < N; i++ {
   876  		s := N - i
   877  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, true)
   878  	}
   879  }
   880  
   881  func BenchmarkGet(b *testing.B) {
   882  	b.StopTimer()
   883  	var (
   884  		t      = &Tree{}
   885  		length = compInt(10)
   886  		N      = compInt(b.N)
   887  	)
   888  	for i := compInt(0); i < N; i++ {
   889  		s := N - i
   890  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   891  	}
   892  	b.StartTimer()
   893  	for i := compInt(0); i < N; i++ {
   894  		s := N - i
   895  		t.Get(&overlap{start: s, end: s + length})
   896  	}
   897  }
   898  
   899  func BenchmarkMin(b *testing.B) {
   900  	b.StopTimer()
   901  	var (
   902  		t      = &Tree{}
   903  		length = compInt(10)
   904  		N      = compInt(b.N)
   905  	)
   906  	for i := compInt(0); i < 1e5; i++ {
   907  		s := N - i
   908  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   909  	}
   910  	b.StartTimer()
   911  	var m Interface
   912  	for i := compInt(0); i < N; i++ {
   913  		m = t.Min()
   914  	}
   915  	_ = m
   916  }
   917  
   918  func BenchmarkMax(b *testing.B) {
   919  	b.StopTimer()
   920  	var (
   921  		t      = &Tree{}
   922  		length = compInt(10)
   923  		N      = compInt(b.N)
   924  	)
   925  	for i := compInt(0); i < 1e5; i++ {
   926  		s := N - i
   927  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   928  	}
   929  	b.StartTimer()
   930  	var m Interface
   931  	for i := compInt(0); i < N; i++ {
   932  		m = t.Max()
   933  	}
   934  	_ = m
   935  }
   936  
   937  func BenchmarkDelete(b *testing.B) {
   938  	b.StopTimer()
   939  	var (
   940  		t      = &Tree{}
   941  		length = compInt(1)
   942  		N      = compInt(b.N)
   943  	)
   944  	for i := compInt(0); i < N; i++ {
   945  		s := N - i
   946  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   947  	}
   948  	b.StartTimer()
   949  	for i := compInt(0); i < N; i++ {
   950  		s := N - i
   951  		t.Delete(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   952  	}
   953  }
   954  
   955  func BenchmarkFastDelete(b *testing.B) {
   956  	b.StopTimer()
   957  	var (
   958  		t      = &Tree{}
   959  		length = compInt(1)
   960  		N      = compInt(b.N)
   961  	)
   962  	for i := compInt(0); i < N; i++ {
   963  		s := N - i
   964  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   965  	}
   966  	b.StartTimer()
   967  	for i := compInt(0); i < N; i++ {
   968  		s := N - i
   969  		t.Delete(&overlap{start: s, end: s + length, id: uintptr(s)}, true)
   970  	}
   971  }
   972  
   973  func BenchmarkDeleteMin(b *testing.B) {
   974  	b.StopTimer()
   975  	var (
   976  		t      = &Tree{}
   977  		length = compInt(10)
   978  		N      = compInt(b.N)
   979  	)
   980  	for i := compInt(0); i < N; i++ {
   981  		s := N - i
   982  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
   983  	}
   984  	b.StartTimer()
   985  	for i := compInt(0); i < N; i++ {
   986  		t.DeleteMin(false)
   987  	}
   988  }
   989  
   990  func BenchmarkFastDeleteMin(b *testing.B) {
   991  	b.StopTimer()
   992  	var (
   993  		t      = &Tree{}
   994  		length = compInt(10)
   995  		N      = compInt(b.N)
   996  	)
   997  	for i := compInt(0); i < N; i++ {
   998  		s := N - i
   999  		t.Insert(&overlap{start: s, end: s + length, id: uintptr(s)}, false)
  1000  	}
  1001  	b.StartTimer()
  1002  	for i := compInt(0); i < N; i++ {
  1003  		t.DeleteMin(true)
  1004  	}
  1005  }