From 49f1ba48452f81720b3c184f659893dc115dd714 Mon Sep 17 00:00:00 2001 From: rojazz1999 Date: Tue, 9 Aug 2016 15:17:44 +0800 Subject: [PATCH] Ascend* & Descend* results should be limited by the item's value when an index is provided --- buntdb.go | 9 ++++-- buntdb_test.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/buntdb.go b/buntdb.go index 00394fa..fc4d605 100644 --- a/buntdb.go +++ b/buntdb.go @@ -1230,8 +1230,13 @@ func (tx *Tx) scan( // create some limit items var itemA, itemB *dbItem if gt || lt { - itemA = &dbItem{key: start} - itemB = &dbItem{key: stop} + if index == "" { + itemA = &dbItem{key: start} + itemB = &dbItem{key: stop} + } else { + itemA = &dbItem{val: start} + itemB = &dbItem{val: stop} + } } // execute the scan on the underlying tree. if desc { diff --git a/buntdb_test.go b/buntdb_test.go index 6a8532f..f441f23 100644 --- a/buntdb_test.go +++ b/buntdb_test.go @@ -1060,6 +1060,88 @@ rect:2: [15 15],[24 24] t.Fatalf("expected [%v], got [%v]", strings.TrimSpace(res), strings.TrimSpace(buf.String())) } } + +func TestIndexAscend(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + db := testOpen(t) + defer testClose(db) + + // create a simple index + if err := db.CreateIndex("usr", "usr:*", IndexInt); err != nil { + t.Fatal(err) + } + if err := db.Update(func(tx *Tx) error { + for i := 10; i > 0; i-- { + tx.Set(fmt.Sprintf("usr:%d", i), fmt.Sprintf("%d", 10-i), nil) + } + return nil + }); err != nil { + t.Fatal(err) + } + + buf := &bytes.Buffer{} + err := db.View(func(tx *Tx) error { + tx.Ascend("usr", func(key, value string) bool { + fmt.Fprintf(buf, "%s %s\n", key, value) + return true + }) + fmt.Fprintln(buf) + + tx.AscendGreaterOrEqual("usr", "8", func(key, value string) bool { + fmt.Fprintf(buf, "%s %s\n", key, value) + return true + }) + fmt.Fprintln(buf) + + tx.AscendLessThan("usr", "3", func(key, value string) bool { + fmt.Fprintf(buf, "%s %s\n", key, value) + return true + }) + fmt.Fprintln(buf) + + tx.AscendRange("usr", "4", "8", func(key, value string) bool { + fmt.Fprintf(buf, "%s %s\n", key, value) + return true + }) + return nil + }) + + if err != nil { + t.Fatal(err) + } + + res := ` +usr:10 0 +usr:9 1 +usr:8 2 +usr:7 3 +usr:6 4 +usr:5 5 +usr:4 6 +usr:3 7 +usr:2 8 +usr:1 9 + +usr:2 8 +usr:1 9 + +usr:10 0 +usr:9 1 +usr:8 2 + +usr:6 4 +usr:5 5 +usr:4 6 +usr:3 7 +` + res = strings.Replace(res, "\r", "", -1) + s1 := strings.TrimSpace(buf.String()) + s2 := strings.TrimSpace(res) + if s1 != s2 { + t.Fatalf("expected [%v], got [%v]", s1, s2) + } +} + func testRectStringer(min, max []float64) error { nmin, nmax := IndexRect(Rect(min, max)) if len(nmin) != len(min) {