Example #1
0
func TestIterator(t *testing.T) {
	t.Parallel()

	s := newMemStore()
	c := s.SetCollection("zup", nil)
	prev := []byte{}
	for i := 5; i < 100; i++ {
		data := mkNum(int64(i))
		c.Set(data, prev)
		prev = data
	}

	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)
			})
		})

	})
}