https://github.com/google/cayley
Tip revision: 8ff5bbe1576e5ebb4b031e19f4cdcab7c69448f7 authored by Iddan Aaronsohn on 28 December 2019, 11:21:55 UTC
Test context and correct implementation
Test context and correct implementation
Tip revision: 8ff5bbe
all_iterator.go
// Copyright 2014 The Cayley Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package memstore
import (
"context"
"github.com/cayleygraph/cayley/graph"
"github.com/cayleygraph/cayley/graph/iterator"
"github.com/cayleygraph/cayley/graph/refs"
)
var _ iterator.Shape = (*allIterator)(nil)
type allIterator struct {
qs *QuadStore
all []*primitive
maxid int64 // id of last observed insert (prim id)
nodes bool
}
func (qs *QuadStore) newAllIterator(nodes bool, maxid int64) *allIterator {
return &allIterator{
qs: qs, all: qs.cloneAll(), nodes: nodes,
maxid: maxid,
}
}
func (it *allIterator) Iterate() iterator.Scanner {
return it.qs.newAllIteratorNext(it.nodes, it.maxid, it.all)
}
func (it *allIterator) Lookup() iterator.Index {
return it.qs.newAllIteratorContains(it.nodes, it.maxid)
}
func (it *allIterator) SubIterators() []iterator.Shape { return nil }
func (it *allIterator) Optimize(ctx context.Context) (iterator.Shape, bool) {
return it, false
}
func (it *allIterator) String() string {
return "MemStoreAll"
}
func (it *allIterator) Stats(ctx context.Context) (iterator.Costs, error) {
return iterator.Costs{
NextCost: 1,
ContainsCost: 1,
Size: refs.Size{
// TODO(dennwc): use maxid?
Value: int64(len(it.all)),
Exact: true,
},
}, nil
}
func (p *primitive) filter(isNode bool, maxid int64) bool {
if p.ID > maxid {
return false
} else if isNode && p.Value != nil {
return true
} else if !isNode && !p.Quad.Zero() {
return true
}
return false
}
type allIteratorNext struct {
qs *QuadStore
all []*primitive
maxid int64 // id of last observed insert (prim id)
nodes bool
i int // index into qs.all
cur *primitive
done bool
}
func (qs *QuadStore) newAllIteratorNext(nodes bool, maxid int64, all []*primitive) *allIteratorNext {
return &allIteratorNext{
qs: qs, all: all, nodes: nodes,
i: -1, maxid: maxid,
}
}
func (it *allIteratorNext) ok(p *primitive) bool {
return p.filter(it.nodes, it.maxid)
}
func (it *allIteratorNext) Next(ctx context.Context) bool {
it.cur = nil
if it.done {
return false
}
all := it.all
if it.i >= len(all) {
it.done = true
return false
}
it.i++
for ; it.i < len(all); it.i++ {
p := all[it.i]
if p.ID > it.maxid {
break
}
if it.ok(p) {
it.cur = p
return true
}
}
it.done = true
return false
}
func (it *allIteratorNext) Result() graph.Ref {
if it.cur == nil {
return nil
}
if !it.cur.Quad.Zero() {
return qprim{p: it.cur}
}
return bnode(it.cur.ID)
}
func (it *allIteratorNext) Err() error { return nil }
func (it *allIteratorNext) Close() error {
it.done = true
it.all = nil
return nil
}
func (it *allIteratorNext) TagResults(dst map[string]graph.Ref) {}
func (it *allIteratorNext) String() string {
return "MemStoreAllNext"
}
func (it *allIteratorNext) NextPath(ctx context.Context) bool { return false }
type allIteratorContains struct {
qs *QuadStore
maxid int64 // id of last observed insert (prim id)
nodes bool
cur *primitive
done bool
}
func (qs *QuadStore) newAllIteratorContains(nodes bool, maxid int64) *allIteratorContains {
return &allIteratorContains{
qs: qs, nodes: nodes,
maxid: maxid,
}
}
func (it *allIteratorContains) ok(p *primitive) bool {
return p.filter(it.nodes, it.maxid)
}
func (it *allIteratorContains) Contains(ctx context.Context, v graph.Ref) bool {
it.cur = nil
if it.done {
return false
}
id, ok := asID(v)
if !ok {
return false
}
p := it.qs.prim[id]
if p.ID > it.maxid {
return false
}
if !it.ok(p) {
return false
}
it.cur = p
return true
}
func (it *allIteratorContains) Result() graph.Ref {
if it.cur == nil {
return nil
}
if !it.cur.Quad.Zero() {
return qprim{p: it.cur}
}
return bnode(it.cur.ID)
}
func (it *allIteratorContains) Err() error { return nil }
func (it *allIteratorContains) Close() error {
it.done = true
return nil
}
func (it *allIteratorContains) TagResults(dst map[string]graph.Ref) {}
func (it *allIteratorContains) String() string {
return "MemStoreAllContains"
}
func (it *allIteratorContains) NextPath(ctx context.Context) bool { return false }