Add NaiveLimit solution

parent 32214c5d
......@@ -227,12 +227,6 @@ func (d *Datastore) Delete(key ds.Key) error {
}
func (d *Datastore) Query(q query.Query) (query.Results, error) {
if q.Limit > 0 ||
q.Offset > 0 {
// TODO this is still overly simplistic, but the only callers are
// `ipfs refs local` and ipfs-ds-convert.
return nil, errors.New("mount only supports listing all prefixed keys in random order")
}
prefix := ds.NewKey(q.Prefix)
dses, mounts, rests := d.lookupAll(prefix)
......@@ -257,10 +251,12 @@ func (d *Datastore) Query(q query.Query) (query.Results, error) {
queries.addResults(mount, results)
}
return query.ResultsFromIterator(q, query.Iterator{
qr := query.ResultsFromIterator(q, query.Iterator{
Next: queries.next,
Close: queries.close,
}), nil
})
return query.NaiveLimit(qr, q.Limit), nil
}
func (d *Datastore) Close() error {
......
......@@ -2,12 +2,13 @@ package mount_test
import (
"errors"
"github.com/ipfs/go-datastore/sync"
"testing"
"github.com/ipfs/go-datastore"
mount "github.com/ipfs/go-datastore/mount"
"github.com/ipfs/go-datastore/mount"
"github.com/ipfs/go-datastore/query"
dstest "github.com/ipfs/go-datastore/test"
"github.com/ipfs/go-datastore/test"
)
func TestPutBadNothing(t *testing.T) {
......@@ -262,6 +263,10 @@ func TestQueryCross(t *testing.T) {
}
entries, err := res.Rest()
if err != nil {
err = res.Close()
if err != nil {
t.Errorf("result.Close failed %d", err)
}
t.Fatalf("Query Results.Rest fail: %v\n", err)
}
seen := 0
......@@ -346,6 +351,56 @@ func TestQueryCrossWithSort(t *testing.T) {
}
}
func TestQueryLimitCrossWithSort(t *testing.T) {
mapds1 := sync.MutexWrap(datastore.NewMapDatastore())
mapds2 := sync.MutexWrap(datastore.NewMapDatastore())
mapds3 := sync.MutexWrap(datastore.NewMapDatastore())
m := mount.New([]mount.Mount{
{Prefix: datastore.NewKey("/rok"), Datastore: mapds1},
{Prefix: datastore.NewKey("/zoo"), Datastore: mapds2},
{Prefix: datastore.NewKey("/noop"), Datastore: mapds3},
})
m.Put(datastore.NewKey("/rok/0"), []byte("ghi"))
m.Put(datastore.NewKey("/zoo/0"), []byte("123"))
m.Put(datastore.NewKey("/rok/1"), []byte("def"))
m.Put(datastore.NewKey("/zoo/1"), []byte("167"))
m.Put(datastore.NewKey("/zoo/2"), []byte("345"))
m.Put(datastore.NewKey("/rok/3"), []byte("abc"))
m.Put(datastore.NewKey("/zoo/3"), []byte("456"))
q := query.Query{Limit: 2, Orders: []query.Order{query.OrderByKeyDescending{}}}
res, err := m.Query(q)
if err != nil {
t.Fatalf("Query fail: %v\n", err)
}
entries, err := res.Rest()
if err != nil {
t.Fatalf("Query Results.Rest fail: %v\n", err)
}
expect := []string{
"/zoo/3",
"/zoo/2",
}
if len(entries) != len(expect) {
t.Fatalf("expected %d entries, but got %d", len(expect), len(entries))
}
for i, e := range expect {
if e != entries[i].Key {
t.Errorf("expected key %s, but got %s", e, entries[i].Key)
}
}
err = res.Close()
if err != nil {
t.Errorf("result.Close failed %d", err)
}
}
func TestLookupPrio(t *testing.T) {
mapds0 := datastore.NewMapDatastore()
mapds1 := datastore.NewMapDatastore()
......
......@@ -3,7 +3,7 @@ package query
import (
"time"
goprocess "github.com/jbenet/goprocess"
"github.com/jbenet/goprocess"
)
/*
......
package query
import "sort"
import (
"sort"
)
func DerivedResults(qr Results, ch <-chan Result) Results {
return &results{
......@@ -48,7 +50,7 @@ func NaiveLimit(qr Results, limit int) Results {
}
}()
return DerivedResults(qr, ch)
return ResultsWithChan(qr.Query(), ch)
}
// NaiveOffset skips a given number of results
......@@ -122,6 +124,7 @@ func NaiveQueryApply(q Query, qr Results) Results {
qr = NaiveOffset(qr, q.Offset)
}
if q.Limit != 0 {
// TODO: Offset?
qr = NaiveLimit(qr, q.Offset)
}
return qr
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment