From 5422535d7d7b38afd89df3ddd941f4b0e51559f2 Mon Sep 17 00:00:00 2001 From: Bo Du Date: Wed, 26 Feb 2020 17:16:13 -0500 Subject: [PATCH] Remove implicit cloning of time ranges. --- .../bootstrap/bootstrapper/fs/source.go | 11 ++-- .../bootstrapper/fs/source_data_test.go | 21 ++++---- .../fs/source_index_bench_test.go | 2 +- .../bootstrapper/fs/source_index_test.go | 4 +- .../bootstrap/bootstrapper/peers/source.go | 4 +- .../bootstrapper/peers/source_data_test.go | 32 +++++------ .../bootstrapper/peers/source_test.go | 2 +- .../storage/bootstrap/bootstrapper/persist.go | 4 +- .../storage/bootstrap/bootstrapper/ranges.go | 2 +- .../bootstrap/result/result_data_test.go | 20 +++---- .../storage/bootstrap/result/shard_ranges.go | 10 ++-- src/dbnode/storage/bootstrap/util.go | 6 ++- src/dbnode/storage/index.go | 2 +- src/x/time/ranges.go | 41 +++++++------- src/x/time/ranges_test.go | 53 ++++++++++--------- 15 files changed, 111 insertions(+), 103 deletions(-) diff --git a/src/dbnode/storage/bootstrap/bootstrapper/fs/source.go b/src/dbnode/storage/bootstrap/bootstrapper/fs/source.go index d066de6735..4701b58f7f 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/fs/source.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/fs/source.go @@ -247,7 +247,7 @@ func (s *fileSystemSource) shardAvailability( w := time.Duration(info.BlockSize) currRange := xtime.Range{Start: t, End: t.Add(w)} if targetRangesForShard.Overlaps(currRange) { - tr = tr.AddRange(currRange) + tr.AddRange(currRange) } } return tr @@ -416,7 +416,7 @@ func (s *fileSystemSource) loadShardReadersDataIntoShardResult( if err == nil && run == bootstrapIndexRunType { // Mark index block as fulfilled. fulfilled := result.ShardTimeRanges{ - shard: xtime.Ranges{}.AddRange(timeRange), + shard: xtime.NewRanges(timeRange), } err = runResult.index.IndexResults().MarkFulfilled(start, fulfilled, ns.Options().IndexOptions()) @@ -429,7 +429,7 @@ func (s *fileSystemSource) loadShardReadersDataIntoShardResult( if err == nil { fulfilled := result.ShardTimeRanges{ - shard: xtime.Ranges{}.AddRange(timeRange), + shard: xtime.NewRanges(timeRange), } totalFulfilledRanges.AddRanges(fulfilled) remainingRanges.Subtract(fulfilled) @@ -722,7 +722,8 @@ func (s *fileSystemSource) bootstrapDataRunResultFromAvailability( continue } availability := s.shardAvailability(md.ID(), shard, ranges) - remaining := ranges.RemoveRanges(availability) + remaining := ranges.Clone() + remaining.RemoveRanges(availability) if !remaining.IsEmpty() { unfulfilled.AddRanges(result.ShardTimeRanges{ shard: remaining, @@ -782,7 +783,7 @@ func (s *fileSystemSource) bootstrapFromIndexPersistedBlocks( if !intersects { continue } - willFulfill[shard] = willFulfill[shard].AddRange(intersection) + willFulfill[shard].AddRange(intersection) } } diff --git a/src/dbnode/storage/bootstrap/bootstrapper/fs/source_data_test.go b/src/dbnode/storage/bootstrap/bootstrapper/fs/source_data_test.go index 2a68ed358a..2094398d87 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/fs/source_data_test.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/fs/source_data_test.go @@ -181,7 +181,7 @@ func testBootstrappingIndexShardTimeRanges() result.ShardTimeRanges { // `testBlockSize` rather than `testIndexSize` since the files generated // by this test use 2 hour (which is `testBlockSize`) reader blocks. return map[uint32]xtime.Ranges{ - testShard: xtime.Ranges{}.AddRange(xtime.Range{ + testShard: xtime.NewRanges(xtime.Range{ Start: testStart.Add(testBlockSize), End: testStart.Add(11 * time.Hour), }), @@ -284,10 +284,13 @@ func sortedTagsFromTagsMap(tags map[string]string) ident.Tags { func validateTimeRanges(t *testing.T, tr xtime.Ranges, expected xtime.Ranges) { // Make range eclipses expected - require.True(t, expected.RemoveRanges(tr).IsEmpty()) + expectedWithRemovedRanges := expected.Clone() + expectedWithRemovedRanges.RemoveRanges(tr) + require.True(t, expectedWithRemovedRanges.IsEmpty()) // Now make sure no ranges outside of expected - expectedWithAddedRanges := expected.AddRanges(tr) + expectedWithAddedRanges := expected.Clone() + expectedWithAddedRanges.AddRanges(tr) require.Equal(t, expected.Len(), expectedWithAddedRanges.Len()) iter := expected.Iter() @@ -388,9 +391,9 @@ func TestAvailableTimeRangeFilter(t *testing.T) { require.Equal(t, 1, len(res)) require.NotNil(t, res[testShard]) - expected := xtime.Ranges{}. - AddRange(xtime.Range{Start: testStart, End: testStart.Add(2 * time.Hour)}). - AddRange(xtime.Range{Start: testStart.Add(10 * time.Hour), End: testStart.Add(12 * time.Hour)}) + expected := xtime.NewRanges( + xtime.Range{Start: testStart, End: testStart.Add(2 * time.Hour)}, + xtime.Range{Start: testStart.Add(10 * time.Hour), End: testStart.Add(12 * time.Hour)}) validateTimeRanges(t, res[testShard], expected) } @@ -415,9 +418,9 @@ func TestAvailableTimeRangePartialError(t *testing.T) { require.Equal(t, 1, len(res)) require.NotNil(t, res[testShard]) - expected := xtime.Ranges{}. - AddRange(xtime.Range{Start: testStart, End: testStart.Add(2 * time.Hour)}). - AddRange(xtime.Range{Start: testStart.Add(10 * time.Hour), End: testStart.Add(12 * time.Hour)}) + expected := xtime.NewRanges( + xtime.Range{Start: testStart, End: testStart.Add(2 * time.Hour)}, + xtime.Range{Start: testStart.Add(10 * time.Hour), End: testStart.Add(12 * time.Hour)}) validateTimeRanges(t, res[testShard], expected) } diff --git a/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_bench_test.go b/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_bench_test.go index 5f9b763bcc..59b99fa657 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_bench_test.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_bench_test.go @@ -132,7 +132,7 @@ func BenchmarkBootstrapIndex(b *testing.B) { max = end } - ranges = ranges.AddRange(xtime.Range{Start: start, End: end}) + ranges.AddRange(xtime.Range{Start: start, End: end}) // Override the block size if different. namespaceOpts := testNamespaceMetadata.Options() diff --git a/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_test.go b/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_test.go index a28f2d6674..b268d3680c 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_test.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/fs/source_index_test.go @@ -77,7 +77,7 @@ func newTestBootstrapIndexTimes( } shardTimeRanges := map[uint32]xtime.Ranges{ - testShard: xtime.Ranges{}.AddRange(xtime.Range{ + testShard: xtime.NewRanges(xtime.Range{ Start: start, End: end, }), @@ -567,7 +567,7 @@ func TestBootstrapIndexWithPersistForIndexBlockAtRetentionEdge(t *testing.T) { // NB(bodu): Simulate requesting bootstrapping of two whole index blocks instead of 3 data blocks (1.5 index blocks). times.shardTimeRanges = map[uint32]xtime.Ranges{ - testShard: xtime.Ranges{}.AddRange(xtime.Range{ + testShard: xtime.NewRanges(xtime.Range{ Start: firstIndexBlockStart, End: times.end, }), diff --git a/src/dbnode/storage/bootstrap/bootstrapper/peers/source.go b/src/dbnode/storage/bootstrap/bootstrapper/peers/source.go index e78f323595..9d8d29a13e 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/peers/source.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/peers/source.go @@ -767,7 +767,7 @@ func (s *peersSource) processReaders( if err == nil { // Mark index block as fulfilled. fulfilled := result.ShardTimeRanges{ - shard: xtime.Ranges{}.AddRange(timeRange), + shard: xtime.NewRanges(timeRange), } err = r.IndexResults().MarkFulfilled(start, fulfilled, idxOpts) @@ -775,7 +775,7 @@ func (s *peersSource) processReaders( if err == nil { remainingRanges.Subtract(result.ShardTimeRanges{ - shard: xtime.Ranges{}.AddRange(timeRange), + shard: xtime.NewRanges(timeRange), }) } else { s.log.Error(err.Error(), diff --git a/src/dbnode/storage/bootstrap/bootstrapper/peers/source_data_test.go b/src/dbnode/storage/bootstrap/bootstrapper/peers/source_data_test.go index cbb14f6f98..e650b31fb6 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/peers/source_data_test.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/peers/source_data_test.go @@ -734,18 +734,18 @@ func TestPeersSourceMarksUnfulfilledOnPersistenceErrors(t *testing.T) { require.NoError(t, err) target := result.ShardTimeRanges{ - 0: xtime.Ranges{}. - AddRange(xtime.Range{Start: start, End: midway}). - AddRange(xtime.Range{Start: midway, End: end}), - 1: xtime.Ranges{}. - AddRange(xtime.Range{Start: start, End: midway}). - AddRange(xtime.Range{Start: midway, End: end}), - 2: xtime.Ranges{}. - AddRange(xtime.Range{Start: start, End: midway}). - AddRange(xtime.Range{Start: midway, End: end}), - 3: xtime.Ranges{}. - AddRange(xtime.Range{Start: start, End: midway}). - AddRange(xtime.Range{Start: midway, End: end}), + 0: xtime.NewRanges( + xtime.Range{Start: start, End: midway}, + xtime.Range{Start: midway, End: end}), + 1: xtime.NewRanges( + xtime.Range{Start: start, End: midway}, + xtime.Range{Start: midway, End: end}), + 2: xtime.NewRanges( + xtime.Range{Start: start, End: midway}, + xtime.Range{Start: midway, End: end}), + 3: xtime.NewRanges( + xtime.Range{Start: start, End: midway}, + xtime.Range{Start: midway, End: end}), } tester := bootstrap.BuildNamespacesTester(t, testRunOptsWithPersist, target, testNsMd) @@ -753,10 +753,10 @@ func TestPeersSourceMarksUnfulfilledOnPersistenceErrors(t *testing.T) { tester.TestReadWith(src) expectedRanges := result.ShardTimeRanges{ - 0: xtime.Ranges{}.AddRange(xtime.Range{Start: start, End: midway}), - 1: xtime.Ranges{}.AddRange(xtime.Range{Start: start, End: midway}), - 2: xtime.Ranges{}.AddRange(xtime.Range{Start: start, End: midway}), - 3: xtime.Ranges{}.AddRange(xtime.Range{Start: start, End: midway}), + 0: xtime.NewRanges(xtime.Range{Start: start, End: midway}), + 1: xtime.NewRanges(xtime.Range{Start: start, End: midway}), + 2: xtime.NewRanges(xtime.Range{Start: start, End: midway}), + 3: xtime.NewRanges(xtime.Range{Start: start, End: midway}), } // NB(bodu): There is no time series data written to disk so all ranges fail to be fulfilled. diff --git a/src/dbnode/storage/bootstrap/bootstrapper/peers/source_test.go b/src/dbnode/storage/bootstrap/bootstrapper/peers/source_test.go index eba8f23150..efad43e89b 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/peers/source_test.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/peers/source_test.go @@ -53,7 +53,7 @@ func TestPeersSourceAvailableDataAndIndex(t *testing.T) { numShards = uint32(4) blockStart = time.Now().Truncate(blockSize) shardTimeRangesToBootstrap = result.ShardTimeRanges{} - bootstrapRanges = xtime.Ranges{}.AddRange(xtime.Range{ + bootstrapRanges = xtime.NewRanges(xtime.Range{ Start: blockStart, End: blockStart.Add(blockSize), }) diff --git a/src/dbnode/storage/bootstrap/bootstrapper/persist.go b/src/dbnode/storage/bootstrap/bootstrapper/persist.go index 1df2856f00..c5866616d9 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/persist.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/persist.go @@ -94,7 +94,7 @@ func PersistBootstrapIndexSegment( expectedRanges := make(result.ShardTimeRanges, len(requestedRanges)) for shard := range requestedRanges { shards[shard] = struct{}{} - expectedRanges[shard] = xtime.Ranges{}.AddRange(xtime.Range{ + expectedRanges[shard] = xtime.NewRanges(xtime.Range{ Start: expectedRangeStart, End: expectedRangeEnd, }) @@ -253,7 +253,7 @@ func BuildBootstrapIndexSegment( expectedRanges := make(result.ShardTimeRanges, len(requestedRanges)) for shard := range requestedRanges { - expectedRanges[shard] = xtime.Ranges{}.AddRange(xtime.Range{ + expectedRanges[shard] = xtime.NewRanges(xtime.Range{ Start: expectedRangeStart, End: expectedRangeEnd, }) diff --git a/src/dbnode/storage/bootstrap/bootstrapper/ranges.go b/src/dbnode/storage/bootstrap/bootstrapper/ranges.go index 1c5006c64a..4095fa01a9 100644 --- a/src/dbnode/storage/bootstrap/bootstrapper/ranges.go +++ b/src/dbnode/storage/bootstrap/bootstrapper/ranges.go @@ -58,7 +58,7 @@ func NewShardTimeRangesTimeWindowGroups( continue } // Add to this range. - group[shard] = group[shard].AddRange(intersection) + group[shard].AddRange(intersection) } } diff --git a/src/dbnode/storage/bootstrap/result/result_data_test.go b/src/dbnode/storage/bootstrap/result/result_data_test.go index 2e5eb242b3..6cd36a4dac 100644 --- a/src/dbnode/storage/bootstrap/result/result_data_test.go +++ b/src/dbnode/storage/bootstrap/result/result_data_test.go @@ -375,13 +375,9 @@ func TestShardTimeRangesString(t *testing.T) { } str := ShardTimeRanges{ - 0: xtime.NewRanges(xtime.Range{ - Start: ts[0][0], - End: ts[0][1], - }).AddRange(xtime.Range{ - Start: ts[1][0], - End: ts[1][1], - }), + 0: xtime.NewRanges( + xtime.Range{Start: ts[0][0], End: ts[0][1]}, + xtime.Range{Start: ts[1][0], End: ts[1][1]}), 1: xtime.NewRanges(xtime.Range{ Start: ts[2][0], End: ts[2][1], @@ -400,13 +396,9 @@ func TestShardTimeRangesSummaryString(t *testing.T) { start := time.Unix(1472824800, 0) str := ShardTimeRanges{ - 0: xtime.NewRanges(xtime.Range{ - Start: start, - End: start.Add(testBlockSize), - }).AddRange(xtime.Range{ - Start: start.Add(2 * testBlockSize), - End: start.Add(4 * testBlockSize), - }), + 0: xtime.NewRanges( + xtime.Range{Start: start, End: start.Add(testBlockSize)}, + xtime.Range{Start: start.Add(2 * testBlockSize), End: start.Add(4 * testBlockSize)}), 1: xtime.NewRanges(xtime.Range{ Start: start, End: start.Add(2 * testBlockSize), diff --git a/src/dbnode/storage/bootstrap/result/shard_ranges.go b/src/dbnode/storage/bootstrap/result/shard_ranges.go index 2d547b913a..cab3121a8a 100644 --- a/src/dbnode/storage/bootstrap/result/shard_ranges.go +++ b/src/dbnode/storage/bootstrap/result/shard_ranges.go @@ -80,7 +80,9 @@ func (r ShardTimeRanges) Equal(other ShardTimeRanges) bool { func (r ShardTimeRanges) Copy() ShardTimeRanges { result := make(map[uint32]xtime.Ranges, len(r)) for shard, ranges := range r { - result[shard] = xtime.Ranges{}.AddRanges(ranges) + newRanges := xtime.NewRanges() + newRanges.AddRanges(ranges) + result[shard] = newRanges } return result } @@ -92,7 +94,8 @@ func (r ShardTimeRanges) AddRanges(other ShardTimeRanges) { continue } if existing, ok := r[shard]; ok { - r[shard] = existing.AddRanges(ranges) + existing.AddRanges(ranges) + r[shard] = existing } else { r[shard] = ranges } @@ -123,7 +126,8 @@ func (r ShardTimeRanges) Subtract(other ShardTimeRanges) { continue } - subtractedRanges := ranges.RemoveRanges(otherRanges) + subtractedRanges := ranges.Clone() + subtractedRanges.RemoveRanges(otherRanges) if subtractedRanges.IsEmpty() { delete(r, shard) } else { diff --git a/src/dbnode/storage/bootstrap/util.go b/src/dbnode/storage/bootstrap/util.go index f213f4bca3..d2e5e5ad21 100644 --- a/src/dbnode/storage/bootstrap/util.go +++ b/src/dbnode/storage/bootstrap/util.go @@ -551,14 +551,16 @@ func (nt *NamespacesTester) TestReadWith(s Source) { func validateRanges(ac xtime.Ranges, ex xtime.Ranges) error { // Make range eclipses expected. - removedRange := ex.RemoveRanges(ac) + removedRange := ex.Clone() + removedRange.RemoveRanges(ac) if !removedRange.IsEmpty() { return fmt.Errorf("actual range %v does not match expected range %v "+ "diff: %v", ac, ex, removedRange) } // Now make sure no ranges outside of expected. - expectedWithAddedRanges := ex.AddRanges(ac) + expectedWithAddedRanges := ex.Clone() + expectedWithAddedRanges.AddRanges(ac) if ex.Len() != expectedWithAddedRanges.Len() { return fmt.Errorf("expected with re-added ranges not equal") } diff --git a/src/dbnode/storage/index.go b/src/dbnode/storage/index.go index e2a0d3aafa..c6c2a050ae 100644 --- a/src/dbnode/storage/index.go +++ b/src/dbnode/storage/index.go @@ -1352,7 +1352,7 @@ func (i *nsIndex) blocksForQueryWithRLock(queryRange xtime.Ranges) ([]index.Bloc } // Remove this range from the query range. - queryRange = queryRange.RemoveRange(blockRange) + queryRange.RemoveRange(blockRange) blocks = append(blocks, block) } diff --git a/src/x/time/ranges.go b/src/x/time/ranges.go index 1106f54566..2156a9f377 100644 --- a/src/x/time/ranges.go +++ b/src/x/time/ranges.go @@ -32,11 +32,11 @@ type Ranges struct { // NewRanges constructs a new Ranges object comprising the provided ranges. func NewRanges(ranges ...Range) Ranges { - var result Ranges + res := Ranges{sortedRanges: list.New()} for _, r := range ranges { - result = result.AddRange(r) + res.AddRange(r) } - return result + return res } // Len returns the number of ranges included. @@ -66,37 +66,35 @@ func (tr Ranges) Overlaps(r Range) bool { } // AddRange adds the time range to the collection of ranges. -func (tr Ranges) AddRange(r Range) Ranges { - res := tr.clone() - res.addRangeInPlace(r) - return res +func (tr Ranges) AddRange(r Range) { + if tr.sortedRanges == nil { + tr.sortedRanges = list.New() + } + tr.addRangeInPlace(r) } // AddRanges adds the time ranges. -func (tr Ranges) AddRanges(other Ranges) Ranges { - res := tr.clone() +func (tr Ranges) AddRanges(other Ranges) { + if tr.sortedRanges == nil { + tr.sortedRanges = list.New() + } it := other.Iter() for it.Next() { - res.addRangeInPlace(it.Value()) + tr.addRangeInPlace(it.Value()) } - return res } // RemoveRange removes the time range from the collection of ranges. -func (tr Ranges) RemoveRange(r Range) Ranges { - res := tr.clone() - res.removeRangeInPlace(r) - return res +func (tr Ranges) RemoveRange(r Range) { + tr.removeRangeInPlace(r) } // RemoveRanges removes the given time ranges from the current one. -func (tr Ranges) RemoveRanges(other Ranges) Ranges { - res := tr.clone() +func (tr Ranges) RemoveRanges(other Ranges) { it := other.Iter() for it.Next() { - res.removeRangeInPlace(it.Value()) + tr.removeRangeInPlace(it.Value()) } - return res } // Iter returns an iterator that iterates over the time ranges included. @@ -104,6 +102,11 @@ func (tr Ranges) Iter() *RangeIter { return newRangeIter(tr.sortedRanges) } +// Clone makes a clone of the time ranges. +func (tr Ranges) Clone() Ranges { + return tr.clone() +} + // String returns the string representation of the range. func (tr Ranges) String() string { var buf bytes.Buffer diff --git a/src/x/time/ranges_test.go b/src/x/time/ranges_test.go index 1cf26dcb21..889bcf13a7 100644 --- a/src/x/time/ranges_test.go +++ b/src/x/time/ranges_test.go @@ -68,18 +68,17 @@ func getRangesToRemove() []Range { } func getPopulatedRanges(ranges []Range, start, end int) Ranges { - var tr Ranges + tr := NewRanges() for _, r := range ranges[start:end] { - tr = tr.AddRange(r) + tr.AddRange(r) } return tr } func TestIsEmpty(t *testing.T) { - var tr Ranges + tr := NewRanges() require.True(t, tr.IsEmpty()) - tr = tr.clone() tr.sortedRanges.PushBack(Range{}) require.False(t, tr.IsEmpty()) } @@ -87,9 +86,12 @@ func TestIsEmpty(t *testing.T) { func TestNewRanges(t *testing.T) { rangesToAdd := getRangesToAdd() exp := getPopulatedRanges(rangesToAdd, 0, len(rangesToAdd)) + clone := exp.Clone() obs := NewRanges(rangesToAdd...) - require.True(t, exp.RemoveRanges(obs).IsEmpty()) - require.True(t, obs.RemoveRanges(exp).IsEmpty()) + exp.RemoveRanges(clone) + require.True(t, exp.IsEmpty()) + obs.RemoveRanges(clone) + require.True(t, obs.IsEmpty()) } func TestClone(t *testing.T) { @@ -100,14 +102,14 @@ func TestClone(t *testing.T) { validateResult(t, tr, expectedResults) cloned := tr.clone() - tr = tr.RemoveRange(rangesToAdd[0]) + tr.RemoveRange(rangesToAdd[0]) validateResult(t, cloned, expectedResults) validateResult(t, tr, []Range{rangesToAdd[3], rangesToAdd[2], rangesToAdd[1]}) } func TestAddRange(t *testing.T) { - var tr Ranges - tr = tr.AddRange(Range{}) + tr := NewRanges() + tr.AddRange(Range{}) validateResult(t, tr, []Range{}) rangestoAdd := getRangesToAdd() @@ -121,9 +123,9 @@ func TestAddRange(t *testing.T) { {{Start: testStart.Add(-10 * time.Second), End: testStart.Add(15 * time.Second)}}, } - saved := tr + saved := tr.Clone() for i, r := range rangestoAdd { - tr = tr.AddRange(r) + tr.AddRange(r) validateResult(t, tr, expectedResults[i]) } validateResult(t, saved, []Range{}) @@ -133,14 +135,14 @@ func TestAddRanges(t *testing.T) { rangesToAdd := getRangesToAdd() tr := getPopulatedRanges(rangesToAdd, 0, 4) - tr = tr.AddRanges(Ranges{}) + tr.AddRanges(Ranges{}) expectedResults := []Range{rangesToAdd[3], rangesToAdd[2], rangesToAdd[0], rangesToAdd[1]} validateResult(t, tr, expectedResults) tr2 := getPopulatedRanges(rangesToAdd, 4, 7) - saved := tr - tr = tr.AddRanges(tr2) + saved := tr.Clone() + tr.AddRanges(tr2) expectedResults2 := []Range{{Start: testStart.Add(-10 * time.Second), End: testStart.Add(15 * time.Second)}} validateResult(t, tr, expectedResults2) @@ -173,16 +175,16 @@ func TestRemoveRange(t *testing.T) { }, } - saved := tr + saved := tr.Clone() for i, r := range rangesToRemove { - tr = tr.RemoveRange(r) + tr.RemoveRange(r) validateResult(t, tr, expectedResults[i]) } - tr = tr.RemoveRange(Range{}) + tr.RemoveRange(Range{}) validateResult(t, tr, expectedResults[3]) - tr = tr.RemoveRange(Range{ + tr.RemoveRange(Range{ Start: testStart.Add(-10 * time.Second), End: testStart.Add(15 * time.Second), }) @@ -192,7 +194,7 @@ func TestRemoveRange(t *testing.T) { func TestRemoveRanges(t *testing.T) { tr := getPopulatedRanges(getRangesToAdd(), 0, 4) - tr = tr.RemoveRanges(Ranges{}) + tr.RemoveRanges(Ranges{}) expectedResults := []Range{ {Start: testStart.Add(-8 * time.Second), End: testStart.Add(-5 * time.Second)}, @@ -202,9 +204,9 @@ func TestRemoveRanges(t *testing.T) { } validateResult(t, tr, expectedResults) - saved := tr + saved := tr.Clone() tr2 := getPopulatedRanges(getRangesToRemove(), 0, 4) - tr = tr.RemoveRanges(tr2) + tr.RemoveRanges(tr2) expectedResults2 := []Range{ {Start: testStart.Add(-8 * time.Second), End: testStart.Add(-6 * time.Second)}, @@ -236,15 +238,16 @@ func TestRangesIter(t *testing.T) { {Start: testStart.Add(10 * time.Second), End: testStart.Add(15 * time.Second)}, } validateIter(t, tr.Iter(), expectedResults) - tr = tr.RemoveRange(rangesToAdd[2]) + tr.RemoveRange(rangesToAdd[2]) validateIter(t, tr.Iter(), append(expectedResults[:1], expectedResults[2:]...)) } func TestRangesString(t *testing.T) { - var tr Ranges + tr := NewRanges() require.Equal(t, "[]", tr.String()) start := time.Unix(1465430400, 0).UTC() - tr = tr.AddRange(Range{Start: start, End: start.Add(2 * time.Hour)}). - AddRange(Range{Start: start.Add(4 * time.Hour), End: start.Add(5 * time.Hour)}) + tr.AddRanges(NewRanges( + Range{Start: start, End: start.Add(2 * time.Hour)}, + Range{Start: start.Add(4 * time.Hour), End: start.Add(5 * time.Hour)})) require.Equal(t, "[(2016-06-09 00:00:00 +0000 UTC,2016-06-09 02:00:00 +0000 UTC),(2016-06-09 04:00:00 +0000 UTC,2016-06-09 05:00:00 +0000 UTC)]", tr.String()) }