GraphQL: Do not do read ahead when count is 1 (#3249)

When doing a query like

```graphql
values(count:1)
```

We used to do a read ahead. This removes that read ahead.

Towards #3236
This commit is contained in:
Erik Arvidsson
2017-03-03 14:46:14 -08:00
committed by GitHub
parent 7809dae58a
commit af87b68f91
2 changed files with 49 additions and 16 deletions

View File

@@ -261,6 +261,9 @@ func getSetElements(v types.Value, args map[string]interface{}) (interface{}, er
IteratorAt: func(at uint64) interface{} {
return s.IteratorAt(at)
},
First: func() interface{} {
return &setFirstIterator{s: s}
},
})
if err != nil {
@@ -320,9 +323,15 @@ func getCollectionArgs(col types.Collection, args map[string]interface{}, factor
keys: nomsKeys,
}
return
}
nomsThrough, err = getThroughArg(nomsKeyType, args)
if err != nil {
return
}
count, singleExactMatch = getCountArg(length, args)
if key, ok := args[keyKey]; ok {
nomsKey, err = marshal.Marshal(key)
if err != nil {
@@ -334,28 +343,17 @@ func getCollectionArgs(col types.Collection, args map[string]interface{}, factor
if idx < 0 {
idx = 0
} else if uint64(idx) > length {
// count is already 0
count = 0
return
}
iter = factory.IteratorAt(uint64(idx))
} else if count == 1 && !singleExactMatch {
// no key, no at, no through, but a count:1
iter = factory.First()
} else {
iter = factory.IteratorAt(0)
}
if err != nil {
return
}
if iter == nil {
// count is already 0
return
}
nomsThrough, err = getThroughArg(nomsKeyType, args)
if err != nil {
return
}
count, singleExactMatch = getCountArg(length, args)
return
}
@@ -371,6 +369,9 @@ func getMapElements(v types.Value, args map[string]interface{}, app mapAppender)
IteratorAt: func(at uint64) interface{} {
return m.IteratorAt(at)
},
First: func() interface{} {
return &mapFirstIterator{m: m}
},
})
if err != nil {
@@ -442,6 +443,7 @@ func getThroughArg(nomsKeyType *types.Type, args map[string]interface{}) (types.
type iteratorFactory struct {
IteratorFrom func(from types.Value) interface{}
IteratorAt func(at uint64) interface{}
First func() interface{}
}
type mapEntry struct {
@@ -748,3 +750,23 @@ func (it *mapIteratorForKeys) Next() (k, v types.Value) {
it.idx++
return
}
type setFirstIterator struct {
s types.Set
}
func (it *setFirstIterator) Next() types.Value {
return it.s.First()
}
func (it *setFirstIterator) SkipTo(v types.Value) types.Value {
panic("not implemented")
}
type mapFirstIterator struct {
m types.Map
}
func (it *mapFirstIterator) Next() (types.Value, types.Value) {
return it.m.First()
}

View File

@@ -42,6 +42,17 @@ func TestSetIterator(t *testing.T) {
empty := NewSet()
assert.Nil(empty.Iterator().Next())
assert.Nil(empty.Iterator().SkipTo(Number(-30)))
single := NewSet(Number(42)).Iterator()
assert.Equal(Number(42), single.SkipTo(Number(42)))
assert.Equal(nil, single.SkipTo(Number(42)))
single = NewSet(Number(42)).Iterator()
assert.Equal(Number(42), single.SkipTo(Number(42)))
assert.Equal(nil, single.Next())
single = NewSet(Number(42)).Iterator()
assert.Equal(Number(42), single.SkipTo(Number(21)))
}
func TestSetIteratorAt(t *testing.T) {