Simplify Nexter interface
This change allows a Nexter to be used in the same manner as a scanner
using a for graph.Next(it) {} construction.
It is important that graph.Next(it) and any associated it.Result() calls
operate on the same iterator.
This commit is contained in:
parent
f8e28e066e
commit
b1a70d99aa
31 changed files with 168 additions and 233 deletions
|
|
@ -77,10 +77,14 @@ type Iterator interface {
|
|||
// the iteration interface.
|
||||
//
|
||||
// To get the full results of iteration, do the following:
|
||||
// while (!Next()):
|
||||
// emit result
|
||||
// while (!NextPath()):
|
||||
// emit result
|
||||
//
|
||||
// for graph.Next(it) {
|
||||
// val := it.Result()
|
||||
// ... do things with val.
|
||||
// for it.NextPath() {
|
||||
// ... find other paths to iterate
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// All of them should set iterator.Last to be the last returned value, to
|
||||
// make results work.
|
||||
|
|
@ -135,22 +139,22 @@ type Iterator interface {
|
|||
}
|
||||
|
||||
type Nexter interface {
|
||||
// Next() advances the iterator and returns the next valid result. Returns
|
||||
// (<value>, true) or (nil, false)
|
||||
Next() (Value, bool)
|
||||
// Next advances the iterator to the next value, which will then be available through
|
||||
// the Result method. It returns false if no further advancement is possible.
|
||||
Next() bool
|
||||
|
||||
Iterator
|
||||
}
|
||||
|
||||
// Next is a convenience function that conditionally calls the Next method
|
||||
// of an Iterator if it is a Nexter. If the Iterator is not a Nexter, Next
|
||||
// return a nil Value and false.
|
||||
func Next(it Iterator) (Value, bool) {
|
||||
// returns false.
|
||||
func Next(it Iterator) bool {
|
||||
if n, ok := it.(Nexter); ok {
|
||||
return n.Next()
|
||||
}
|
||||
glog.Errorln("Nexting an un-nextable iterator")
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
|
||||
// FixedIterator wraps iterators that are modifiable by addition of fixed value sets.
|
||||
|
|
@ -253,7 +257,7 @@ func NextLogIn(it Iterator) {
|
|||
}
|
||||
}
|
||||
|
||||
func NextLogOut(it Iterator, val Value, ok bool) (Value, bool) {
|
||||
func NextLogOut(it Iterator, val Value, ok bool) bool {
|
||||
if glog.V(4) {
|
||||
if ok {
|
||||
glog.V(4).Infof("%s %d NEXT IS %d", strings.ToUpper(it.Type().String()), it.UID(), val)
|
||||
|
|
@ -261,5 +265,5 @@ func NextLogOut(it Iterator, val Value, ok bool) (Value, bool) {
|
|||
glog.V(4).Infof("%s %d NEXT DONE", strings.ToUpper(it.Type().String()), it.UID())
|
||||
}
|
||||
}
|
||||
return val, ok
|
||||
return ok
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ func (it *Int64) DebugString(indent int) string {
|
|||
|
||||
// Next() on an Int64 all iterator is a simple incrementing counter.
|
||||
// Return the next integer, and mark it as the result.
|
||||
func (it *Int64) Next() (graph.Value, bool) {
|
||||
func (it *Int64) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
if it.at == -1 {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
|
|
|
|||
|
|
@ -151,25 +151,20 @@ func (it *And) AddSubIterator(sub graph.Iterator) {
|
|||
it.itCount++
|
||||
}
|
||||
|
||||
// Returns the Next value from the And iterator. Because the And is the
|
||||
// intersection of its subiterators, it must choose one subiterator to produce a
|
||||
// candidate, and check this value against the subiterators. A productive choice
|
||||
// of primary iterator is therefore very important.
|
||||
func (it *And) Next() (graph.Value, bool) {
|
||||
// Returns advances the And iterator. Because the And is the intersection of its
|
||||
// subiterators, it must choose one subiterator to produce a candidate, and check
|
||||
// this value against the subiterators. A productive choice of primary iterator
|
||||
// is therefore very important.
|
||||
func (it *And) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
var curr graph.Value
|
||||
var exists bool
|
||||
for {
|
||||
curr, exists = graph.Next(it.primaryIt)
|
||||
if !exists {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
for graph.Next(it.primaryIt) {
|
||||
curr := it.primaryIt.Result()
|
||||
if it.subItsContain(curr) {
|
||||
it.result = curr
|
||||
return graph.NextLogOut(it, curr, true)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
|
||||
func (it *And) Result() graph.Value {
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ func TestTag(t *testing.T) {
|
|||
t.Errorf("Cannot get tag back, got %s", out[0])
|
||||
}
|
||||
|
||||
val, ok := and.Next()
|
||||
if !ok {
|
||||
if !and.Next() {
|
||||
t.Errorf("And did not next")
|
||||
}
|
||||
val := and.Result()
|
||||
if val != 234 {
|
||||
t.Errorf("Unexpected value")
|
||||
}
|
||||
|
|
@ -76,18 +76,15 @@ func TestAndAndFixedIterators(t *testing.T) {
|
|||
t.Error("not accurate")
|
||||
}
|
||||
|
||||
val, ok := and.Next()
|
||||
if val != 3 || ok == false {
|
||||
if !and.Next() || and.Result() != 3 {
|
||||
t.Error("Incorrect first value")
|
||||
}
|
||||
|
||||
val, ok = and.Next()
|
||||
if val != 4 || ok == false {
|
||||
if !and.Next() || and.Result() != 4 {
|
||||
t.Error("Incorrect second value")
|
||||
}
|
||||
|
||||
val, ok = and.Next()
|
||||
if ok {
|
||||
if and.Next() {
|
||||
t.Error("Too many values")
|
||||
}
|
||||
|
||||
|
|
@ -117,8 +114,7 @@ func TestNonOverlappingFixedIterators(t *testing.T) {
|
|||
t.Error("not accurate")
|
||||
}
|
||||
|
||||
_, ok := and.Next()
|
||||
if ok {
|
||||
if and.Next() {
|
||||
t.Error("Too many values")
|
||||
}
|
||||
|
||||
|
|
@ -131,18 +127,15 @@ func TestAllIterators(t *testing.T) {
|
|||
and.AddSubIterator(all2)
|
||||
and.AddSubIterator(all1)
|
||||
|
||||
val, ok := and.Next()
|
||||
if val.(int64) != 4 || ok == false {
|
||||
if !and.Next() || and.Result() != int64(4) {
|
||||
t.Error("Incorrect first value")
|
||||
}
|
||||
|
||||
val, ok = and.Next()
|
||||
if val.(int64) != 5 || ok == false {
|
||||
if !and.Next() || and.Result() != int64(5) {
|
||||
t.Error("Incorrect second value")
|
||||
}
|
||||
|
||||
val, ok = and.Next()
|
||||
if ok {
|
||||
if and.Next() {
|
||||
t.Error("Too many values")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,8 +135,8 @@ func (it *Fixed) Contains(v graph.Value) bool {
|
|||
return graph.ContainsLogOut(it, v, false)
|
||||
}
|
||||
|
||||
// Return the next stored value from the iterator.
|
||||
func (it *Fixed) Next() (graph.Value, bool) {
|
||||
// Next advances the iterator.
|
||||
func (it *Fixed) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
if it.lastIndex == len(it.values) {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
|
|
|
|||
|
|
@ -158,16 +158,13 @@ func (it *HasA) Contains(val graph.Value) bool {
|
|||
// result iterator (a triple iterator based on the last checked value) and returns true if
|
||||
// another match is made.
|
||||
func (it *HasA) NextContains() bool {
|
||||
for {
|
||||
linkVal, ok := graph.Next(it.resultIt)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for graph.Next(it.resultIt) {
|
||||
link := it.resultIt.Result()
|
||||
if glog.V(4) {
|
||||
glog.V(4).Infoln("Quad is", it.ts.Quad(linkVal))
|
||||
glog.V(4).Infoln("Quad is", it.ts.Quad(link))
|
||||
}
|
||||
if it.primaryIt.Contains(linkVal) {
|
||||
it.result = it.ts.TripleDirection(linkVal, it.dir)
|
||||
if it.primaryIt.Contains(link) {
|
||||
it.result = it.ts.TripleDirection(link, it.dir)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -188,20 +185,20 @@ func (it *HasA) NextPath() bool {
|
|||
return it.NextContains()
|
||||
}
|
||||
|
||||
// Get the next result from this iterator. This is simpler than Contains. We have a
|
||||
// Next advances the iterator. This is simpler than Contains. We have a
|
||||
// subiterator we can get a value from, and we can take that resultant triple,
|
||||
// pull our direction out of it, and return that.
|
||||
func (it *HasA) Next() (graph.Value, bool) {
|
||||
func (it *HasA) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
if it.resultIt != nil {
|
||||
it.resultIt.Close()
|
||||
}
|
||||
it.resultIt = &Null{}
|
||||
|
||||
tID, ok := graph.Next(it.primaryIt)
|
||||
if !ok {
|
||||
if !graph.Next(it.primaryIt) {
|
||||
return graph.NextLogOut(it, 0, false)
|
||||
}
|
||||
tID := it.primaryIt.Result()
|
||||
name := it.ts.Quad(tID).Get(it.dir)
|
||||
val := it.ts.ValueOf(name)
|
||||
it.result = val
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ func (it *Null) DebugString(indent int) string {
|
|||
return strings.Repeat(" ", indent) + "(null)"
|
||||
}
|
||||
|
||||
func (it *Null) Next() (graph.Value, bool) {
|
||||
return nil, false
|
||||
func (it *Null) Next() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (it *Null) Result() graph.Value {
|
||||
|
|
|
|||
|
|
@ -153,23 +153,23 @@ func (it *LinksTo) Optimize() (graph.Iterator, bool) {
|
|||
}
|
||||
|
||||
// Next()ing a LinksTo operates as described above.
|
||||
func (it *LinksTo) Next() (graph.Value, bool) {
|
||||
func (it *LinksTo) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
val, ok := graph.Next(it.nextIt)
|
||||
if !ok {
|
||||
// Subiterator is empty, get another one
|
||||
candidate, ok := graph.Next(it.primaryIt)
|
||||
if !ok {
|
||||
// We're out of nodes in our subiterator, so we're done as well.
|
||||
return graph.NextLogOut(it, 0, false)
|
||||
}
|
||||
it.nextIt.Close()
|
||||
it.nextIt = it.ts.TripleIterator(it.dir, candidate)
|
||||
// Recurse -- return the first in the next set.
|
||||
return it.Next()
|
||||
if graph.Next(it.nextIt) {
|
||||
it.result = it.nextIt.Result()
|
||||
return graph.NextLogOut(it, it.nextIt, true)
|
||||
}
|
||||
it.result = val
|
||||
return graph.NextLogOut(it, val, ok)
|
||||
|
||||
// Subiterator is empty, get another one
|
||||
if !graph.Next(it.primaryIt) {
|
||||
// We're out of nodes in our subiterator, so we're done as well.
|
||||
return graph.NextLogOut(it, 0, false)
|
||||
}
|
||||
it.nextIt.Close()
|
||||
it.nextIt = it.ts.TripleIterator(it.dir, it.primaryIt.Result())
|
||||
|
||||
// Recurse -- return the first in the next set.
|
||||
return it.Next()
|
||||
}
|
||||
|
||||
func (it *LinksTo) Result() graph.Value {
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ func TestLinksTo(t *testing.T) {
|
|||
}
|
||||
fixed.Add(val)
|
||||
lto := NewLinksTo(ts, fixed, quad.Object)
|
||||
val, ok := lto.Next()
|
||||
if !ok {
|
||||
if !lto.Next() {
|
||||
t.Error("At least one triple matches the fixed object")
|
||||
}
|
||||
val = lto.Result()
|
||||
if val != 2 {
|
||||
t.Errorf("Quad index 2, such as %s, should match %s", ts.Quad(2), ts.Quad(val))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,8 +51,6 @@ func NewOptional(it graph.Iterator) *Optional {
|
|||
}
|
||||
}
|
||||
|
||||
func (it *Optional) CanNext() bool { return false }
|
||||
|
||||
func (it *Optional) UID() uint64 {
|
||||
return it.uid
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,35 +141,34 @@ func (it *Or) AddSubIterator(sub graph.Iterator) {
|
|||
it.itCount++
|
||||
}
|
||||
|
||||
// Returns the Next value from the Or graph.iterator. Because the Or is the
|
||||
// union of its subiterators, it must produce from all subiterators -- unless
|
||||
// it's shortcircuiting, in which case, it's the first one that returns anything.
|
||||
func (it *Or) Next() (graph.Value, bool) {
|
||||
// Next advances the Or graph.iterator. Because the Or is the union of its
|
||||
// subiterators, it must produce from all subiterators -- unless it it
|
||||
// shortcircuiting, in which case, it is the first one that returns anything.
|
||||
func (it *Or) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
var curr graph.Value
|
||||
var exists bool
|
||||
firstTime := false
|
||||
var first bool
|
||||
for {
|
||||
if it.currentIterator == -1 {
|
||||
it.currentIterator = 0
|
||||
firstTime = true
|
||||
first = true
|
||||
}
|
||||
curIt := it.internalIterators[it.currentIterator]
|
||||
curr, exists = graph.Next(curIt)
|
||||
if !exists {
|
||||
if it.isShortCircuiting && !firstTime {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
it.currentIterator++
|
||||
if it.currentIterator == it.itCount {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
} else {
|
||||
it.result = curr
|
||||
return graph.NextLogOut(it, curr, true)
|
||||
|
||||
if graph.Next(curIt) {
|
||||
it.result = curIt.Result()
|
||||
return graph.NextLogOut(it, it.result, true)
|
||||
}
|
||||
|
||||
if it.isShortCircuiting && !first {
|
||||
break
|
||||
}
|
||||
it.currentIterator++
|
||||
if it.currentIterator == it.itCount {
|
||||
break
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
|
||||
func (it *Or) Result() graph.Value {
|
||||
|
|
|
|||
|
|
@ -23,12 +23,8 @@ import (
|
|||
|
||||
func iterated(it graph.Iterator) []int {
|
||||
var res []int
|
||||
for {
|
||||
val, ok := graph.Next(it)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
res = append(res, val.(int))
|
||||
for graph.Next(it) {
|
||||
res = append(res, it.Result().(int))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,12 +129,8 @@ func (qs *queryShape) MakeNode(it graph.Iterator) *Node {
|
|||
}
|
||||
case graph.Fixed:
|
||||
n.IsFixed = true
|
||||
for {
|
||||
val, more := graph.Next(it)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
n.Values = append(n.Values, qs.ts.NameOf(val))
|
||||
for graph.Next(it) {
|
||||
n.Values = append(n.Values, qs.ts.NameOf(it.Result()))
|
||||
}
|
||||
case graph.HasA:
|
||||
hasa := it.(*HasA)
|
||||
|
|
|
|||
|
|
@ -127,20 +127,15 @@ func (it *Comparison) Clone() graph.Iterator {
|
|||
return out
|
||||
}
|
||||
|
||||
func (it *Comparison) Next() (graph.Value, bool) {
|
||||
var val graph.Value
|
||||
var ok bool
|
||||
for {
|
||||
val, ok = graph.Next(it.subIt)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
func (it *Comparison) Next() bool {
|
||||
for graph.Next(it.subIt) {
|
||||
val := it.subIt.Result()
|
||||
if it.doComparison(val) {
|
||||
break
|
||||
it.result = val
|
||||
return true
|
||||
}
|
||||
}
|
||||
it.result = val
|
||||
return val, ok
|
||||
return false
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
|
|
|
|||
|
|
@ -69,12 +69,8 @@ func TestValueComparison(t *testing.T) {
|
|||
vc := NewComparison(simpleFixedIterator(), test.operator, test.operand, ts)
|
||||
|
||||
var got []string
|
||||
for {
|
||||
val, ok := vc.Next()
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
got = append(got, ts.NameOf(val))
|
||||
for vc.Next() {
|
||||
got = append(got, ts.NameOf(vc.Result()))
|
||||
}
|
||||
if !reflect.DeepEqual(got, test.expect) {
|
||||
t.Errorf("Failed to show %s, got:%q expect:%q", test.message, got, test.expect)
|
||||
|
|
|
|||
|
|
@ -101,10 +101,10 @@ func (it *AllIterator) Clone() graph.Iterator {
|
|||
return out
|
||||
}
|
||||
|
||||
func (it *AllIterator) Next() (graph.Value, bool) {
|
||||
func (it *AllIterator) Next() bool {
|
||||
if !it.open {
|
||||
it.result = nil
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
var out []byte
|
||||
out = make([]byte, len(it.iter.Key()))
|
||||
|
|
@ -115,10 +115,10 @@ func (it *AllIterator) Next() (graph.Value, bool) {
|
|||
}
|
||||
if !bytes.HasPrefix(out, it.prefix) {
|
||||
it.Close()
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
it.result = out
|
||||
return out, true
|
||||
return true
|
||||
}
|
||||
|
||||
func (it *AllIterator) ResultTree() *graph.ResultTree {
|
||||
|
|
|
|||
|
|
@ -117,19 +117,19 @@ func (it *Iterator) Close() {
|
|||
}
|
||||
}
|
||||
|
||||
func (it *Iterator) Next() (graph.Value, bool) {
|
||||
func (it *Iterator) Next() bool {
|
||||
if it.iter == nil {
|
||||
it.result = nil
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
if !it.open {
|
||||
it.result = nil
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
if !it.iter.Valid() {
|
||||
it.result = nil
|
||||
it.Close()
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
if bytes.HasPrefix(it.iter.Key(), it.nextPrefix) {
|
||||
out := make([]byte, len(it.iter.Key()))
|
||||
|
|
@ -139,11 +139,11 @@ func (it *Iterator) Next() (graph.Value, bool) {
|
|||
if !ok {
|
||||
it.Close()
|
||||
}
|
||||
return out, true
|
||||
return true
|
||||
}
|
||||
it.Close()
|
||||
it.result = nil
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
|
||||
func (it *Iterator) ResultTree() *graph.ResultTree {
|
||||
|
|
|
|||
|
|
@ -45,12 +45,8 @@ func makeTripleSet() []*quad.Quad {
|
|||
|
||||
func iteratedTriples(qs graph.TripleStore, it graph.Iterator) []*quad.Quad {
|
||||
var res ordered
|
||||
for {
|
||||
val, ok := graph.Next(it)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
res = append(res, qs.Quad(val))
|
||||
for graph.Next(it) {
|
||||
res = append(res, qs.Quad(it.Result()))
|
||||
}
|
||||
sort.Sort(res)
|
||||
return res
|
||||
|
|
@ -85,12 +81,8 @@ func (o ordered) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
|||
|
||||
func iteratedNames(qs graph.TripleStore, it graph.Iterator) []string {
|
||||
var res []string
|
||||
for {
|
||||
val, ok := graph.Next(it)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
res = append(res, qs.NameOf(val))
|
||||
for graph.Next(it) {
|
||||
res = append(res, qs.NameOf(it.Result()))
|
||||
}
|
||||
sort.Strings(res)
|
||||
return res
|
||||
|
|
@ -266,8 +258,8 @@ func TestIterator(t *testing.T) {
|
|||
it.Reset()
|
||||
|
||||
it = qs.TriplesAllIterator()
|
||||
edge, _ := graph.Next(it)
|
||||
triple := qs.Quad(edge)
|
||||
graph.Next(it)
|
||||
triple := qs.Quad(it.Result())
|
||||
set := makeTripleSet()
|
||||
var ok bool
|
||||
for _, t := range set {
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ func (ts *TripleStore) optimizeLinksTo(it *iterator.LinksTo) (graph.Iterator, bo
|
|||
if primary.Type() == graph.Fixed {
|
||||
size, _ := primary.Size()
|
||||
if size == 1 {
|
||||
val, ok := graph.Next(primary)
|
||||
if !ok {
|
||||
panic("Sizes lie")
|
||||
if !graph.Next(primary) {
|
||||
panic("unexpected size during optimize")
|
||||
}
|
||||
val := primary.Result()
|
||||
newIt := ts.TripleIterator(it.Direction(), val)
|
||||
nt := newIt.Tagger()
|
||||
nt.CopyFrom(it)
|
||||
|
|
|
|||
|
|
@ -36,15 +36,13 @@ func (it *AllIterator) SubIterators() []graph.Iterator {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (it *AllIterator) Next() (graph.Value, bool) {
|
||||
next, out := it.Int64.Next()
|
||||
if !out {
|
||||
return next, out
|
||||
func (it *AllIterator) Next() bool {
|
||||
if !it.Int64.Next() {
|
||||
return false
|
||||
}
|
||||
i64 := next.(int64)
|
||||
_, ok := it.ts.revIdMap[i64]
|
||||
_, ok := it.ts.revIdMap[it.Int64.Result().(int64)]
|
||||
if !ok {
|
||||
return it.Next()
|
||||
}
|
||||
return next, out
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ func (it *Iterator) Clone() graph.Iterator {
|
|||
|
||||
func (it *Iterator) Close() {}
|
||||
|
||||
func (it *Iterator) Next() (graph.Value, bool) {
|
||||
func (it *Iterator) Next() bool {
|
||||
graph.NextLogIn(it)
|
||||
if it.tree.Max() == nil || it.result == int64(it.tree.Max().(Int64)) {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
|
|
|
|||
|
|
@ -132,11 +132,8 @@ func (ts *TripleStore) tripleExists(t *quad.Quad) (bool, int64) {
|
|||
}
|
||||
it := NewLlrbIterator(smallest_tree, "")
|
||||
|
||||
for {
|
||||
val, ok := it.Next()
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for it.Next() {
|
||||
val := it.Result()
|
||||
if t.Equals(&ts.triples[val.(int64)]) {
|
||||
return true, val.(int64)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ func (ts *TripleStore) optimizeLinksTo(it *iterator.LinksTo) (graph.Iterator, bo
|
|||
if primary.Type() == graph.Fixed {
|
||||
size, _ := primary.Size()
|
||||
if size == 1 {
|
||||
val, ok := graph.Next(primary)
|
||||
if !ok {
|
||||
panic("Sizes lie")
|
||||
if !graph.Next(primary) {
|
||||
panic("unexpected size during optimize")
|
||||
}
|
||||
val := primary.Result()
|
||||
newIt := ts.TripleIterator(it.Direction(), val)
|
||||
nt := newIt.Tagger()
|
||||
nt.CopyFrom(it)
|
||||
|
|
|
|||
|
|
@ -114,10 +114,10 @@ func TestIteratorsAndNextResultOrderA(t *testing.T) {
|
|||
outerAnd.AddSubIterator(fixed)
|
||||
outerAnd.AddSubIterator(hasa)
|
||||
|
||||
val, ok := outerAnd.Next()
|
||||
if !ok {
|
||||
if !outerAnd.Next() {
|
||||
t.Error("Expected one matching subtree")
|
||||
}
|
||||
val := outerAnd.Result()
|
||||
if ts.NameOf(val) != "C" {
|
||||
t.Errorf("Matching subtree should be %s, got %s", "barak", ts.NameOf(val))
|
||||
}
|
||||
|
|
@ -138,8 +138,7 @@ func TestIteratorsAndNextResultOrderA(t *testing.T) {
|
|||
t.Errorf("Unexpected result, got:%q expect:%q", got, expect)
|
||||
}
|
||||
|
||||
val, ok = outerAnd.Next()
|
||||
if ok {
|
||||
if outerAnd.Next() {
|
||||
t.Error("More than one possible top level output?")
|
||||
}
|
||||
}
|
||||
|
|
@ -190,8 +189,7 @@ func TestRemoveTriple(t *testing.T) {
|
|||
hasa := iterator.NewHasA(ts, innerAnd, quad.Object)
|
||||
|
||||
newIt, _ := hasa.Optimize()
|
||||
_, ok := graph.Next(newIt)
|
||||
if ok {
|
||||
if graph.Next(newIt) {
|
||||
t.Error("E should not have any followers.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ func (it *Iterator) Clone() graph.Iterator {
|
|||
return m
|
||||
}
|
||||
|
||||
func (it *Iterator) Next() (graph.Value, bool) {
|
||||
func (it *Iterator) Next() bool {
|
||||
var result struct {
|
||||
Id string "_id"
|
||||
//Sub string "Sub"
|
||||
|
|
@ -151,10 +151,10 @@ func (it *Iterator) Next() (graph.Value, bool) {
|
|||
if err != nil {
|
||||
glog.Errorln("Error Nexting Iterator: ", err)
|
||||
}
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
it.result = result.Id
|
||||
return result.Id, true
|
||||
return true
|
||||
}
|
||||
|
||||
func (it *Iterator) ResultTree() *graph.ResultTree {
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ func (ts *TripleStore) optimizeLinksTo(it *iterator.LinksTo) (graph.Iterator, bo
|
|||
if primary.Type() == graph.Fixed {
|
||||
size, _ := primary.Size()
|
||||
if size == 1 {
|
||||
val, ok := graph.Next(primary)
|
||||
if !ok {
|
||||
panic("Sizes lie")
|
||||
if !graph.Next(primary) {
|
||||
panic("unexpected size during optimize")
|
||||
}
|
||||
val := primary.Result()
|
||||
newIt := ts.TripleIterator(it.Direction(), val)
|
||||
nt := newIt.Tagger()
|
||||
nt.CopyFrom(it)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@
|
|||
|
||||
package graph
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ResultTree struct {
|
||||
result Value
|
||||
|
|
@ -26,14 +29,13 @@ func NewResultTree(result Value) *ResultTree {
|
|||
}
|
||||
|
||||
func (t *ResultTree) String() string {
|
||||
base := fmt.Sprintf("(%d", t.result)
|
||||
if len(t.subtrees) != 0 {
|
||||
for _, sub := range t.subtrees {
|
||||
base += fmt.Sprintf(" %s", sub)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "(%d", t.result)
|
||||
for _, sub := range t.subtrees {
|
||||
fmt.Fprintf(&buf, " %s", sub)
|
||||
}
|
||||
base += ")"
|
||||
return base
|
||||
buf.WriteByte(')')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (t *ResultTree) AddSubtree(sub *ResultTree) {
|
||||
|
|
@ -41,22 +43,15 @@ func (t *ResultTree) AddSubtree(sub *ResultTree) {
|
|||
}
|
||||
|
||||
func StringResultTreeEvaluator(it Nexter) string {
|
||||
ok := true
|
||||
out := ""
|
||||
for {
|
||||
_, ok = it.Next()
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
out += it.ResultTree().String()
|
||||
out += "\n"
|
||||
for it.NextPath() == true {
|
||||
out += " "
|
||||
out += it.ResultTree().String()
|
||||
out += "\n"
|
||||
var buf bytes.Buffer
|
||||
for it.Next() {
|
||||
fmt.Fprintln(&buf, it.ResultTree())
|
||||
for it.NextPath() {
|
||||
buf.WriteByte(' ')
|
||||
fmt.Fprintln(&buf, it.ResultTree())
|
||||
}
|
||||
}
|
||||
return out
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func PrintResultTreeEvaluator(it Nexter) {
|
||||
|
|
|
|||
|
|
@ -151,8 +151,7 @@ func runIteratorToArray(it graph.Iterator, ses *Session, limit int) []map[string
|
|||
if ses.doHalt {
|
||||
return nil
|
||||
}
|
||||
_, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
break
|
||||
}
|
||||
tags := make(map[string]graph.Value)
|
||||
|
|
@ -187,11 +186,10 @@ func runIteratorToArrayNoTags(it graph.Iterator, ses *Session, limit int) []stri
|
|||
if ses.doHalt {
|
||||
return nil
|
||||
}
|
||||
val, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
break
|
||||
}
|
||||
output = append(output, ses.ts.NameOf(val))
|
||||
output = append(output, ses.ts.NameOf(it.Result()))
|
||||
count++
|
||||
if limit >= 0 && count >= limit {
|
||||
break
|
||||
|
|
@ -208,8 +206,7 @@ func runIteratorWithCallback(it graph.Iterator, ses *Session, callback otto.Valu
|
|||
if ses.doHalt {
|
||||
return
|
||||
}
|
||||
_, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
break
|
||||
}
|
||||
tags := make(map[string]graph.Value)
|
||||
|
|
@ -249,8 +246,7 @@ func runIteratorOnSession(it graph.Iterator, ses *Session) {
|
|||
if ses.doHalt {
|
||||
return
|
||||
}
|
||||
_, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
break
|
||||
}
|
||||
tags := make(map[string]graph.Value)
|
||||
|
|
|
|||
|
|
@ -88,11 +88,7 @@ func (s *Session) ExecInput(input string, c chan interface{}, limit int) {
|
|||
if glog.V(2) {
|
||||
glog.V(2).Infoln(it.DebugString(0))
|
||||
}
|
||||
for {
|
||||
_, ok := graph.Next(it)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for graph.Next(it) {
|
||||
tags := make(map[string]graph.Value)
|
||||
it.TagResults(tags)
|
||||
c <- tags
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ func TestMemstoreBackedSexp(t *testing.T) {
|
|||
if it.Type() != test.typ {
|
||||
t.Errorf("Incorrect type for %s, got:%q expect %q", test.message, it.Type(), test.expect)
|
||||
}
|
||||
got, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
t.Errorf("Failed to %s", test.message)
|
||||
}
|
||||
got := it.Result()
|
||||
if expect := ts.ValueOf(test.expect); got != expect {
|
||||
t.Errorf("Incorrect result for %s, got:%v expect %v", test.message, got, expect)
|
||||
}
|
||||
|
|
@ -88,10 +88,10 @@ func TestTreeConstraintParse(t *testing.T) {
|
|||
if it.Type() != graph.And {
|
||||
t.Error("Odd iterator tree. Got: %s", it.DebugString(0))
|
||||
}
|
||||
out, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
t.Error("Got no results")
|
||||
}
|
||||
out := it.Result()
|
||||
if out != ts.ValueOf("i") {
|
||||
t.Errorf("Got %d, expected %d", out, ts.ValueOf("i"))
|
||||
}
|
||||
|
|
@ -105,8 +105,7 @@ func TestTreeConstraintTagParse(t *testing.T) {
|
|||
"(:like\n" +
|
||||
"($a (:is :good))))"
|
||||
it := BuildIteratorTreeForQuery(ts, query)
|
||||
_, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
t.Error("Got no results")
|
||||
}
|
||||
tags := make(map[string]graph.Value)
|
||||
|
|
@ -135,15 +134,14 @@ func TestMultipleConstraintParse(t *testing.T) {
|
|||
if it.Type() != graph.And {
|
||||
t.Error("Odd iterator tree. Got: %s", it.DebugString(0))
|
||||
}
|
||||
out, ok := graph.Next(it)
|
||||
if !ok {
|
||||
if !graph.Next(it) {
|
||||
t.Error("Got no results")
|
||||
}
|
||||
out := it.Result()
|
||||
if out != ts.ValueOf("i") {
|
||||
t.Errorf("Got %d, expected %d", out, ts.ValueOf("i"))
|
||||
}
|
||||
_, ok = graph.Next(it)
|
||||
if ok {
|
||||
if graph.Next(it) {
|
||||
t.Error("Too many results")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,11 +77,7 @@ func (s *Session) ExecInput(input string, out chan interface{}, limit int) {
|
|||
fmt.Println(it.DebugString(0))
|
||||
}
|
||||
nResults := 0
|
||||
for {
|
||||
_, ok := graph.Next(it)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for graph.Next(it) {
|
||||
tags := make(map[string]graph.Value)
|
||||
it.TagResults(tags)
|
||||
out <- &tags
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue