Base nexting on interface satisfaction
This is done unsubtlely at the moment and there is plenty of room for optimisation of assertion location to prevent repeated reasserting as is done now.
This commit is contained in:
parent
b498a06a7b
commit
d6f94be514
27 changed files with 57 additions and 82 deletions
|
|
@ -31,7 +31,6 @@ import (
|
|||
|
||||
// An All iterator across a range of int64 values, from `max` to `min`.
|
||||
type Int64 struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
max, min int64
|
||||
|
|
|
|||
|
|
@ -22,10 +22,9 @@ import (
|
|||
"github.com/google/cayley/graph"
|
||||
)
|
||||
|
||||
// The And iterator. Consists of a Base and a number of subiterators, the primary of which will
|
||||
// The And iterator. Consists of a number of subiterators, the primary of which will
|
||||
// be Next()ed if next is called.
|
||||
type And struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
internalIterators []graph.Iterator
|
||||
|
|
@ -60,7 +59,7 @@ func (it *And) Tagger() *graph.Tagger {
|
|||
return &it.tags
|
||||
}
|
||||
|
||||
// Overrides Base TagResults, as it needs to add it's own results and
|
||||
// An extended TagResults, as it needs to add it's own results and
|
||||
// recurse down it's subiterators.
|
||||
func (it *And) TagResults(dst map[string]graph.Value) {
|
||||
for _, tag := range it.tags.Tags() {
|
||||
|
|
@ -161,7 +160,7 @@ func (it *And) Next() (graph.Value, bool) {
|
|||
var curr graph.Value
|
||||
var exists bool
|
||||
for {
|
||||
curr, exists = it.primaryIt.Next()
|
||||
curr, exists = graph.Next(it.primaryIt)
|
||||
if !exists {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,14 +145,14 @@ func optimizeOrder(its []graph.Iterator) []graph.Iterator {
|
|||
// all of it's contents, and to Check() each of those against everyone
|
||||
// else.
|
||||
for _, it := range its {
|
||||
if !it.CanNext() {
|
||||
if _, canNext := it.(graph.Nexter); !canNext {
|
||||
bad = append(bad, it)
|
||||
continue
|
||||
}
|
||||
rootStats := it.Stats()
|
||||
cost := rootStats.NextCost
|
||||
for _, f := range its {
|
||||
if !f.CanNext() {
|
||||
if _, canNext := it.(graph.Nexter); !canNext {
|
||||
continue
|
||||
}
|
||||
if f == it {
|
||||
|
|
@ -177,7 +177,7 @@ func optimizeOrder(its []graph.Iterator) []graph.Iterator {
|
|||
|
||||
// ... push everyone else after...
|
||||
for _, it := range its {
|
||||
if !it.CanNext() {
|
||||
if _, canNext := it.(graph.Nexter); !canNext {
|
||||
continue
|
||||
}
|
||||
if it != best {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import (
|
|||
// A Fixed iterator consists of it's values, an index (where it is in the process of Next()ing) and
|
||||
// an equality function.
|
||||
type Fixed struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
values []graph.Value
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ import (
|
|||
// a primary subiterator, a direction in which the triples for that subiterator point,
|
||||
// and a temporary holder for the iterator generated on Check().
|
||||
type HasA struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
ts graph.TripleStore
|
||||
|
|
@ -159,7 +158,7 @@ func (it *HasA) Check(val graph.Value) bool {
|
|||
// another match is made.
|
||||
func (it *HasA) GetCheckResult() bool {
|
||||
for {
|
||||
linkVal, ok := it.resultIt.Next()
|
||||
linkVal, ok := graph.Next(it.resultIt)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
|
@ -198,7 +197,7 @@ func (it *HasA) Next() (graph.Value, bool) {
|
|||
}
|
||||
it.resultIt = &Null{}
|
||||
|
||||
tID, ok := it.primaryIt.Next()
|
||||
tID, ok := graph.Next(it.primaryIt)
|
||||
if !ok {
|
||||
return graph.NextLogOut(it, 0, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@
|
|||
|
||||
package iterator
|
||||
|
||||
// Define the general iterator interface, as well as the Base which all
|
||||
// iterators can "inherit" from to get default iterator functionality.
|
||||
// Define the general iterator interface.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
|
@ -30,14 +29,6 @@ func NextUID() uint64 {
|
|||
return atomic.AddUint64(&nextIteratorID, 1) - 1
|
||||
}
|
||||
|
||||
// The Base iterator is the iterator other iterators inherit from to get some
|
||||
// default functionality.
|
||||
type Base struct {
|
||||
}
|
||||
|
||||
// Accessor
|
||||
func (it *Base) CanNext() bool { return true }
|
||||
|
||||
// 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.
|
||||
|
|
@ -88,8 +79,6 @@ func (it *Null) DebugString(indent int) string {
|
|||
return strings.Repeat(" ", indent) + "(null)"
|
||||
}
|
||||
|
||||
func (it *Null) CanNext() bool { return true }
|
||||
|
||||
func (it *Null) Next() (graph.Value, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ import (
|
|||
// for each node) the subiterator, and the direction the iterator comes from.
|
||||
// `next_it` is the tempoarary iterator held per result in `primary_it`.
|
||||
type LinksTo struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
ts graph.TripleStore
|
||||
|
|
@ -155,10 +154,10 @@ func (it *LinksTo) Optimize() (graph.Iterator, bool) {
|
|||
// Next()ing a LinksTo operates as described above.
|
||||
func (it *LinksTo) Next() (graph.Value, bool) {
|
||||
graph.NextLogIn(it)
|
||||
val, ok := it.nextIt.Next()
|
||||
val, ok := graph.Next(it.nextIt)
|
||||
if !ok {
|
||||
// Subiterator is empty, get another one
|
||||
candidate, ok := it.primaryIt.Next()
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/barakmich/glog"
|
||||
|
||||
"github.com/google/cayley/graph"
|
||||
)
|
||||
|
||||
|
|
@ -78,16 +76,6 @@ 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) {
|
||||
glog.Errorln("Nexting an un-nextable iterator")
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (it *Optional) ResultTree() *graph.ResultTree {
|
||||
return graph.NewResultTree(it.Result())
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import (
|
|||
)
|
||||
|
||||
type Or struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
isShortCircuiting bool
|
||||
|
|
@ -156,7 +155,7 @@ func (it *Or) Next() (graph.Value, bool) {
|
|||
firstTime = true
|
||||
}
|
||||
curIt := it.internalIterators[it.currentIterator]
|
||||
curr, exists = curIt.Next()
|
||||
curr, exists = graph.Next(curIt)
|
||||
if !exists {
|
||||
if it.isShortCircuiting && !firstTime {
|
||||
return graph.NextLogOut(it, nil, false)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
func iterated(it graph.Iterator) []int {
|
||||
var res []int
|
||||
for {
|
||||
val, ok := it.Next()
|
||||
val, ok := graph.Next(it)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ func (qs *queryShape) MakeNode(it graph.Iterator) *Node {
|
|||
case graph.Fixed:
|
||||
n.IsFixed = true
|
||||
for {
|
||||
val, more := it.Next()
|
||||
val, more := graph.Next(it)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ const (
|
|||
)
|
||||
|
||||
type Comparison struct {
|
||||
Base
|
||||
uid uint64
|
||||
tags graph.Tagger
|
||||
subIt graph.Iterator
|
||||
|
|
@ -132,7 +131,7 @@ func (it *Comparison) Next() (graph.Value, bool) {
|
|||
var val graph.Value
|
||||
var ok bool
|
||||
for {
|
||||
val, ok = it.subIt.Next()
|
||||
val, ok = graph.Next(it.subIt)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue