Move current result handling out of Base
Delete majority of Base functionality.
This commit is contained in:
parent
ee6d4c8db7
commit
375d953d93
14 changed files with 140 additions and 82 deletions
|
|
@ -36,6 +36,7 @@ type Int64 struct {
|
|||
tags graph.Tagger
|
||||
max, min int64
|
||||
at int64
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
// Creates a new Int64 with the given range.
|
||||
|
|
@ -99,10 +100,19 @@ func (it *Int64) Next() (graph.Value, bool) {
|
|||
if it.at > it.max {
|
||||
it.at = -1
|
||||
}
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return graph.NextLogOut(it, val, true)
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (it *Int64) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Int64) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// No sub-iterators.
|
||||
func (it *Int64) SubIterators() []graph.Iterator {
|
||||
return nil
|
||||
|
|
@ -121,7 +131,7 @@ func (it *Int64) Check(tsv graph.Value) bool {
|
|||
graph.CheckLogIn(it, tsv)
|
||||
v := tsv.(int64)
|
||||
if it.min <= v && v <= it.max {
|
||||
it.Last = v
|
||||
it.result = v
|
||||
return graph.CheckLogOut(it, v, true)
|
||||
}
|
||||
return graph.CheckLogOut(it, v, false)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ type And struct {
|
|||
itCount int
|
||||
primaryIt graph.Iterator
|
||||
checkList []graph.Iterator
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
// Creates a new And iterator.
|
||||
|
|
@ -167,11 +168,15 @@ func (it *And) Next() (graph.Value, bool) {
|
|||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
if it.checkSubIts(curr) {
|
||||
it.Last = curr
|
||||
it.result = curr
|
||||
return graph.NextLogOut(it, curr, true)
|
||||
}
|
||||
}
|
||||
panic("Somehow broke out of Next() loop in And")
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (it *And) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// Checks a value against the non-primary iterators, in order.
|
||||
|
|
@ -195,7 +200,7 @@ func (it *And) checkCheckList(val graph.Value) bool {
|
|||
}
|
||||
}
|
||||
if ok {
|
||||
it.Last = val
|
||||
it.result = val
|
||||
}
|
||||
return graph.CheckLogOut(it, val, ok)
|
||||
}
|
||||
|
|
@ -214,7 +219,7 @@ func (it *And) Check(val graph.Value) bool {
|
|||
if !othersGood {
|
||||
return graph.CheckLogOut(it, val, false)
|
||||
}
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return graph.CheckLogOut(it, val, true)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type Fixed struct {
|
|||
values []graph.Value
|
||||
lastIndex int
|
||||
cmp Equality
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
// Define the signature of an equality function.
|
||||
|
|
@ -130,7 +131,7 @@ func (it *Fixed) Check(v graph.Value) bool {
|
|||
graph.CheckLogIn(it, v)
|
||||
for _, x := range it.values {
|
||||
if it.cmp(x, v) {
|
||||
it.Last = x
|
||||
it.result = x
|
||||
return graph.CheckLogOut(it, v, true)
|
||||
}
|
||||
}
|
||||
|
|
@ -144,11 +145,20 @@ func (it *Fixed) Next() (graph.Value, bool) {
|
|||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
out := it.values[it.lastIndex]
|
||||
it.Last = out
|
||||
it.result = out
|
||||
it.lastIndex++
|
||||
return graph.NextLogOut(it, out, true)
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (it *Fixed) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Fixed) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// No sub-iterators.
|
||||
func (it *Fixed) SubIterators() []graph.Iterator {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ type HasA struct {
|
|||
primaryIt graph.Iterator
|
||||
dir graph.Direction
|
||||
resultIt graph.Iterator
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
// Construct a new HasA iterator, given the triple subiterator, and the triple
|
||||
|
|
@ -168,7 +169,7 @@ func (it *HasA) GetCheckResult() bool {
|
|||
glog.V(4).Infoln("Triple is", it.ts.Triple(linkVal))
|
||||
}
|
||||
if it.primaryIt.Check(linkVal) {
|
||||
it.Last = it.ts.TripleDirection(linkVal, it.dir)
|
||||
it.result = it.ts.TripleDirection(linkVal, it.dir)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -205,10 +206,14 @@ func (it *HasA) Next() (graph.Value, bool) {
|
|||
}
|
||||
name := it.ts.Triple(tID).Get(it.dir)
|
||||
val := it.ts.ValueOf(name)
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return graph.NextLogOut(it, val, true)
|
||||
}
|
||||
|
||||
func (it *HasA) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// GetStats() returns the statistics on the HasA iterator. This is curious. Next
|
||||
// cost is easy, it's an extra call or so on top of the subiterator Next cost.
|
||||
// CheckCost involves going to the graph.TripleStore, iterating out values, and hoping
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package iterator
|
|||
// iterators can "inherit" from to get default iterator functionality.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
|
|
@ -34,7 +33,6 @@ func NextUID() uint64 {
|
|||
// The Base iterator is the iterator other iterators inherit from to get some
|
||||
// default functionality.
|
||||
type Base struct {
|
||||
Last graph.Value
|
||||
canNext bool
|
||||
}
|
||||
|
||||
|
|
@ -44,50 +42,13 @@ func BaseInit(it *Base) {
|
|||
it.canNext = true
|
||||
}
|
||||
|
||||
// Prints a silly debug string. Most classes override.
|
||||
func (it *Base) DebugString(indent int) string {
|
||||
return fmt.Sprintf("%s(base)", strings.Repeat(" ", indent))
|
||||
}
|
||||
|
||||
// Nothing in a base iterator.
|
||||
func (it *Base) Check(v graph.Value) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Base iterators should never appear in a tree if they are, select against
|
||||
// them.
|
||||
func (it *Base) Stats() graph.IteratorStats {
|
||||
return graph.IteratorStats{100000, 100000, 100000}
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (it *Base) ResultTree() *graph.ResultTree {
|
||||
tree := graph.NewResultTree(it.Result())
|
||||
return tree
|
||||
}
|
||||
|
||||
// Nothing in a base iterator.
|
||||
func (it *Base) Next() (graph.Value, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (it *Base) NextResult() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Returns the last result of an iterator.
|
||||
func (it *Base) Result() graph.Value {
|
||||
return it.Last
|
||||
}
|
||||
|
||||
// Accessor
|
||||
func (it *Base) CanNext() bool { return it.canNext }
|
||||
|
||||
// Nothing to clean up.
|
||||
// func (it *Base) Close() {}
|
||||
|
||||
func (it *Base) Reset() {}
|
||||
|
||||
// Here we define the simplest iterator -- the Null iterator. It contains nothing.
|
||||
// It is the empty set. Often times, queries that contain one of these match nothing,
|
||||
// so it's important to give it a special iterator.
|
||||
|
|
@ -149,8 +110,7 @@ func (it *Null) Result() graph.Value {
|
|||
}
|
||||
|
||||
func (it *Null) ResultTree() *graph.ResultTree {
|
||||
tree := graph.NewResultTree(it.Result())
|
||||
return tree
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Null) SubIterators() []graph.Iterator {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type LinksTo struct {
|
|||
primaryIt graph.Iterator
|
||||
dir graph.Direction
|
||||
nextIt graph.Iterator
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
// Construct a new LinksTo iterator around a direction and a subiterator of
|
||||
|
|
@ -121,7 +122,7 @@ func (it *LinksTo) Check(val graph.Value) bool {
|
|||
graph.CheckLogIn(it, val)
|
||||
node := it.ts.TripleDirection(val, it.dir)
|
||||
if it.primaryIt.Check(node) {
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return graph.CheckLogOut(it, val, true)
|
||||
}
|
||||
return graph.CheckLogOut(it, val, false)
|
||||
|
|
@ -169,10 +170,14 @@ func (it *LinksTo) Next() (graph.Value, bool) {
|
|||
// Recurse -- return the first in the next set.
|
||||
return it.Next()
|
||||
}
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return graph.NextLogOut(it, val, ok)
|
||||
}
|
||||
|
||||
func (it *LinksTo) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// Close our subiterators.
|
||||
func (it *LinksTo) Close() {
|
||||
it.nextIt.Close()
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ type Optional struct {
|
|||
tags graph.Tagger
|
||||
subIt graph.Iterator
|
||||
lastCheck bool
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
// Creates a new optional iterator.
|
||||
|
|
@ -78,6 +79,9 @@ func (it *Optional) Clone() graph.Iterator {
|
|||
return out
|
||||
}
|
||||
|
||||
// FIXME(kortschak) When we create a Nexter interface the
|
||||
// following two methods need to go away.
|
||||
|
||||
// Nexting the iterator is unsupported -- error and return an empty set.
|
||||
// (As above, a reasonable alternative would be to Next() an all iterator)
|
||||
func (it *Optional) Next() (graph.Value, bool) {
|
||||
|
|
@ -85,6 +89,15 @@ func (it *Optional) Next() (graph.Value, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (it *Optional) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Optional) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// An optional iterator only has a next result if, (a) last time we checked
|
||||
// we had any results whatsoever, and (b) there was another subresult in our
|
||||
// optional subbranch.
|
||||
|
|
@ -106,7 +119,7 @@ func (it *Optional) SubIterators() []graph.Iterator {
|
|||
func (it *Optional) Check(val graph.Value) bool {
|
||||
checked := it.subIt.Check(val)
|
||||
it.lastCheck = checked
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type Or struct {
|
|||
internalIterators []graph.Iterator
|
||||
itCount int
|
||||
currentIterator int
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
func NewOr() *Or {
|
||||
|
|
@ -169,11 +170,15 @@ func (it *Or) Next() (graph.Value, bool) {
|
|||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
} else {
|
||||
it.Last = curr
|
||||
it.result = curr
|
||||
return graph.NextLogOut(it, curr, true)
|
||||
}
|
||||
}
|
||||
panic("Somehow broke out of Next() loop in Or")
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (it *Or) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// Checks a value against the iterators, in order.
|
||||
|
|
@ -196,7 +201,7 @@ func (it *Or) Check(val graph.Value) bool {
|
|||
if !anyGood {
|
||||
return graph.CheckLogOut(it, val, false)
|
||||
}
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return graph.CheckLogOut(it, val, true)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,13 @@ const (
|
|||
|
||||
type Comparison struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
subIt graph.Iterator
|
||||
op Operator
|
||||
val interface{}
|
||||
ts graph.TripleStore
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
subIt graph.Iterator
|
||||
op Operator
|
||||
val interface{}
|
||||
ts graph.TripleStore
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
func NewComparison(sub graph.Iterator, op Operator, val interface{}, ts graph.TripleStore) *Comparison {
|
||||
|
|
@ -141,10 +142,19 @@ func (it *Comparison) Next() (graph.Value, bool) {
|
|||
break
|
||||
}
|
||||
}
|
||||
it.Last = val
|
||||
it.result = val
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (it *Comparison) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Comparison) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
func (it *Comparison) NextResult() bool {
|
||||
for {
|
||||
hasNext := it.subIt.NextResult()
|
||||
|
|
@ -155,7 +165,7 @@ func (it *Comparison) NextResult() bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
it.Last = it.subIt.Result()
|
||||
it.result = it.subIt.Result()
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +223,6 @@ func (it *Comparison) Stats() graph.IteratorStats {
|
|||
return it.subIt.Stats()
|
||||
}
|
||||
|
||||
func (it *Base) Size() (int64, bool) {
|
||||
func (it *Comparison) Size() (int64, bool) {
|
||||
return 0, true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type AllIterator struct {
|
|||
iter ldbit.Iterator
|
||||
ts *TripleStore
|
||||
ro *opt.ReadOptions
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
func NewAllIterator(prefix string, d graph.Direction, ts *TripleStore) *AllIterator {
|
||||
|
|
@ -103,7 +104,7 @@ func (it *AllIterator) Clone() graph.Iterator {
|
|||
|
||||
func (it *AllIterator) Next() (graph.Value, bool) {
|
||||
if !it.open {
|
||||
it.Last = nil
|
||||
it.result = nil
|
||||
return nil, false
|
||||
}
|
||||
var out []byte
|
||||
|
|
@ -117,17 +118,25 @@ func (it *AllIterator) Next() (graph.Value, bool) {
|
|||
it.Close()
|
||||
return nil, false
|
||||
}
|
||||
it.Last = out
|
||||
it.result = out
|
||||
return out, true
|
||||
}
|
||||
|
||||
func (it *AllIterator) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *AllIterator) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// No subiterators.
|
||||
func (it *AllIterator) SubIterators() []graph.Iterator {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (it *AllIterator) Check(v graph.Value) bool {
|
||||
it.Last = v
|
||||
it.result = v
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ type Iterator struct {
|
|||
ts *TripleStore
|
||||
ro *opt.ReadOptions
|
||||
originalPrefix string
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
func NewIterator(prefix string, d graph.Direction, value graph.Value, ts *TripleStore) *Iterator {
|
||||
|
|
@ -119,22 +120,22 @@ func (it *Iterator) Close() {
|
|||
|
||||
func (it *Iterator) Next() (graph.Value, bool) {
|
||||
if it.iter == nil {
|
||||
it.Last = nil
|
||||
it.result = nil
|
||||
return nil, false
|
||||
}
|
||||
if !it.open {
|
||||
it.Last = nil
|
||||
it.result = nil
|
||||
return nil, false
|
||||
}
|
||||
if !it.iter.Valid() {
|
||||
it.Last = nil
|
||||
it.result = nil
|
||||
it.Close()
|
||||
return nil, false
|
||||
}
|
||||
if bytes.HasPrefix(it.iter.Key(), it.nextPrefix) {
|
||||
out := make([]byte, len(it.iter.Key()))
|
||||
copy(out, it.iter.Key())
|
||||
it.Last = out
|
||||
it.result = out
|
||||
ok := it.iter.Next()
|
||||
if !ok {
|
||||
it.Close()
|
||||
|
|
@ -142,10 +143,18 @@ func (it *Iterator) Next() (graph.Value, bool) {
|
|||
return out, true
|
||||
}
|
||||
it.Close()
|
||||
it.Last = nil
|
||||
it.result = nil
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (it *Iterator) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Iterator) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// No subiterators.
|
||||
func (it *Iterator) SubIterators() []graph.Iterator {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -46,6 +46,5 @@ func (it *AllIterator) Next() (graph.Value, bool) {
|
|||
if !ok {
|
||||
return it.Next()
|
||||
}
|
||||
it.Last = next
|
||||
return next, out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ type Iterator struct {
|
|||
data string
|
||||
isRunning bool
|
||||
iterLast Int64
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
type Int64 int64
|
||||
|
|
@ -97,12 +98,20 @@ func (it *Iterator) Close() {}
|
|||
|
||||
func (it *Iterator) Next() (graph.Value, bool) {
|
||||
graph.NextLogIn(it)
|
||||
if it.tree.Max() == nil || it.Last == int64(it.tree.Max().(Int64)) {
|
||||
if it.tree.Max() == nil || it.result == int64(it.tree.Max().(Int64)) {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
it.iterLast = IterateOne(it.tree, it.iterLast)
|
||||
it.Last = int64(it.iterLast)
|
||||
return graph.NextLogOut(it, it.Last, true)
|
||||
it.result = int64(it.iterLast)
|
||||
return graph.NextLogOut(it, it.result, true)
|
||||
}
|
||||
|
||||
func (it *Iterator) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Iterator) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// No subiterators.
|
||||
|
|
@ -117,7 +126,7 @@ func (it *Iterator) Size() (int64, bool) {
|
|||
func (it *Iterator) Check(v graph.Value) bool {
|
||||
graph.CheckLogIn(it, v)
|
||||
if it.tree.Has(Int64(v.(int64))) {
|
||||
it.Last = v
|
||||
it.result = v
|
||||
return graph.CheckLogOut(it, v, true)
|
||||
}
|
||||
return graph.CheckLogOut(it, v, false)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ type Iterator struct {
|
|||
isAll bool
|
||||
constraint bson.M
|
||||
collection string
|
||||
result graph.Value
|
||||
}
|
||||
|
||||
func NewIterator(ts *TripleStore, collection string, d graph.Direction, val graph.Value) *Iterator {
|
||||
|
|
@ -158,10 +159,18 @@ func (it *Iterator) Next() (graph.Value, bool) {
|
|||
}
|
||||
return nil, false
|
||||
}
|
||||
it.Last = result.Id
|
||||
it.result = result.Id
|
||||
return result.Id, true
|
||||
}
|
||||
|
||||
func (it *Iterator) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
}
|
||||
|
||||
func (it *Iterator) Result() graph.Value {
|
||||
return it.result
|
||||
}
|
||||
|
||||
// No subiterators.
|
||||
func (it *Iterator) SubIterators() []graph.Iterator {
|
||||
return nil
|
||||
|
|
@ -170,7 +179,7 @@ func (it *Iterator) SubIterators() []graph.Iterator {
|
|||
func (it *Iterator) Check(v graph.Value) bool {
|
||||
graph.CheckLogIn(it, v)
|
||||
if it.isAll {
|
||||
it.Last = v
|
||||
it.result = v
|
||||
return graph.CheckLogOut(it, v, true)
|
||||
}
|
||||
var offset int
|
||||
|
|
@ -186,7 +195,7 @@ func (it *Iterator) Check(v graph.Value) bool {
|
|||
}
|
||||
val := v.(string)[offset : it.ts.hasher.Size()*2+offset]
|
||||
if val == it.hash {
|
||||
it.Last = v
|
||||
it.result = v
|
||||
return graph.CheckLogOut(it, v, true)
|
||||
}
|
||||
return graph.CheckLogOut(it, v, false)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue