Index: impl/memory/gkvlite_iter_test.go |
diff --git a/impl/memory/gkvlite_iter_test.go b/impl/memory/gkvlite_iter_test.go |
deleted file mode 100644 |
index 2a873ffeca39dc925020034e3c3f8c7d7df6ce09..0000000000000000000000000000000000000000 |
--- a/impl/memory/gkvlite_iter_test.go |
+++ /dev/null |
@@ -1,283 +0,0 @@ |
-// Copyright 2015 The LUCI Authors. All rights reserved. |
-// Use of this source code is governed under the Apache License, Version 2.0 |
-// that can be found in the LICENSE file. |
- |
-package memory |
- |
-import ( |
- "bytes" |
- "testing" |
- |
- "github.com/luci/gae/service/datastore" |
- "github.com/luci/gae/service/datastore/serialize" |
- "github.com/luci/gkvlite" |
- "github.com/luci/luci-go/common/data/cmpbin" |
- . "github.com/smartystreets/goconvey/convey" |
-) |
- |
-func mkNum(n int64) []byte { |
- buf := &bytes.Buffer{} |
- _, err := cmpbin.WriteInt(buf, n) |
- memoryCorruption(err) |
- |
- return buf.Bytes() |
-} |
- |
-func readNum(data []byte) int64 { |
- ret, _, err := cmpbin.ReadInt(bytes.NewBuffer(data)) |
- memoryCorruption(err) |
- |
- return ret |
-} |
- |
-func TestIterator(t *testing.T) { |
- t.Parallel() |
- |
- s := newMemStore() |
- c := s.GetOrCreateCollection("zup") |
- prev := []byte{} |
- for i := 5; i < 100; i++ { |
- data := mkNum(int64(i)) |
- c.Set(data, prev) |
- prev = data |
- } |
- c = s.Snapshot().GetCollection("zup") |
- |
- get := func(c C, t *iterator) interface{} { |
- ret := interface{}(nil) |
- t.next(nil, func(i *gkvlite.Item) { |
- if i != nil { |
- ret = readNum(i.Key) |
- } |
- }) |
- return ret |
- } |
- |
- skipGet := func(c C, t *iterator, skipTo int64) interface{} { |
- ret := interface{}(nil) |
- t.next(mkNum(skipTo), func(i *gkvlite.Item) { |
- if i != nil { |
- ret = readNum(i.Key) |
- } |
- }) |
- return ret |
- } |
- |
- Convey("Test iterator", t, func() { |
- Convey("start at nil", func(ctx C) { |
- t := (&iterDefinition{c: c}).mkIter() |
- defer t.stop() |
- So(get(ctx, t), ShouldEqual, 5) |
- So(get(ctx, t), ShouldEqual, 6) |
- So(get(ctx, t), ShouldEqual, 7) |
- |
- Convey("And can skip", func(ctx C) { |
- So(skipGet(ctx, t, 10), ShouldEqual, 10) |
- So(get(ctx, t), ShouldEqual, 11) |
- |
- Convey("But not forever", func(ctx C) { |
- t.next(mkNum(200), func(i *gkvlite.Item) { |
- ctx.So(i, ShouldBeNil) |
- }) |
- t.next(nil, func(i *gkvlite.Item) { |
- ctx.So(i, ShouldBeNil) |
- }) |
- }) |
- }) |
- |
- Convey("Can iterate explicitly", func(ctx C) { |
- So(skipGet(ctx, t, 7), ShouldEqual, 8) |
- So(skipGet(ctx, t, 8), ShouldEqual, 9) |
- |
- // Giving the immediately next key doesn't cause an internal reset. |
- So(skipGet(ctx, t, 10), ShouldEqual, 10) |
- }) |
- |
- Convey("Can stop", func(ctx C) { |
- t.stop() |
- t.next(mkNum(200), func(i *gkvlite.Item) { |
- ctx.So(i, ShouldBeNil) |
- }) |
- t.next(nil, func(i *gkvlite.Item) { |
- ctx.So(i, ShouldBeNil) |
- }) |
- So(t.stop, ShouldNotPanic) |
- }) |
- |
- Convey("Going backwards is ignored", func(ctx C) { |
- So(skipGet(ctx, t, 3), ShouldEqual, 8) |
- So(get(ctx, t), ShouldEqual, 9) |
- So(skipGet(ctx, t, 20), ShouldEqual, 20) |
- So(get(ctx, t), ShouldEqual, 21) |
- }) |
- |
- Convey("will stop at the end of the list", func(ctx C) { |
- So(skipGet(ctx, t, 95), ShouldEqual, 95) |
- So(get(ctx, t), ShouldEqual, 96) |
- So(get(ctx, t), ShouldEqual, 97) |
- So(get(ctx, t), ShouldEqual, 98) |
- So(get(ctx, t), ShouldEqual, 99) |
- So(get(ctx, t), ShouldBeNil) |
- So(get(ctx, t), ShouldBeNil) |
- }) |
- }) |
- |
- Convey("can have caps on both sides", func(ctx C) { |
- t := (&iterDefinition{c: c, start: mkNum(20), end: mkNum(25)}).mkIter() |
- So(get(ctx, t), ShouldEqual, 20) |
- So(get(ctx, t), ShouldEqual, 21) |
- So(get(ctx, t), ShouldEqual, 22) |
- So(get(ctx, t), ShouldEqual, 23) |
- So(get(ctx, t), ShouldEqual, 24) |
- t.next(nil, func(i *gkvlite.Item) { |
- ctx.So(i, ShouldBeNil) |
- }) |
- }) |
- |
- Convey("can skip over starting cap", func(ctx C) { |
- t := (&iterDefinition{c: c, start: mkNum(20), end: mkNum(25)}).mkIter() |
- So(skipGet(ctx, t, 22), ShouldEqual, 22) |
- So(get(ctx, t), ShouldEqual, 23) |
- So(get(ctx, t), ShouldEqual, 24) |
- t.next(nil, func(i *gkvlite.Item) { |
- ctx.So(i, ShouldBeNil) |
- }) |
- }) |
- |
- }) |
-} |
- |
-func TestMultiIteratorSimple(t *testing.T) { |
- t.Parallel() |
- |
- // Simulate an index with 2 columns (int and int). |
- vals := [][]int64{ |
- {1, 0}, |
- {1, 2}, |
- {1, 4}, |
- {1, 7}, |
- {1, 9}, |
- {3, 10}, |
- {3, 11}, |
- } |
- |
- valBytes := make([][]byte, len(vals)) |
- for i, nms := range vals { |
- numbs := make([][]byte, len(nms)) |
- for j, n := range nms { |
- numbs[j] = mkNum(n) |
- } |
- valBytes[i] = serialize.Join(numbs...) |
- } |
- |
- otherVals := [][]int64{ |
- {3, 0}, |
- {4, 10}, |
- {19, 7}, |
- {20, 2}, |
- {20, 3}, |
- {20, 4}, |
- {20, 8}, |
- {20, 11}, |
- } |
- |
- otherValBytes := make([][]byte, len(otherVals)) |
- for i, nms := range otherVals { |
- numbs := make([][]byte, len(nms)) |
- for i, n := range nms { |
- numbs[i] = mkNum(n) |
- } |
- otherValBytes[i] = serialize.Join(numbs...) |
- } |
- |
- Convey("Test MultiIterator", t, func() { |
- s := newMemStore() |
- c := s.GetOrCreateCollection("zup1") |
- for _, row := range valBytes { |
- c.Set(row, []byte{}) |
- } |
- c2 := s.GetOrCreateCollection("zup2") |
- for _, row := range otherValBytes { |
- c2.Set(row, []byte{}) |
- } |
- c = s.Snapshot().GetCollection("zup1") |
- c2 = s.Snapshot().GetCollection("zup2") |
- |
- Convey("can join the same collection twice", func() { |
- // get just the (1, *) |
- // starting at (1, 2) (i.e. >= 2) |
- // ending at (1, 4) (i.e. < 7) |
- defs := []*iterDefinition{ |
- {c: c, prefix: mkNum(1), prefixLen: len(mkNum(1)), start: mkNum(2), end: mkNum(7)}, |
- {c: c, prefix: mkNum(1), prefixLen: len(mkNum(1)), start: mkNum(2), end: mkNum(7)}, |
- } |
- |
- i := 1 |
- So(multiIterate(defs, func(suffix []byte) error { |
- So(readNum(suffix), ShouldEqual, vals[i][1]) |
- i++ |
- return nil |
- }), shouldBeSuccessful) |
- |
- So(i, ShouldEqual, 3) |
- }) |
- |
- Convey("can make empty iteration", func() { |
- // get just the (20, *) (doesn't exist) |
- defs := []*iterDefinition{ |
- {c: c, prefix: mkNum(20)}, |
- {c: c, prefix: mkNum(20)}, |
- } |
- |
- i := 0 |
- So(multiIterate(defs, func(suffix []byte) error { |
- panic("never") |
- }), shouldBeSuccessful) |
- |
- So(i, ShouldEqual, 0) |
- }) |
- |
- Convey("can join (other, val, val)", func() { |
- // 'other' must start with 20, 'vals' must start with 1 |
- // no range constraints |
- defs := []*iterDefinition{ |
- {c: c2, prefix: mkNum(20)}, |
- {c: c, prefix: mkNum(1)}, |
- {c: c, prefix: mkNum(1)}, |
- } |
- |
- expect := []int64{2, 4} |
- i := 0 |
- So(multiIterate(defs, func(suffix []byte) error { |
- So(readNum(suffix), ShouldEqual, expect[i]) |
- i++ |
- return nil |
- }), shouldBeSuccessful) |
- }) |
- |
- Convey("Can stop early", func() { |
- defs := []*iterDefinition{ |
- {c: c, prefix: mkNum(1), prefixLen: len(mkNum(1))}, |
- {c: c, prefix: mkNum(1), prefixLen: len(mkNum(1))}, |
- } |
- |
- i := 0 |
- So(multiIterate(defs, func(suffix []byte) error { |
- So(readNum(suffix), ShouldEqual, vals[i][1]) |
- i++ |
- return nil |
- }), shouldBeSuccessful) |
- So(i, ShouldEqual, 5) |
- |
- i = 0 |
- So(multiIterate(defs, func(suffix []byte) error { |
- So(readNum(suffix), ShouldEqual, vals[i][1]) |
- i++ |
- return datastore.Stop |
- }), shouldBeSuccessful) |
- So(i, ShouldEqual, 1) |
- }) |
- |
- }) |
- |
-} |