Move current result handling out of Base

Delete majority of Base functionality.
This commit is contained in:
kortschak 2014-07-30 15:01:09 +09:30
parent ee6d4c8db7
commit 375d953d93
14 changed files with 140 additions and 82 deletions

View file

@ -36,6 +36,7 @@ type Int64 struct {
tags graph.Tagger tags graph.Tagger
max, min int64 max, min int64
at int64 at int64
result graph.Value
} }
// Creates a new Int64 with the given range. // Creates a new Int64 with the given range.
@ -99,10 +100,19 @@ func (it *Int64) Next() (graph.Value, bool) {
if it.at > it.max { if it.at > it.max {
it.at = -1 it.at = -1
} }
it.Last = val it.result = val
return graph.NextLogOut(it, val, true) 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. // No sub-iterators.
func (it *Int64) SubIterators() []graph.Iterator { func (it *Int64) SubIterators() []graph.Iterator {
return nil return nil
@ -121,7 +131,7 @@ func (it *Int64) Check(tsv graph.Value) bool {
graph.CheckLogIn(it, tsv) graph.CheckLogIn(it, tsv)
v := tsv.(int64) v := tsv.(int64)
if it.min <= v && v <= it.max { if it.min <= v && v <= it.max {
it.Last = v it.result = v
return graph.CheckLogOut(it, v, true) return graph.CheckLogOut(it, v, true)
} }
return graph.CheckLogOut(it, v, false) return graph.CheckLogOut(it, v, false)

View file

@ -32,6 +32,7 @@ type And struct {
itCount int itCount int
primaryIt graph.Iterator primaryIt graph.Iterator
checkList []graph.Iterator checkList []graph.Iterator
result graph.Value
} }
// Creates a new And iterator. // Creates a new And iterator.
@ -167,11 +168,15 @@ func (it *And) Next() (graph.Value, bool) {
return graph.NextLogOut(it, nil, false) return graph.NextLogOut(it, nil, false)
} }
if it.checkSubIts(curr) { if it.checkSubIts(curr) {
it.Last = curr it.result = curr
return graph.NextLogOut(it, curr, true) 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. // Checks a value against the non-primary iterators, in order.
@ -195,7 +200,7 @@ func (it *And) checkCheckList(val graph.Value) bool {
} }
} }
if ok { if ok {
it.Last = val it.result = val
} }
return graph.CheckLogOut(it, val, ok) return graph.CheckLogOut(it, val, ok)
} }
@ -214,7 +219,7 @@ func (it *And) Check(val graph.Value) bool {
if !othersGood { if !othersGood {
return graph.CheckLogOut(it, val, false) return graph.CheckLogOut(it, val, false)
} }
it.Last = val it.result = val
return graph.CheckLogOut(it, val, true) return graph.CheckLogOut(it, val, true)
} }

View file

@ -36,6 +36,7 @@ type Fixed struct {
values []graph.Value values []graph.Value
lastIndex int lastIndex int
cmp Equality cmp Equality
result graph.Value
} }
// Define the signature of an equality function. // Define the signature of an equality function.
@ -130,7 +131,7 @@ func (it *Fixed) Check(v graph.Value) bool {
graph.CheckLogIn(it, v) graph.CheckLogIn(it, v)
for _, x := range it.values { for _, x := range it.values {
if it.cmp(x, v) { if it.cmp(x, v) {
it.Last = x it.result = x
return graph.CheckLogOut(it, v, true) return graph.CheckLogOut(it, v, true)
} }
} }
@ -144,11 +145,20 @@ func (it *Fixed) Next() (graph.Value, bool) {
return graph.NextLogOut(it, nil, false) return graph.NextLogOut(it, nil, false)
} }
out := it.values[it.lastIndex] out := it.values[it.lastIndex]
it.Last = out it.result = out
it.lastIndex++ it.lastIndex++
return graph.NextLogOut(it, out, true) 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. // No sub-iterators.
func (it *Fixed) SubIterators() []graph.Iterator { func (it *Fixed) SubIterators() []graph.Iterator {
return nil return nil

View file

@ -53,6 +53,7 @@ type HasA struct {
primaryIt graph.Iterator primaryIt graph.Iterator
dir graph.Direction dir graph.Direction
resultIt graph.Iterator resultIt graph.Iterator
result graph.Value
} }
// Construct a new HasA iterator, given the triple subiterator, and the triple // 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)) glog.V(4).Infoln("Triple is", it.ts.Triple(linkVal))
} }
if it.primaryIt.Check(linkVal) { if it.primaryIt.Check(linkVal) {
it.Last = it.ts.TripleDirection(linkVal, it.dir) it.result = it.ts.TripleDirection(linkVal, it.dir)
return true return true
} }
} }
@ -205,10 +206,14 @@ func (it *HasA) Next() (graph.Value, bool) {
} }
name := it.ts.Triple(tID).Get(it.dir) name := it.ts.Triple(tID).Get(it.dir)
val := it.ts.ValueOf(name) val := it.ts.ValueOf(name)
it.Last = val it.result = val
return graph.NextLogOut(it, val, true) 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 // 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. // 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 // CheckCost involves going to the graph.TripleStore, iterating out values, and hoping

