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
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)

View file

@ -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)
}

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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()

View file

@ -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
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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

View file

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

View file

@ -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)

View file

@ -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)