github.com/biogo/store@v0.0.0-20201120204734-aad293a2328f/step/step_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 step
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"math"
    11  	"math/rand"
    12  	"reflect"
    13  	"testing"
    14  
    15  	"gopkg.in/check.v1"
    16  )
    17  
    18  // Tests
    19  func Test(t *testing.T) { check.TestingT(t) }
    20  
    21  type S struct{}
    22  
    23  var _ = check.Suite(&S{})
    24  
    25  type nilable int
    26  
    27  func (n *nilable) Equal(e Equaler) bool {
    28  	return n == e.(*nilable)
    29  }
    30  
    31  func (s *S) TestCreate(c *check.C) {
    32  	_, err := New(0, 0, nil)
    33  	c.Check(err, check.ErrorMatches, ErrZeroLength.Error())
    34  	for _, vec := range []struct {
    35  		start, end int
    36  		zero       Equaler
    37  	}{
    38  		{1, 10, (*nilable)(nil)},
    39  		{0, 10, (*nilable)(nil)},
    40  		{-1, 100, (*nilable)(nil)},
    41  		{-100, -10, (*nilable)(nil)},
    42  		{1, 10, Int(0)},
    43  		{0, 10, Int(0)},
    44  		{-1, 100, Int(0)},
    45  		{-100, -10, Int(0)},
    46  	} {
    47  		sv, err := New(vec.start, vec.end, vec.zero)
    48  		c.Assert(err, check.Equals, nil)
    49  		c.Check(sv.Start(), check.Equals, vec.start)
    50  		c.Check(sv.End(), check.Equals, vec.end)
    51  		c.Check(sv.Len(), check.Equals, vec.end-vec.start)
    52  		c.Check(sv.Zero, check.DeepEquals, vec.zero)
    53  		var at Equaler
    54  		for i := vec.start; i < vec.end; i++ {
    55  			at, err = sv.At(i)
    56  			c.Check(at, check.DeepEquals, vec.zero)
    57  			c.Check(err, check.Equals, nil)
    58  		}
    59  		_, err = sv.At(vec.start - 1)
    60  		c.Check(err, check.ErrorMatches, ErrOutOfRange.Error())
    61  		_, err = sv.At(vec.start - 1)
    62  		c.Check(err, check.ErrorMatches, ErrOutOfRange.Error())
    63  	}
    64  }
    65  
    66  func (s *S) TestSet_1(c *check.C) {
    67  	for i, t := range []struct {
    68  		start, end int
    69  		zero       Equaler
    70  		sets       []position
    71  		expect     string
    72  	}{
    73  		{1, 10, Int(0),
    74  			[]position{
    75  				{1, Int(2)},
    76  				{2, Int(3)},
    77  				{3, Int(3)},
    78  				{4, Int(3)},
    79  				{5, Int(2)},
    80  			},
    81  			"[1:2 2:3 5:2 6:0 10:<nil>]",
    82  		},
    83  		{1, 10, Int(0),
    84  			[]position{
    85  				{3, Int(3)},
    86  				{4, Int(3)},
    87  				{1, Int(2)},
    88  				{2, Int(3)},
    89  				{5, Int(2)},
    90  			},
    91  			"[1:2 2:3 5:2 6:0 10:<nil>]",
    92  		},
    93  		{1, 10, Int(0),
    94  			[]position{
    95  				{3, Int(3)},
    96  				{4, Int(3)},
    97  				{5, Int(2)},
    98  				{1, Int(2)},
    99  				{2, Int(3)},
   100  				{9, Int(2)},
   101  			},
   102  			"[1:2 2:3 5:2 6:0 9:2 10:<nil>]",
   103  		},
   104  		{1, 10, Float(0),
   105  			[]position{
   106  				{3, Float(math.NaN())},
   107  				{4, Float(math.NaN())},
   108  				{5, Float(2)},
   109  				{1, Float(2)},
   110  				{2, Float(math.NaN())},
   111  				{9, Float(2)},
   112  			},
   113  			"[1:2 2:NaN 5:2 6:0 9:2 10:<nil>]",
   114  		},
   115  		{1, 10, Float(math.NaN()),
   116  			[]position{
   117  				{3, Float(3)},
   118  				{4, Float(3)},
   119  				{5, Float(2)},
   120  				{1, Float(2)},
   121  				{2, Float(3)},
   122  				{9, Float(2)},
   123  			},
   124  			"[1:2 2:3 5:2 6:NaN 9:2 10:<nil>]",
   125  		},
   126  	} {
   127  		sv, err := New(t.start, t.end, t.zero)
   128  		c.Assert(err, check.Equals, nil)
   129  		c.Check(func() { sv.Set(t.start-1, nil) }, check.Panics, ErrOutOfRange)
   130  		c.Check(func() { sv.Set(t.end, nil) }, check.Panics, ErrOutOfRange)
   131  		for _, v := range t.sets {
   132  			sv.Set(v.pos, v.val)
   133  			c.Check(sv.min.pos, check.Equals, t.start)
   134  			c.Check(sv.max.pos, check.Equals, t.end)
   135  			c.Check(sv.Len(), check.Equals, t.end-t.start)
   136  		}
   137  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
   138  		sv.Relaxed = true
   139  		sv.Set(t.start-1, sv.Zero)
   140  		sv.Set(t.end, sv.Zero)
   141  		c.Check(sv.Len(), check.Equals, t.end-t.start+2)
   142  		for _, v := range t.sets {
   143  			sv.Set(v.pos, t.zero)
   144  		}
   145  		sv.Set(t.start-1, t.zero)
   146  		sv.Set(t.end, t.zero)
   147  		c.Check(sv.t.Len(), check.Equals, 2)
   148  		c.Check(sv.String(), check.Equals, fmt.Sprintf("[%d:%v %d:%v]", t.start-1, t.zero, t.end+1, nil))
   149  	}
   150  }
   151  
   152  func (s *S) TestSet_2(c *check.C) {
   153  	for i, t := range []struct {
   154  		start, end int
   155  		zero       Int
   156  		sets       []position
   157  		expect     string
   158  		count      int
   159  	}{
   160  		{1, 2, 0,
   161  			[]position{
   162  				{1, Int(2)},
   163  				{2, Int(3)},
   164  				{3, Int(3)},
   165  				{4, Int(3)},
   166  				{5, Int(2)},
   167  				{-1, Int(5)},
   168  				{10, Int(23)},
   169  			},
   170  			"[-1:5 0:0 1:2 2:3 5:2 6:0 10:23 11:<nil>]",
   171  			7,
   172  		},
   173  		{1, 10, 0,
   174  			[]position{
   175  				{0, Int(0)},
   176  			},
   177  			"[0:0 10:<nil>]",
   178  			1,
   179  		},
   180  		{1, 10, 0,
   181  			[]position{
   182  				{-1, Int(0)},
   183  			},
   184  			"[-1:0 10:<nil>]",
   185  			1,
   186  		},
   187  		{1, 10, 0,
   188  			[]position{
   189  				{11, Int(0)},
   190  			},
   191  			"[1:0 12:<nil>]",
   192  			1,
   193  		},
   194  		{1, 10, 0,
   195  			[]position{
   196  				{2, Int(1)},
   197  				{3, Int(1)},
   198  				{4, Int(1)},
   199  				{5, Int(1)},
   200  				{6, Int(1)},
   201  				{7, Int(1)},
   202  				{8, Int(1)},
   203  				{5, Int(1)},
   204  			},
   205  			"[1:0 2:1 9:0 10:<nil>]",
   206  			3,
   207  		},
   208  		{1, 10, 0,
   209  			[]position{
   210  				{3, Int(1)},
   211  				{2, Int(1)},
   212  			},
   213  			"[1:0 2:1 4:0 10:<nil>]",
   214  			3,
   215  		},
   216  	} {
   217  		sv, err := New(t.start, t.end, t.zero)
   218  		c.Assert(err, check.Equals, nil)
   219  		sv.Relaxed = true
   220  		for _, v := range t.sets {
   221  			sv.Set(v.pos, v.val)
   222  		}
   223  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
   224  		c.Check(sv.Count(), check.Equals, t.count)
   225  	}
   226  }
   227  
   228  func (s *S) TestSetRange_0(c *check.C) {
   229  	type posRange struct {
   230  		start, end int
   231  		val        Int
   232  	}
   233  	for i, t := range []struct {
   234  		start, end int
   235  		zero       Int
   236  		sets       []posRange
   237  		expect     string
   238  		count      int
   239  	}{
   240  		// Left overhang
   241  		{1, 10, 0,
   242  			[]posRange{
   243  				{-2, 0, 1},
   244  			},
   245  			"[-2:1 0:0 10:<nil>]",
   246  			2,
   247  		},
   248  		{1, 10, 0,
   249  			[]posRange{
   250  				{-2, 0, 0},
   251  			},
   252  			"[-2:0 10:<nil>]",
   253  			1,
   254  		},
   255  		{1, 10, 0,
   256  			[]posRange{
   257  				{-1, 1, 1},
   258  			},
   259  			"[-1:1 1:0 10:<nil>]",
   260  			2,
   261  		},
   262  		{1, 10, 0,
   263  			[]posRange{
   264  				{-1, 1, 0},
   265  			},
   266  			"[-1:0 10:<nil>]",
   267  			1,
   268  		},
   269  		{1, 10, 0,
   270  			[]posRange{
   271  				{-1, 2, 1},
   272  			},
   273  			"[-1:1 2:0 10:<nil>]",
   274  			2,
   275  		},
   276  		{1, 10, 0,
   277  			[]posRange{
   278  				{-1, 2, 0},
   279  			},
   280  			"[-1:0 10:<nil>]",
   281  			1,
   282  		},
   283  
   284  		// Right overhang
   285  		{1, 10, 0,
   286  			[]posRange{
   287  				{11, 12, 1},
   288  			},
   289  			"[1:0 11:1 12:<nil>]",
   290  			2,
   291  		},
   292  		{1, 10, 0,
   293  			[]posRange{
   294  				{11, 12, 0},
   295  			},
   296  			"[1:0 12:<nil>]",
   297  			1,
   298  		},
   299  		{1, 10, 0,
   300  			[]posRange{
   301  				{11, 13, 1},
   302  			},
   303  			"[1:0 11:1 13:<nil>]",
   304  			2,
   305  		},
   306  		{1, 10, 0,
   307  			[]posRange{
   308  				{11, 13, 0},
   309  			},
   310  			"[1:0 13:<nil>]",
   311  			1,
   312  		},
   313  		{1, 10, 0,
   314  			[]posRange{
   315  				{1, 10, 1},
   316  				{11, 13, 1},
   317  			},
   318  			"[1:1 10:0 11:1 13:<nil>]",
   319  			3,
   320  		},
   321  		{1, 10, 0,
   322  			[]posRange{
   323  				{1, 10, 1},
   324  				{11, 13, 0},
   325  			},
   326  			"[1:1 10:0 13:<nil>]",
   327  			2,
   328  		},
   329  		{1, 10, 0,
   330  			[]posRange{
   331  				{10, 11, 1},
   332  			},
   333  			"[1:0 10:1 11:<nil>]",
   334  			2,
   335  		},
   336  		{1, 10, 0,
   337  			[]posRange{
   338  				{10, 11, 0},
   339  			},
   340  			"[1:0 11:<nil>]",
   341  			1,
   342  		},
   343  		{1, 10, 0,
   344  			[]posRange{
   345  				{9, 11, 1},
   346  			},
   347  			"[1:0 9:1 11:<nil>]",
   348  			2,
   349  		},
   350  		{1, 10, 0,
   351  			[]posRange{
   352  				{9, 11, 0},
   353  			},
   354  			"[1:0 11:<nil>]",
   355  			1,
   356  		},
   357  	} {
   358  		sv, err := New(t.start, t.end, t.zero)
   359  		c.Assert(err, check.Equals, nil)
   360  		sv.Relaxed = true
   361  		c.Logf("subtest %d process", i)
   362  		for _, v := range t.sets {
   363  			in := fmt.Sprint(sv)
   364  			sv.SetRange(v.start, v.end, v.val)
   365  			c.Logf(" %s --%+v-> %s min:%+v max:%+v", in, v, sv, *sv.min, *sv.max)
   366  		}
   367  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
   368  		c.Check(sv.Count(), check.Equals, t.count)
   369  	}
   370  }
   371  
   372  func (s *S) TestSetRange_1(c *check.C) {
   373  	type posRange struct {
   374  		start, end int
   375  		val        Int
   376  	}
   377  	for i, t := range []struct {
   378  		start, end int
   379  		zero       Int
   380  		sets       []posRange
   381  		expect     string
   382  		count      int
   383  	}{
   384  		{1, 10, 0,
   385  			[]posRange{
   386  				{1, 2, 2},
   387  				{2, 3, 3},
   388  				{3, 4, 3},
   389  				{4, 5, 3},
   390  				{5, 6, 2},
   391  			},
   392  			"[1:2 2:3 5:2 6:0 10:<nil>]",
   393  			4,
   394  		},
   395  		{1, 10, 0,
   396  			[]posRange{
   397  				{3, 4, 3},
   398  				{4, 5, 3},
   399  				{1, 2, 2},
   400  				{2, 3, 3},
   401  				{5, 6, 2},
   402  			},
   403  			"[1:2 2:3 5:2 6:0 10:<nil>]",
   404  			4,
   405  		},
   406  		{1, 10, 0,
   407  			[]posRange{
   408  				{3, 4, 3},
   409  				{4, 5, 3},
   410  				{5, 6, 2},
   411  				{1, 2, 2},
   412  				{2, 3, 3},
   413  				{9, 10, 2},
   414  			},
   415  			"[1:2 2:3 5:2 6:0 9:2 10:<nil>]",
   416  			5,
   417  		},
   418  		{1, 10, 0,
   419  			[]posRange{
   420  				{3, 6, 3},
   421  				{4, 5, 1},
   422  				{5, 7, 2},
   423  				{1, 3, 2},
   424  				{9, 10, 2},
   425  			},
   426  			"[1:2 3:3 4:1 5:2 7:0 9:2 10:<nil>]",
   427  			6,
   428  		},
   429  		{1, 10, 0,
   430  			[]posRange{
   431  				{1, 3, 3},
   432  				{4, 5, 1},
   433  				{7, 8, 2},
   434  				{9, 10, 4},
   435  			},
   436  			"[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]",
   437  			7,
   438  		},
   439  	} {
   440  		sv, err := New(t.start, t.end, t.zero)
   441  		c.Assert(err, check.Equals, nil)
   442  		c.Check(func() { sv.SetRange(t.start-2, t.start, nil) }, check.Panics, ErrOutOfRange)
   443  		c.Check(func() { sv.SetRange(t.end, t.end+2, nil) }, check.Panics, ErrOutOfRange)
   444  		for _, v := range t.sets {
   445  			sv.SetRange(v.start, v.end, v.val)
   446  			c.Check(sv.min.pos, check.Equals, t.start)
   447  			c.Check(sv.max.pos, check.Equals, t.end)
   448  			c.Check(sv.Len(), check.Equals, t.end-t.start)
   449  		}
   450  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
   451  		c.Check(sv.Count(), check.Equals, t.count)
   452  		sv.Relaxed = true
   453  		sv.SetRange(t.start-1, t.start, sv.Zero)
   454  		sv.SetRange(t.end, t.end+1, sv.Zero)
   455  		c.Check(sv.Len(), check.Equals, t.end-t.start+2)
   456  		sv.SetRange(t.start-1, t.end+1, t.zero)
   457  		c.Check(sv.t.Len(), check.Equals, 2)
   458  		c.Check(sv.String(), check.Equals, fmt.Sprintf("[%d:%v %d:%v]", t.start-1, t.zero, t.end+1, nil))
   459  	}
   460  }
   461  
   462  func (s *S) TestSetRange_2(c *check.C) {
   463  	sv, _ := New(0, 1, nil)
   464  	c.Check(func() { sv.SetRange(1, 0, nil) }, check.Panics, ErrInvertedRange)
   465  	type posRange struct {
   466  		start, end int
   467  		val        Int
   468  	}
   469  	for i, t := range []struct {
   470  		start, end int
   471  		zero       Int
   472  		sets       []posRange
   473  		expect     string
   474  	}{
   475  		{1, 10, 0,
   476  			[]posRange{
   477  				{1, 2, 2},
   478  				{2, 3, 3},
   479  				{3, 4, 3},
   480  				{4, 5, 3},
   481  				{5, 6, 2},
   482  				{-10, -1, 4},
   483  				{23, 35, 10},
   484  			},
   485  			"[-10:4 -1:0 1:2 2:3 5:2 6:0 23:10 35:<nil>]",
   486  		},
   487  		{1, 2, 0,
   488  			[]posRange{
   489  				{1, 1, 2},
   490  			},
   491  			"[1:0 2:<nil>]",
   492  		},
   493  		{1, 10, 0,
   494  			[]posRange{
   495  				{-10, 1, 0},
   496  			},
   497  			"[-10:0 10:<nil>]",
   498  		},
   499  		{1, 10, 0,
   500  			[]posRange{
   501  				{-10, 1, 1},
   502  			},
   503  			"[-10:1 1:0 10:<nil>]",
   504  		},
   505  		{1, 10, 0,
   506  			[]posRange{
   507  				{-10, 0, 1},
   508  			},
   509  			"[-10:1 0:0 10:<nil>]",
   510  		},
   511  		{1, 10, 0,
   512  			[]posRange{
   513  				{-10, 0, 0},
   514  			},
   515  			"[-10:0 10:<nil>]",
   516  		},
   517  		{1, 10, 0,
   518  			[]posRange{
   519  				{10, 20, 0},
   520  			},
   521  			"[1:0 20:<nil>]",
   522  		},
   523  		{1, 10, 0,
   524  			[]posRange{
   525  				{10, 20, 1},
   526  			},
   527  			"[1:0 10:1 20:<nil>]",
   528  		},
   529  		{1, 10, 0,
   530  			[]posRange{
   531  				{11, 20, 0},
   532  			},
   533  			"[1:0 20:<nil>]",
   534  		},
   535  		{1, 10, 0,
   536  			[]posRange{
   537  				{11, 20, 1},
   538  			},
   539  			"[1:0 11:1 20:<nil>]",
   540  		},
   541  		{1, 10, 0,
   542  			[]posRange{
   543  				{1, 10, 1},
   544  				{11, 20, 1},
   545  			},
   546  			"[1:1 10:0 11:1 20:<nil>]",
   547  		},
   548  		{1, 10, 0,
   549  			[]posRange{
   550  				{2, 5, 1},
   551  				{2, 5, 0},
   552  			},
   553  			"[1:0 10:<nil>]",
   554  		},
   555  		{1, 10, 0,
   556  			[]posRange{
   557  				{2, 6, 1},
   558  				{2, 5, 0},
   559  			},
   560  			"[1:0 5:1 6:0 10:<nil>]",
   561  		},
   562  		{1, 10, 0,
   563  			[]posRange{
   564  				{1, 3, 1},
   565  				{5, 7, 2},
   566  				{3, 5, 1},
   567  			},
   568  			"[1:1 5:2 7:0 10:<nil>]",
   569  		},
   570  		{1, 10, 0,
   571  			[]posRange{
   572  				{1, 3, 1},
   573  				{5, 7, 2},
   574  				{3, 5, 2},
   575  			},
   576  			"[1:1 3:2 7:0 10:<nil>]",
   577  		},
   578  		{1, 10, 0,
   579  			[]posRange{
   580  				{2, 5, 1},
   581  				{2, 6, 0},
   582  			},
   583  			"[1:0 10:<nil>]",
   584  		},
   585  		{1, 10, 0,
   586  			[]posRange{
   587  				{2, 6, 1},
   588  				{2, 5, 0},
   589  			},
   590  			"[1:0 5:1 6:0 10:<nil>]",
   591  		},
   592  		{1, 10, 0,
   593  			[]posRange{
   594  				{2, 5, 1},
   595  				{2, 5, 2},
   596  			},
   597  			"[1:0 2:2 5:0 10:<nil>]",
   598  		},
   599  		{1, 10, 0,
   600  			[]posRange{
   601  				{2, 5, 1},
   602  				{3, 5, 2},
   603  			},
   604  			"[1:0 2:1 3:2 5:0 10:<nil>]",
   605  		},
   606  		{1, 10, 0,
   607  			[]posRange{
   608  				{2, 5, 1},
   609  				{3, 5, 0},
   610  			},
   611  			"[1:0 2:1 3:0 10:<nil>]",
   612  		},
   613  		{1, 10, 0,
   614  			[]posRange{
   615  				{5, 20, 1},
   616  			},
   617  			"[1:0 5:1 20:<nil>]",
   618  		},
   619  		{1, 10, 0,
   620  			[]posRange{
   621  				{5, 10, 1},
   622  			},
   623  			"[1:0 5:1 10:<nil>]",
   624  		},
   625  		{5, 10, 0,
   626  			[]posRange{
   627  				{5, 10, 1},
   628  				{1, 4, 1},
   629  			},
   630  			"[1:1 4:0 5:1 10:<nil>]",
   631  		},
   632  		{1, 4, 0,
   633  			[]posRange{
   634  				{1, 4, 1},
   635  				{5, 10, 1},
   636  			},
   637  			"[1:1 4:0 5:1 10:<nil>]",
   638  		},
   639  	} {
   640  		sv, err := New(t.start, t.end, t.zero)
   641  		c.Assert(err, check.Equals, nil)
   642  		sv.Relaxed = true
   643  		for _, v := range t.sets {
   644  			sv.SetRange(v.start, v.end, v.val)
   645  		}
   646  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
   647  	}
   648  }
   649  
   650  func (s *S) TestStepAt(c *check.C) {
   651  	type posRange struct {
   652  		start, end int
   653  		val        Int
   654  	}
   655  	t := struct {
   656  		start, end int
   657  		zero       Int
   658  		sets       []posRange
   659  		expect     string
   660  	}{1, 10, 0,
   661  		[]posRange{
   662  			{1, 3, 3},
   663  			{4, 5, 1},
   664  			{7, 8, 2},
   665  			{9, 10, 4},
   666  		},
   667  		"[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]",
   668  	}
   669  
   670  	sv, err := New(t.start, t.end, t.zero)
   671  	c.Assert(err, check.Equals, nil)
   672  	for _, v := range t.sets {
   673  		sv.SetRange(v.start, v.end, v.val)
   674  	}
   675  	c.Check(sv.String(), check.Equals, t.expect)
   676  	for i, v := range t.sets {
   677  		for j := v.start; j < v.end; j++ {
   678  			st, en, at, err := sv.StepAt(v.start)
   679  			c.Check(err, check.Equals, nil)
   680  			c.Check(at, check.DeepEquals, v.val)
   681  			c.Check(st, check.Equals, v.start)
   682  			c.Check(en, check.Equals, v.end)
   683  		}
   684  		st, en, at, err := sv.StepAt(v.end)
   685  		if v.end < sv.End() {
   686  			c.Check(err, check.Equals, nil)
   687  			c.Check(at, check.DeepEquals, sv.Zero)
   688  			c.Check(st, check.Equals, v.end)
   689  			c.Check(en, check.Equals, t.sets[i+1].start)
   690  		} else {
   691  			c.Check(err, check.ErrorMatches, ErrOutOfRange.Error())
   692  		}
   693  	}
   694  	_, _, _, err = sv.StepAt(t.start - 1)
   695  	c.Check(err, check.ErrorMatches, ErrOutOfRange.Error())
   696  }
   697  
   698  func (s *S) TestDo(c *check.C) {
   699  	var data interface{}
   700  	type posRange struct {
   701  		start, end int
   702  		val        Int
   703  	}
   704  	for i, t := range []struct {
   705  		start, end int
   706  		zero       Int
   707  		relaxed    bool
   708  		sets       []posRange
   709  		setup      func()
   710  		fn         Operation
   711  		expect     interface{}
   712  	}{
   713  		{1, 10, 0, false,
   714  			[]posRange{
   715  				{1, 3, 3},
   716  				{4, 5, 1},
   717  				{7, 8, 2},
   718  				{9, 10, 4},
   719  			},
   720  			func() { data = []Int(nil) },
   721  			func(start, end int, vi Equaler) {
   722  				sl := data.([]Int)
   723  				v := vi.(Int)
   724  				for i := start; i < end; i++ {
   725  					sl = append(sl, v)
   726  				}
   727  				data = sl
   728  			},
   729  			[]Int{3, 3, 0, 1, 0, 0, 2, 0, 4},
   730  		},
   731  		{5, 10, 0, true,
   732  			[]posRange{
   733  				{5, 10, 1},
   734  				{1, 7, 1},
   735  			},
   736  			func() { data = []Int(nil) },
   737  			func(start, end int, vi Equaler) {
   738  				sl := data.([]Int)
   739  				v := vi.(Int)
   740  				for i := start; i < end; i++ {
   741  					sl = append(sl, v)
   742  				}
   743  				data = sl
   744  			},
   745  			[]Int{1, 1, 1, 1, 1, 1, 1, 1, 1},
   746  		},
   747  		{5, 10, 0, true,
   748  			[]posRange{
   749  				{5, 10, 1},
   750  				{3, 7, 1},
   751  				{1, 3, 1},
   752  			},
   753  			func() { data = []Int(nil) },
   754  			func(start, end int, vi Equaler) {
   755  				sl := data.([]Int)
   756  				v := vi.(Int)
   757  				for i := start; i < end; i++ {
   758  					sl = append(sl, v)
   759  				}
   760  				data = sl
   761  			},
   762  			[]Int{1, 1, 1, 1, 1, 1, 1, 1, 1},
   763  		},
   764  	} {
   765  		t.setup()
   766  		sv, err := New(t.start, t.end, t.zero)
   767  		sv.Relaxed = t.relaxed
   768  		c.Assert(err, check.Equals, nil)
   769  		for _, v := range t.sets {
   770  			sv.SetRange(v.start, v.end, v.val)
   771  		}
   772  		sv.Do(t.fn)
   773  		c.Check(data, check.DeepEquals, t.expect, check.Commentf("subtest %d", i))
   774  		c.Check(reflect.ValueOf(data).Len(), check.Equals, sv.Len())
   775  	}
   776  }
   777  
   778  func (s *S) TestDoRange(c *check.C) {
   779  	var data interface{}
   780  	type posRange struct {
   781  		start, end int
   782  		val        Int
   783  	}
   784  	for i, t := range []struct {
   785  		start, end int
   786  		zero       Int
   787  		sets       []posRange
   788  		setup      func()
   789  		fn         Operation
   790  		from, to   int
   791  		expect     interface{}
   792  		err        error
   793  	}{
   794  		{1, 10, 0,
   795  			[]posRange{
   796  				{1, 3, 3},
   797  				{4, 5, 1},
   798  				{7, 8, 2},
   799  				{9, 10, 4},
   800  			},
   801  			func() { data = []Int(nil) },
   802  			func(start, end int, vi Equaler) {
   803  				sl := data.([]Int)
   804  				v := vi.(Int)
   805  				for i := start; i < end; i++ {
   806  					sl = append(sl, v)
   807  				}
   808  				data = sl
   809  			},
   810  			2, 8,
   811  			[]Int{3, 0, 1, 0, 0, 2},
   812  			nil,
   813  		},
   814  		{1, 10, 0,
   815  			[]posRange{
   816  				{1, 3, 3},
   817  				{4, 5, 1},
   818  				{7, 8, 2},
   819  				{9, 10, 4},
   820  			},
   821  			func() { data = []Int(nil) },
   822  			func(_, _ int, _ Equaler) {},
   823  			-2, -1,
   824  			[]Int(nil),
   825  			ErrOutOfRange,
   826  		},
   827  		{1, 10, 0,
   828  			[]posRange{
   829  				{1, 3, 3},
   830  				{4, 5, 1},
   831  				{7, 8, 2},
   832  				{9, 10, 4},
   833  			},
   834  			func() { data = []Int(nil) },
   835  			func(_, _ int, _ Equaler) {},
   836  			10, 1,
   837  			[]Int(nil),
   838  			ErrInvertedRange,
   839  		},
   840  	} {
   841  		t.setup()
   842  		sv, err := New(t.start, t.end, t.zero)
   843  		c.Assert(err, check.Equals, nil)
   844  		for _, v := range t.sets {
   845  			sv.SetRange(v.start, v.end, v.val)
   846  		}
   847  		c.Check(sv.DoRange(t.from, t.to, t.fn), check.DeepEquals, t.err)
   848  		c.Check(data, check.DeepEquals, t.expect, check.Commentf("subtest %d", i))
   849  		if t.from <= t.to && t.from < sv.End() && t.to > sv.Start() {
   850  			c.Check(reflect.ValueOf(data).Len(), check.Equals, t.to-t.from)
   851  		}
   852  	}
   853  }
   854  
   855  func (s *S) TestApply(c *check.C) {
   856  	type posRange struct {
   857  		start, end int
   858  		val        Equaler
   859  	}
   860  	for i, t := range []struct {
   861  		start, end int
   862  		zero       Equaler
   863  		sets       []posRange
   864  		mutate     Mutator
   865  		expect     string
   866  	}{
   867  		{1, 10, Int(0),
   868  			[]posRange{
   869  				{1, 3, Int(3)},
   870  				{4, 5, Int(1)},
   871  				{7, 8, Int(2)},
   872  				{9, 10, Int(4)},
   873  			},
   874  			IncInt,
   875  			"[1:4 3:1 4:2 5:1 7:3 8:1 9:5 10:<nil>]",
   876  		},
   877  		{1, 10, Int(0),
   878  			[]posRange{
   879  				{1, 3, Int(3)},
   880  				{4, 5, Int(1)},
   881  				{7, 8, Int(2)},
   882  				{9, 10, Int(4)},
   883  			},
   884  			DecInt,
   885  			"[1:2 3:-1 4:0 5:-1 7:1 8:-1 9:3 10:<nil>]",
   886  		},
   887  		{1, 10, Float(0),
   888  			[]posRange{
   889  				{1, 3, Float(3)},
   890  				{4, 5, Float(1)},
   891  				{7, 8, Float(2)},
   892  				{9, 10, Float(4)},
   893  			},
   894  			IncFloat,
   895  			"[1:4 3:1 4:2 5:1 7:3 8:1 9:5 10:<nil>]",
   896  		},
   897  		{1, 10, Float(0),
   898  			[]posRange{
   899  				{1, 3, Float(3)},
   900  				{4, 5, Float(1)},
   901  				{7, 8, Float(2)},
   902  				{9, 10, Float(4)},
   903  			},
   904  			DecFloat,
   905  			"[1:2 3:-1 4:0 5:-1 7:1 8:-1 9:3 10:<nil>]",
   906  		},
   907  		{1, 10, Int(0),
   908  			[]posRange{
   909  				{1, 3, Int(3)},
   910  				{4, 5, Int(1)},
   911  				{7, 8, Int(2)},
   912  				{9, 10, Int(4)},
   913  			},
   914  			func(_ Equaler) Equaler { return Int(0) },
   915  			"[1:0 10:<nil>]",
   916  		},
   917  	} {
   918  		sv, err := New(t.start, t.end, t.zero)
   919  		c.Assert(err, check.Equals, nil)
   920  		for _, v := range t.sets {
   921  			sv.SetRange(v.start, v.end, v.val)
   922  		}
   923  		sv.Apply(t.mutate)
   924  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
   925  	}
   926  }
   927  
   928  func (s *S) TestMutateRange(c *check.C) {
   929  	type posRange struct {
   930  		start, end int
   931  		val        Int
   932  	}
   933  	for i, t := range []struct {
   934  		start, end int
   935  		zero       Int
   936  		sets       []posRange
   937  		mutate     Mutator
   938  		from, to   int
   939  		expect     string
   940  		err        error
   941  	}{
   942  		{1, 10, 0,
   943  			[]posRange{
   944  				{1, 3, 3},
   945  				{4, 5, 1},
   946  				{7, 8, 2},
   947  				{9, 10, 4},
   948  			},
   949  			IncInt,
   950  			2, 8,
   951  			"[1:3 2:4 3:1 4:2 5:1 7:3 8:0 9:4 10:<nil>]",
   952  			nil,
   953  		},
   954  		{1, 10, 0,
   955  			[]posRange{
   956  				{1, 3, 3},
   957  				{7, 8, 2},
   958  				{9, 10, 4},
   959  			},
   960  			IncInt,
   961  			4, 6,
   962  			"[1:3 3:0 4:1 6:0 7:2 8:0 9:4 10:<nil>]",
   963  			nil,
   964  		},
   965  		{1, 10, 0,
   966  			[]posRange{
   967  				{1, 3, 3},
   968  				{7, 8, 1},
   969  				{9, 10, 4},
   970  			},
   971  			IncInt,
   972  			4, 7,
   973  			"[1:3 3:0 4:1 8:0 9:4 10:<nil>]",
   974  			nil,
   975  		},
   976  		{1, 10, 0,
   977  			[]posRange{
   978  				{1, 3, 3},
   979  				{4, 5, 1},
   980  				{7, 8, 2},
   981  				{9, 10, 4},
   982  			},
   983  			func(_ Equaler) Equaler { return Int(0) },
   984  			2, 8,
   985  			"[1:3 2:0 9:4 10:<nil>]",
   986  			nil,
   987  		},
   988  		{1, 10, 0,
   989  			[]posRange{
   990  				{1, 3, 3},
   991  				{4, 5, 1},
   992  				{7, 9, 2},
   993  				{9, 10, 4},
   994  			},
   995  			func(_ Equaler) Equaler { return Int(0) },
   996  			2, 8,
   997  			"[1:3 2:0 8:2 9:4 10:<nil>]",
   998  			nil,
   999  		},
  1000  		{1, 10, 0,
  1001  			[]posRange{
  1002  				{1, 3, 3},
  1003  				{7, 8, 1},
  1004  				{9, 10, 4},
  1005  			},
  1006  			IncInt,
  1007  			4, 8,
  1008  			"[1:3 3:0 4:1 7:2 8:0 9:4 10:<nil>]",
  1009  			nil,
  1010  		},
  1011  		{1, 20, 0,
  1012  			[]posRange{
  1013  				{5, 10, 1},
  1014  				{10, 15, 2},
  1015  				{15, 20, 3},
  1016  			},
  1017  			func(v Equaler) Equaler {
  1018  				if v.Equal(Int(3)) {
  1019  					return Int(1)
  1020  				}
  1021  				return v
  1022  			},
  1023  			8, 18,
  1024  			"[1:0 5:1 10:2 15:1 18:3 20:<nil>]",
  1025  			nil,
  1026  		},
  1027  		{1, 20, 0,
  1028  			[]posRange{
  1029  				{1, 6, 1},
  1030  				{6, 15, 2},
  1031  				{15, 20, 1},
  1032  			},
  1033  			func(v Equaler) Equaler {
  1034  				return Int(2)
  1035  			},
  1036  			4, 12,
  1037  			"[1:1 4:2 15:1 20:<nil>]",
  1038  			nil,
  1039  		},
  1040  		{1, 10, 0,
  1041  			[]posRange{
  1042  				{1, 3, 3},
  1043  				{4, 5, 1},
  1044  				{7, 8, 2},
  1045  				{9, 10, 4},
  1046  			},
  1047  			IncInt,
  1048  			-1, 0,
  1049  			"[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]",
  1050  			ErrOutOfRange,
  1051  		},
  1052  		{1, 10, 0,
  1053  			[]posRange{
  1054  				{1, 3, 3},
  1055  				{4, 5, 1},
  1056  				{7, 8, 2},
  1057  				{9, 10, 4},
  1058  			},
  1059  			IncInt,
  1060  			10, 1,
  1061  			"[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]",
  1062  			ErrInvertedRange,
  1063  		},
  1064  	} {
  1065  		sv, err := New(t.start, t.end, t.zero)
  1066  		c.Assert(err, check.Equals, nil)
  1067  		for _, v := range t.sets {
  1068  			sv.SetRange(v.start, v.end, v.val)
  1069  		}
  1070  		c.Check(sv.ApplyRange(t.from, t.to, t.mutate), check.DeepEquals, t.err)
  1071  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
  1072  	}
  1073  }
  1074  
  1075  // pair is a [2]bool type satisfying the step.Equaler interface.
  1076  type pair [2]bool
  1077  
  1078  // Equal returns whether p equals e. Equal assumes the underlying type of e is pair.
  1079  func (p pair) Equal(e Equaler) bool {
  1080  	return p == e.(pair)
  1081  }
  1082  
  1083  func (s *S) TestMutateRangePartial(c *check.C) {
  1084  	type posRange struct {
  1085  		start, end int
  1086  		val        pair
  1087  	}
  1088  	for i, t := range []struct {
  1089  		start, end int
  1090  		zero       pair
  1091  		sets       []posRange
  1092  		mutate     Mutator
  1093  		from, to   int
  1094  		expect     string
  1095  		err        error
  1096  	}{
  1097  		{94, 301, pair{},
  1098  			[]posRange{
  1099  				{94, 120, pair{false, false}},
  1100  				{120, 134, pair{false, true}},
  1101  				{134, 301, pair{false, false}},
  1102  			},
  1103  			func(e Equaler) Equaler {
  1104  				p := e.(pair)
  1105  				p[1] = true
  1106  				return p
  1107  			},
  1108  			113, 130,
  1109  			"[94:[false false] 113:[false true] 134:[false false] 301:<nil>]",
  1110  			nil,
  1111  		},
  1112  		{253121, 253565, pair{},
  1113  			[]posRange{
  1114  				{253121, 253565, pair{false, true}},
  1115  			},
  1116  			func(e Equaler) Equaler {
  1117  				p := e.(pair)
  1118  				p[1] = true
  1119  				return p
  1120  			},
  1121  			253115, 253565,
  1122  			"[253115:[false true] 253565:<nil>]",
  1123  			nil,
  1124  		},
  1125  		{253121, 253565, pair{},
  1126  			[]posRange{
  1127  				{253121, 253565, pair{false, true}},
  1128  			},
  1129  			func(e Equaler) Equaler {
  1130  				p := e.(pair)
  1131  				p[1] = true
  1132  				return p
  1133  			},
  1134  			253121, 253575,
  1135  			"[253121:[false true] 253575:<nil>]",
  1136  			nil,
  1137  		},
  1138  		{253121, 253565, pair{},
  1139  			[]posRange{
  1140  				{253121, 253565, pair{false, true}},
  1141  			},
  1142  			func(e Equaler) Equaler {
  1143  				p := e.(pair)
  1144  				p[1] = true
  1145  				return p
  1146  			},
  1147  			253115, 253575,
  1148  			"[253115:[false true] 253575:<nil>]",
  1149  			nil,
  1150  		},
  1151  		{0, 13, pair{},
  1152  			[]posRange{
  1153  				{0, 1, pair{false, false}},
  1154  				{1, 2, pair{false, true}},
  1155  				{2, 4, pair{true, true}},
  1156  				{4, 6, pair{true, false}},
  1157  				{6, 7, pair{false, false}},
  1158  				{7, 9, pair{false, true}},
  1159  				{9, 13, pair{false, false}},
  1160  			},
  1161  			func(e Equaler) Equaler {
  1162  				p := e.(pair)
  1163  				p[1] = false
  1164  				return p
  1165  			},
  1166  			8, 11,
  1167  			"[0:[false false] 1:[false true] 2:[true true] 4:[true false] 6:[false false] 7:[false true] 8:[false false] 13:<nil>]",
  1168  			nil,
  1169  		},
  1170  		{0, 13, pair{},
  1171  			[]posRange{
  1172  				{0, 1, pair{false, false}},
  1173  				{1, 2, pair{false, true}},
  1174  				{2, 3, pair{true, false}},
  1175  				{3, 6, pair{true, false}},
  1176  				{6, 7, pair{false, true}},
  1177  				{7, 9, pair{true, true}},
  1178  				{9, 10, pair{true, false}},
  1179  				{10, 13, pair{false, false}},
  1180  			},
  1181  			func(e Equaler) Equaler {
  1182  				p := e.(pair)
  1183  				p[1] = false
  1184  				return p
  1185  			},
  1186  			1, 5,
  1187  			"[0:[false false] 2:[true false] 6:[false true] 7:[true true] 9:[true false] 10:[false false] 13:<nil>]",
  1188  			nil,
  1189  		},
  1190  	} {
  1191  		sv, err := New(t.start, t.end, pair{})
  1192  		c.Assert(err, check.Equals, nil)
  1193  		sv.Relaxed = true
  1194  		for _, v := range t.sets {
  1195  			sv.SetRange(v.start, v.end, v.val)
  1196  		}
  1197  
  1198  		c.Check(sv.ApplyRange(t.from, t.to, t.mutate), check.DeepEquals, t.err)
  1199  
  1200  		var (
  1201  			last      Equaler
  1202  			failed    = false
  1203  			failedEnd int
  1204  		)
  1205  		sv.Do(func(start, end int, e Equaler) {
  1206  			if e == last {
  1207  				failed = true
  1208  				failedEnd = start
  1209  			}
  1210  			last = e
  1211  		})
  1212  		if failed {
  1213  			c.Errorf("setting pair[1]=true over [%d,%d) gives invalid vector near %d:\n%s",
  1214  				t.start, t.end, failedEnd, sv.String())
  1215  		}
  1216  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
  1217  	}
  1218  }
  1219  
  1220  func (s *S) TestMutatorSetting(c *check.C) {
  1221  	type posRange struct {
  1222  		start, end int
  1223  	}
  1224  	for i, t := range []struct {
  1225  		sets   []posRange
  1226  		max    int
  1227  		expect string
  1228  		err    error
  1229  	}{
  1230  		{
  1231  			[]posRange{
  1232  				{30, 70},
  1233  				{10, 50},
  1234  			},
  1235  			70,
  1236  			"[10:[false true] 70:<nil>]",
  1237  			nil,
  1238  		},
  1239  		{
  1240  			[]posRange{
  1241  				{10, 50},
  1242  				{30, 70},
  1243  			},
  1244  			70,
  1245  			"[10:[false true] 70:<nil>]",
  1246  			nil,
  1247  		},
  1248  		{
  1249  			[]posRange{
  1250  				{30, 50},
  1251  				{10, 70},
  1252  			},
  1253  			70,
  1254  			"[10:[false true] 70:<nil>]",
  1255  			nil,
  1256  		},
  1257  		{
  1258  			[]posRange{
  1259  				{10, 70},
  1260  				{30, 50},
  1261  			},
  1262  			70,
  1263  			"[10:[false true] 70:<nil>]",
  1264  			nil,
  1265  		},
  1266  	} {
  1267  		sv, err := New(t.sets[0].start, t.sets[0].end, pair{})
  1268  		c.Assert(err, check.Equals, nil)
  1269  		sv.Relaxed = true
  1270  		av := newVector(t.sets[0].start, t.sets[0].end, t.max, pair{})
  1271  		for _, v := range t.sets {
  1272  			m := func(e Equaler) Equaler {
  1273  				p := e.(pair)
  1274  				p[1] = true
  1275  				return p
  1276  			}
  1277  			c.Check(sv.ApplyRange(v.start, v.end, m), check.DeepEquals, t.err)
  1278  			av.applyRange(v.start, v.end, m)
  1279  		}
  1280  
  1281  		c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i))
  1282  		c.Check(av.aggreesWith(sv), check.Equals, true)
  1283  	}
  1284  }
  1285  
  1286  type vector struct {
  1287  	min, max int
  1288  	data     []Equaler
  1289  }
  1290  
  1291  func newVector(start, end, cap int, zero Equaler) *vector {
  1292  	data := make([]Equaler, cap)
  1293  	for i := range data {
  1294  		data[i] = zero
  1295  	}
  1296  	return &vector{
  1297  		min:  start,
  1298  		max:  end,
  1299  		data: data,
  1300  	}
  1301  }
  1302  
  1303  func (v *vector) setRange(start, end int, e Equaler) {
  1304  	if start == end {
  1305  		return
  1306  	}
  1307  	if start < v.min {
  1308  		v.min = start
  1309  	}
  1310  	if end > v.max {
  1311  		v.max = end
  1312  	}
  1313  	for i := start; i < end; i++ {
  1314  		v.data[i] = e
  1315  	}
  1316  }
  1317  
  1318  func (v *vector) applyRange(start, end int, m Mutator) {
  1319  	if start == end {
  1320  		return
  1321  	}
  1322  	if start < v.min {
  1323  		v.min = start
  1324  	}
  1325  	if end > v.max {
  1326  		v.max = end
  1327  	}
  1328  	for i := start; i < end; i++ {
  1329  		v.data[i] = m(v.data[i])
  1330  	}
  1331  }
  1332  
  1333  func (v *vector) aggreesWith(sv *Vector) bool {
  1334  	if v.min != sv.Start() || v.max != sv.End() {
  1335  		return false
  1336  	}
  1337  	ok := true
  1338  	sv.Do(func(start, end int, e Equaler) {
  1339  		for _, ve := range v.data[start:end] {
  1340  			if e != ve {
  1341  				ok = false
  1342  			}
  1343  		}
  1344  	})
  1345  	return ok
  1346  }
  1347  
  1348  func (v *vector) String() string {
  1349  	var (
  1350  		buf  bytes.Buffer
  1351  		last Equaler
  1352  	)
  1353  	fmt.Fprint(&buf, "[")
  1354  	for i := v.min; i < v.max; i++ {
  1355  		if v.data[i] != last {
  1356  			fmt.Fprintf(&buf, "%d:%v ", i, v.data[i])
  1357  		}
  1358  		last = v.data[i]
  1359  	}
  1360  	fmt.Fprintf(&buf, "%d:<nil>]", v.max)
  1361  	return buf.String()
  1362  }
  1363  
  1364  func (s *S) TestMutateRangePartialFuzzing(c *check.C) {
  1365  	rand.Seed(1)
  1366  	sv, err := New(0, 1, pair{})
  1367  	c.Assert(err, check.Equals, nil)
  1368  	sv.Relaxed = true
  1369  	v := newVector(0, 1, 15, pair{})
  1370  	var prev, prevArray string
  1371  	for i := 0; i < 100000; i++ {
  1372  		s := rand.Intn(10)
  1373  		l := rand.Intn(5)
  1374  		j := rand.Intn(2)
  1375  		f := rand.Intn(2) < 1
  1376  		c.Check(sv.ApplyRange(s, s+l, func(e Equaler) Equaler {
  1377  			p := e.(pair)
  1378  			p[j] = f
  1379  			return p
  1380  		}), check.DeepEquals, nil)
  1381  		v.applyRange(s, s+l, func(e Equaler) Equaler {
  1382  			p := e.(pair)
  1383  			p[j] = f
  1384  			return p
  1385  		})
  1386  		now := sv.String()
  1387  		array := v.String()
  1388  		c.Assert(sv.min, check.DeepEquals, sv.t.Min(),
  1389  			check.Commentf("invalid tree after iteration %d: set [%d,%d) pair[%d]=%t:\nwas: %v\nis:  %s", i, s, s+l, j, f, prev, now),
  1390  		)
  1391  		c.Assert(sv.max, check.DeepEquals, sv.t.Max(),
  1392  			check.Commentf("invalid tree after iteration %d: set [%d,%d) pair[%d]=%t:\nwas: %v\nis:  %s", i, s, s+l, j, f, prev, now),
  1393  		)
  1394  		c.Assert(v.aggreesWith(sv), check.Equals, true,
  1395  			check.Commentf("vector disagreement after iteration %d: set [%d,%d) pair[%d]=%t:\nwas:   %s\narray: %v\nwas:   %s\nstep:  %s",
  1396  				i, s, s+l, j, f, prevArray, array, prev, now),
  1397  		)
  1398  		var last Equaler
  1399  		sv.Do(func(start, end int, e Equaler) {
  1400  			if e == last {
  1401  				c.Fatalf("iteration %d: setting pair[%d]=%t over [%d,%d) gives invalid vector near %d:\nwas: %s\nis:  %s\nwant:%s",
  1402  					i, j, f, s, s+l, start, prev, now, array)
  1403  			}
  1404  			last = e
  1405  		})
  1406  		prev = now
  1407  		prevArray = array
  1408  	}
  1409  }
  1410  
  1411  func (s *S) TestSetRangeFuzzing(c *check.C) {
  1412  	rand.Seed(2)
  1413  	sv, err := New(0, 1, pair{})
  1414  	c.Assert(err, check.Equals, nil)
  1415  	sv.Relaxed = true
  1416  	v := newVector(0, 1, 15, pair{})
  1417  	var prev, prevArray string
  1418  	for i := 0; i < 100000; i++ {
  1419  		s := rand.Intn(10)
  1420  		l := rand.Intn(5)
  1421  		f := pair{rand.Intn(2) < 1, rand.Intn(2) < 1}
  1422  		sv.SetRange(s, s+l, f)
  1423  		v.setRange(s, s+l, f)
  1424  		now := sv.String()
  1425  		array := v.String()
  1426  		c.Assert(sv.min, check.DeepEquals, sv.t.Min(),
  1427  			check.Commentf("invalid tree after iteration %d: set [%d,%d) to %#v:\nwas: %v\nis:  %s", i, s, s+l, f, prev, now),
  1428  		)
  1429  		c.Assert(sv.max, check.DeepEquals, sv.t.Max(),
  1430  			check.Commentf("invalid tree after iteration %d: set [%d,%d) to %#v:\nwas: %v\nis:  %s", i, s, s+l, f, prev, now),
  1431  		)
  1432  		c.Assert(v.aggreesWith(sv), check.Equals, true,
  1433  			check.Commentf("vector disagreement after iteration %d: set [%d,%d) to %#v:\nwas:   %s\narray: %v\nwas:   %s\nstep:  %s",
  1434  				i, s, s+l, f, prevArray, array, prev, now),
  1435  		)
  1436  		var last Equaler
  1437  		sv.Do(func(start, end int, e Equaler) {
  1438  			if e == last {
  1439  				c.Fatalf("iteration %d: setting pair=%#v over [%d,%d) gives invalid vector near %d:\nwas: %s\nis:  %s\nwant:%s",
  1440  					i, f, s, s+l, start, prev, now, array)
  1441  			}
  1442  			last = e
  1443  		})
  1444  		prev = now
  1445  		prevArray = array
  1446  	}
  1447  }
  1448  
  1449  func (s *S) TestAgreementFuzzing(c *check.C) {
  1450  	rand.Seed(1)
  1451  	mutV, err := New(0, 1, pair{})
  1452  	c.Assert(err, check.Equals, nil)
  1453  	mutV.Relaxed = true
  1454  	setV, err := New(0, 1, pair{})
  1455  	c.Assert(err, check.Equals, nil)
  1456  	setV.Relaxed = true
  1457  	var (
  1458  		prevSet, prevMut string
  1459  		setLen           int
  1460  	)
  1461  	// Set up agreeing representations of intervals.
  1462  	for i := 0; i < 100000; i++ {
  1463  		s := rand.Intn(1000)
  1464  		l := rand.Intn(50)
  1465  		setV.SetRange(s, s+l, pair{true, false})
  1466  		c.Assert(mutV.ApplyRange(s, s+l, func(e Equaler) Equaler {
  1467  			p := e.(pair)
  1468  			p[0] = true
  1469  			return p
  1470  		}), check.Equals, nil)
  1471  
  1472  		setNow := setV.String()
  1473  		mutNow := mutV.String()
  1474  		var mutLen int
  1475  		setLen = 0
  1476  		setV.Do(func(start, end int, e Equaler) {
  1477  			p := e.(pair)
  1478  			if p[0] {
  1479  				setLen += end - start
  1480  			}
  1481  		})
  1482  		mutV.Do(func(start, end int, e Equaler) {
  1483  			p := e.(pair)
  1484  			if p[0] {
  1485  				mutLen += end - start
  1486  			}
  1487  		})
  1488  		if setLen != mutLen {
  1489  			c.Fatalf("length disagreement after iteration %d: %d != %d\nset was: %s\nmut was: %s\nset now: %s\nmut now: %s",
  1490  				i, setLen, mutLen, prevSet, prevMut, setNow, mutNow)
  1491  		}
  1492  
  1493  		prevSet = setNow
  1494  		prevMut = mutNow
  1495  	}
  1496  
  1497  	// Mutate the other element of steps in the mutating vector, checking for changes
  1498  	// in position 0 of the steps.
  1499  	for i := 0; i < 100000; i++ {
  1500  		s := rand.Intn(1000)
  1501  		l := rand.Intn(50)
  1502  		c.Assert(mutV.ApplyRange(s, s+l, func(e Equaler) Equaler {
  1503  			p := e.(pair)
  1504  			p[1] = rand.Intn(2) < 1
  1505  			return p
  1506  		}), check.Equals, nil)
  1507  
  1508  		mutNow := mutV.String()
  1509  		var mutLen int
  1510  		mutV.Do(func(start, end int, e Equaler) {
  1511  			p := e.(pair)
  1512  			if p[0] {
  1513  				mutLen += end - start
  1514  			}
  1515  		})
  1516  		if setLen != mutLen {
  1517  			c.Fatalf("length disagreement after iteration %d: %d != %d\nmut was: %s\nmut now: %s",
  1518  				i, setLen, mutLen, prevMut, mutNow)
  1519  		}
  1520  
  1521  		prevMut = mutNow
  1522  	}
  1523  }
  1524  
  1525  // Benchmarks
  1526  
  1527  func applyRange(b *testing.B, coverage float64) {
  1528  	b.StopTimer()
  1529  	var (
  1530  		length = 100
  1531  		start  = 0
  1532  		end    = int(float64(b.N)/coverage) / length
  1533  		zero   = Int(0)
  1534  		pool   = make([]int, b.N)
  1535  	)
  1536  	if end == 0 {
  1537  		return
  1538  	}
  1539  	sv, _ := New(start, end, zero)
  1540  	for i := 0; i < b.N; i++ {
  1541  		pool[i] = rand.Intn(end)
  1542  	}
  1543  	b.StartTimer()
  1544  	for _, r := range pool {
  1545  		sv.ApplyRange(r, r+length, IncInt)
  1546  	}
  1547  }
  1548  
  1549  func BenchmarkApplyRangeXDense(b *testing.B) {
  1550  	applyRange(b, 1000)
  1551  }
  1552  func BenchmarkApplyRangeVDense(b *testing.B) {
  1553  	applyRange(b, 100)
  1554  }
  1555  func BenchmarkApplyRangeDense(b *testing.B) {
  1556  	applyRange(b, 10)
  1557  }
  1558  func BenchmarkApplyRangeUnity(b *testing.B) {
  1559  	applyRange(b, 1)
  1560  }
  1561  func BenchmarkApplyRangeSparse(b *testing.B) {
  1562  	applyRange(b, 0.1)
  1563  }
  1564  func BenchmarkApplyRangeVSparse(b *testing.B) {
  1565  	applyRange(b, 0.01)
  1566  }
  1567  func BenchmarkApplyRangeXSparse(b *testing.B) {
  1568  	applyRange(b, 0.001)
  1569  }
  1570  
  1571  func atFunc(b *testing.B, coverage float64) {
  1572  	b.StopTimer()
  1573  	var (
  1574  		length = 100
  1575  		start  = 0
  1576  		end    = int(float64(b.N)/coverage) / length
  1577  		zero   = Int(0)
  1578  	)
  1579  	if end == 0 {
  1580  		return
  1581  	}
  1582  	sv, _ := New(start, end, zero)
  1583  	for i := 0; i < b.N; i++ {
  1584  		r := rand.Intn(end)
  1585  		sv.ApplyRange(r, r+length, IncInt)
  1586  	}
  1587  	b.StartTimer()
  1588  	for i := 0; i < b.N; i++ {
  1589  		_, err := sv.At(rand.Intn(end))
  1590  		if err != nil {
  1591  			panic("cannot reach")
  1592  		}
  1593  	}
  1594  }
  1595  
  1596  func BenchmarkAtXDense(b *testing.B) {
  1597  	atFunc(b, 1000)
  1598  }
  1599  func BenchmarkAtVDense(b *testing.B) {
  1600  	atFunc(b, 100)
  1601  }
  1602  func BenchmarkAtDense(b *testing.B) {
  1603  	atFunc(b, 10)
  1604  }
  1605  func BenchmarkAtUnity(b *testing.B) {
  1606  	atFunc(b, 1)
  1607  }
  1608  func BenchmarkAtSparse(b *testing.B) {
  1609  	atFunc(b, 0.1)
  1610  }
  1611  func BenchmarkAtVSparse(b *testing.B) {
  1612  	atFunc(b, 0.01)
  1613  }
  1614  func BenchmarkAtXSparse(b *testing.B) {
  1615  	atFunc(b, 0.001)
  1616  }