View file

@ -18,7 +18,6 @@ package iterator
// iterators can "inherit" from to get default iterator functionality. // iterators can "inherit" from to get default iterator functionality.
import ( import (
"fmt"
"strings" "strings"
"sync/atomic" "sync/atomic"
@ -34,7 +33,6 @@ func NextUID() uint64 {
// The Base iterator is the iterator other iterators inherit from to get some // The Base iterator is the iterator other iterators inherit from to get some
// default functionality. // default functionality.
type Base struct { type Base struct {
Last graph.Value
canNext bool canNext bool
} }
@ -44,50 +42,13 @@ func BaseInit(it *Base) {
it.canNext = true 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 { func (it *Base) NextResult() bool {
return false return false
} }
// Returns the last result of an iterator.
func (it *Base) Result() graph.Value {
return it.Last
}
// Accessor // Accessor
func (it *Base) CanNext() bool { return it.canNext } 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. // 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, // 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. // 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 { func (it *Null) ResultTree() *graph.ResultTree {
tree := graph.NewResultTree(it.Result()) return graph.NewResultTree(it.Result())
return tree
} }
func (it *Null) SubIterators() []graph.Iterator { func (it *Null) SubIterators() []graph.Iterator {

View file

@ -47,6 +47,7 @@ type LinksTo struct {
primaryIt graph.Iterator primaryIt graph.Iterator
dir graph.Direction dir graph.Direction
nextIt graph.Iterator nextIt graph.Iterator
result graph.Value
} }
// Construct a new LinksTo iterator around a direction and a subiterator of // 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) graph.CheckLogIn(it, val)
node := it.ts.TripleDirection(val, it.dir) node := it.ts.TripleDirection(val, it.dir)
if it.primaryIt.Check(node) { if it.primaryIt.Check(node) {
it.Last = val it.result = val
return graph.CheckLogOut(it, val, true) return graph.CheckLogOut(it, val, true)
} }
return graph.CheckLogOut(it, val, false) 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. // Recurse -- return the first in the next set.
return it.Next() return it.Next()
} }
it.Last = val it.result = val
return graph.NextLogOut(it, val, ok) return graph.NextLogOut(it, val, ok)
} }
func (it *LinksTo) Result() graph.Value {
return it.result
}
// Close our subiterators. // Close our subiterators.
func (it *LinksTo) Close() { func (it *LinksTo) Close() {
it.nextIt.Close() it.nextIt.Close()

View file

@ -43,6 +43,7 @@ type Optional struct {
tags graph.Tagger tags graph.Tagger
subIt graph.Iterator subIt graph.Iterator
lastCheck bool lastCheck bool
result graph.Value
} }
// Creates a new optional iterator. // Creates a new optional iterator.
@ -78,6 +79,9 @@ func (it *Optional) Clone() graph.Iterator {
return out 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. // Nexting the iterator is unsupported -- error and return an empty set.
// (As above, a reasonable alternative would be to Next() an all iterator) // (As above, a reasonable alternative would be to Next() an all iterator)
func (it *Optional) Next() (graph.Value, bool) { func (it *Optional) Next() (graph.Value, bool) {
@ -85,6 +89,15 @@ func (it *Optional) Next() (graph.Value, bool) {
return nil, false 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 // 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 // we had any results whatsoever, and (b) there was another subresult in our
// optional subbranch. // optional subbranch.
@ -106,7 +119,7 @@ func (it *Optional) SubIterators() []graph.Iterator {
func (it *Optional) Check(val graph.Value) bool { func (it *Optional) Check(val graph.Value) bool {
checked := it.subIt.Check(val) checked := it.subIt.Check(val)
it.lastCheck = checked it.lastCheck = checked
it.Last = val it.result = val
return true return true
} }

View file

@ -36,6 +36,7 @@ type Or struct {
internalIterators []graph.Iterator internalIterators []graph.Iterator
itCount int itCount int
currentIterator int currentIterator int
result graph.Value
} }
func NewOr() *Or { func NewOr() *Or {
@ -169,11 +170,15 @@ func (it *Or) Next() (graph.Value, bool) {
return graph.NextLogOut(it, nil, false) return graph.NextLogOut(it, nil, false)
} }
} else { } else {
it.Last = curr it.result = curr
return graph.NextLogOut(it, curr, true) 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. // Checks a value against the iterators, in order.
@ -196,7 +201,7 @@ func (it *Or) Check(val graph.Value) bool {
if !anyGood { if !anyGood {
return graph.CheckLogOut(it, val, false) return graph.CheckLogOut(it, val, false)
} }
it.Last = val it.result = val
return graph.CheckLogOut(it, val, true) return graph.CheckLogOut(it, val, true)
} }

View file

@ -47,12 +47,13 @@ const (
type Comparison struct { type Comparison struct {
Base Base
uid uint64 uid uint64
tags graph.Tagger tags graph.Tagger
subIt graph.Iterator subIt graph.Iterator
op Operator op Operator
val interface{} val interface{}
ts graph.TripleStore ts graph.TripleStore
result graph.Value
} }
func NewComparison(sub graph.Iterator, op Operator, val interface{}, ts graph.TripleStore) *Comparison { 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 break
} }
} }
it.Last = val it.result = val
return val, ok 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 { func (it *Comparison) NextResult() bool {
for { for {
hasNext := it.subIt.NextResult() hasNext := it.subIt.NextResult()
@ -155,7 +165,7 @@ func (it *Comparison) NextResult() bool {
return true return true
} }
} }
it.Last = it.subIt.Result() it.result = it.subIt.Result()
return true return true
} }
@ -213,6 +223,6 @@ func (it *Comparison) Stats() graph.IteratorStats {
return it.subIt.Stats() return it.subIt.Stats()
} }
func (it *Base) Size() (int64, bool) { func (it *Comparison) Size() (int64, bool) {
return 0, true return 0, true
} }

View file

@ -36,6 +36,7 @@ type AllIterator struct {
iter ldbit.Iterator iter ldbit.Iterator
ts *TripleStore ts *TripleStore
ro *opt.ReadOptions ro *opt.ReadOptions
result graph.Value
} }
func NewAllIterator(prefix string, d graph.Direction, ts *TripleStore) *AllIterator { 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) { func (it *AllIterator) Next() (graph.Value, bool) {
if !it.open { if !it.open {
it.Last = nil it.result = nil
return nil, false return nil, false
} }
var out []byte var out []byte
@ -117,17 +118,25 @@ func (it *AllIterator) Next() (graph.Value, bool) {
it.Close() it.Close()
return nil, false return nil, false
} }
it.Last = out it.result = out
return out, true 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. // No subiterators.
func (it *AllIterator) SubIterators() []graph.Iterator { func (it *AllIterator) SubIterators() []graph.Iterator {
return nil return nil
} }
func (it *AllIterator) Check(v graph.Value) bool { func (it *AllIterator) Check(v graph.Value) bool {
it.Last = v it.result = v
return true return true
} }

View file

@ -38,6 +38,7 @@ type Iterator struct {
ts *TripleStore ts *TripleStore
ro *opt.ReadOptions ro *opt.ReadOptions
originalPrefix string originalPrefix string
result graph.Value
} }
func NewIterator(prefix string, d graph.Direction, value graph.Value, ts *TripleStore) *Iterator { 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) { func (it *Iterator) Next() (graph.Value, bool) {
if it.iter == nil { if it.iter == nil {
it.Last = nil it.result = nil
return nil, false return nil, false
} }
if !it.open { if !it.open {
it.Last = nil it.result = nil
return nil, false return nil, false
} }
if !it.iter.Valid() { if !it.iter.Valid() {
it.Last = nil it.result = nil
it.Close() it.Close()
return nil, false return nil, false
} }
if bytes.HasPrefix(it.iter.Key(), it.nextPrefix) { if bytes.HasPrefix(it.iter.Key(), it.nextPrefix) {
out := make([]byte, len(it.iter.Key())) out := make([]byte, len(it.iter.Key()))
copy(out, it.iter.Key()) copy(out, it.iter.Key())
it.Last = out it.result = out
ok := it.iter.Next() ok := it.iter.Next()
if !ok { if !ok {
it.Close() it.Close()
@ -142,10 +143,18 @@ func (it *Iterator) Next() (graph.Value, bool) {
return out, true return out, true
} }
it.Close() it.Close()
it.Last = nil it.result = nil
return nil, false 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. // No subiterators.
func (it *Iterator) SubIterators() []graph.Iterator { func (it *Iterator) SubIterators() []graph.Iterator {
return nil return nil

View file

@ -46,6 +46,5 @@ func (it *AllIterator) Next() (graph.Value, bool) {
if !ok { if !ok {
return it.Next() return it.Next()
} }
it.Last = next
return next, out return next, out
} }

View file

@ -33,6 +33,7 @@ type Iterator struct {
data string data string
isRunning bool isRunning bool
iterLast Int64 iterLast Int64
result graph.Value
} }
type Int64 int64 type Int64 int64
@ -97,12 +98,20 @@ func (it *Iterator) Close() {}
func (it *Iterator) Next() (graph.Value, bool) { func (it *Iterator) Next() (graph.Value, bool) {
graph.NextLogIn(it) 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) return graph.NextLogOut(it, nil, false)
} }
it.iterLast = IterateOne(it.tree, it.iterLast) it.iterLast = IterateOne(it.tree, it.iterLast)
it.Last = int64(it.iterLast) it.result = int64(it.iterLast)
return graph.NextLogOut(it, it.Last, true) 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. // No subiterators.
@ -117,7 +126,7 @@ func (it *Iterator) Size() (int64, bool) {
func (it *Iterator) Check(v graph.Value) bool { func (it *Iterator) Check(v graph.Value) bool {
graph.CheckLogIn(it, v) graph.CheckLogIn(it, v)
if it.tree.Has(Int64(v.(int64))) { if it.tree.Has(Int64(v.(int64))) {
it.Last = v it.result = v
return graph.CheckLogOut(it, v, true) return graph.CheckLogOut(it, v, true)
} }
return graph.CheckLogOut(it, v, false) return graph.CheckLogOut(it, v, false)

View file

@ -39,6 +39,7 @@ type Iterator struct {
isAll bool isAll bool
constraint bson.M constraint bson.M
collection string collection string
result graph.Value
} }
func NewIterator(ts *TripleStore, collection string, d graph.Direction, val graph.Value) *Iterator { 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 return nil, false
} }
it.Last = result.Id it.result = result.Id
return result.Id, true 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. // No subiterators.
func (it *Iterator) SubIterators() []graph.Iterator { func (it *Iterator) SubIterators() []graph.Iterator {
return nil return nil
@ -170,7 +179,7 @@ func (it *Iterator) SubIterators() []graph.Iterator {
func (it *Iterator) Check(v graph.Value) bool { func (it *Iterator) Check(v graph.Value) bool {
graph.CheckLogIn(it, v) graph.CheckLogIn(it, v)
if it.isAll { if it.isAll {
it.Last = v it.result = v
return graph.CheckLogOut(it, v, true) return graph.CheckLogOut(it, v, true)
} }
var offset int 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] val := v.(string)[offset : it.ts.hasher.Size()*2+offset]
if val == it.hash { if val == it.hash {
it.Last = v it.result = v
return graph.CheckLogOut(it, v, true) return graph.CheckLogOut(it, v, true)
} }
return graph.CheckLogOut(it, v, false) return graph.CheckLogOut(it, v, false)