Added comments for the loop iterator.
This commit is contained in:
parent
d9b67c8335
commit
a0318aa7b2
2 changed files with 30 additions and 10 deletions
|
|
@ -7,6 +7,14 @@ import (
|
||||||
"github.com/google/cayley/graph"
|
"github.com/google/cayley/graph"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Loop implements a loop operator. Composed of the following members:
|
||||||
|
// - baseIt - the iterator composing the query preceding the loop.
|
||||||
|
// - loopIt - an iterator implementing the loop morph query; has an EntryPoint iterator as starting point.
|
||||||
|
// - loopEntryIt - the starting point for the loop iterator; knowing this allows us to plug and change the source iterator
|
||||||
|
// - filterIt - an iterator implementing the filtering part of the loop; has an EntryPoint iterator as starting point
|
||||||
|
// - filterEntryIt - the starting point for the filter iterator; allows to plug and change the source iterator
|
||||||
|
// - prevValuesIt - the results obtained for each loop iteration will be stored in this iterator;
|
||||||
|
// this allows us to use this iterator as source for the next loop
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
uid uint64
|
uid uint64
|
||||||
tags graph.Tagger
|
tags graph.Tagger
|
||||||
|
|
@ -50,6 +58,7 @@ func (it *Loop) Tagger() *graph.Tagger {
|
||||||
return &it.tags
|
return &it.tags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) TagResults(dst map[string]graph.Value) {
|
func (it *Loop) TagResults(dst map[string]graph.Value) {
|
||||||
for _, tag := range it.tags.Tags() {
|
for _, tag := range it.tags.Tags() {
|
||||||
dst[tag] = it.Result()
|
dst[tag] = it.Result()
|
||||||
|
|
@ -63,6 +72,7 @@ func (it *Loop) TagResults(dst map[string]graph.Value) {
|
||||||
it.loopIt.TagResults(dst)
|
it.loopIt.TagResults(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) Contains(val graph.Value) bool {
|
func (it *Loop) Contains(val graph.Value) bool {
|
||||||
graph.ContainsLogIn(it, val)
|
graph.ContainsLogIn(it, val)
|
||||||
if it.loopIt.Contains(val) {
|
if it.loopIt.Contains(val) {
|
||||||
|
|
@ -71,6 +81,7 @@ func (it *Loop) Contains(val graph.Value) bool {
|
||||||
return graph.ContainsLogOut(it, val, false)
|
return graph.ContainsLogOut(it, val, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) Clone() graph.Iterator {
|
func (it *Loop) Clone() graph.Iterator {
|
||||||
out := NewLoop(it.ts, it.baseIt, it.loopIt, it.filterIt, it.loopEntryIt, it.filterEntryIt, it.loops, it.bounded)
|
out := NewLoop(it.ts, it.baseIt, it.loopIt, it.filterIt, it.loopEntryIt, it.filterEntryIt, it.loops, it.bounded)
|
||||||
out.tags.CopyFrom(it)
|
out.tags.CopyFrom(it)
|
||||||
|
|
@ -116,20 +127,18 @@ func (it *Loop) advanceLoop() {
|
||||||
it.prevValuesIt = it.ts.FixedIterator()
|
it.prevValuesIt = it.ts.FixedIterator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkFilter checks whether a value is expandable using the filter iterator.
|
||||||
func (it *Loop) checkFilter(value graph.Value) bool {
|
func (it *Loop) checkFilter(value graph.Value) bool {
|
||||||
|
// Create a fixed iterator containing the value
|
||||||
fixed := it.ts.FixedIterator()
|
fixed := it.ts.FixedIterator()
|
||||||
fixed.Add(value)
|
fixed.Add(value)
|
||||||
|
|
||||||
|
// Set is as the source for the filter iterator.
|
||||||
it.filterEntryIt.SetIterator(fixed)
|
it.filterEntryIt.SetIterator(fixed)
|
||||||
it.filterIt.Reset()
|
it.filterIt.Reset()
|
||||||
|
|
||||||
//fmt.Println("Before add value")
|
// Check if the filter has a next value.
|
||||||
//it.filterEntryIt.Add(value)
|
|
||||||
//fmt.Println("After add value")
|
|
||||||
|
|
||||||
//fmt.Println("Before next")
|
|
||||||
answer := graph.Next(it.filterIt)
|
answer := graph.Next(it.filterIt)
|
||||||
//fmt.Println("After next")
|
|
||||||
return answer
|
return answer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,11 +157,12 @@ func (it *Loop) next() bool {
|
||||||
|
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
if found := graph.Next(it.loopIt); !found {
|
if found := graph.Next(it.loopIt); !found {
|
||||||
// A value has not been found, try looping again
|
// A value has not been found, try a new loop iteration.
|
||||||
it.advanceLoop()
|
it.advanceLoop()
|
||||||
return it.next()
|
return it.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For a found value, we must check it passes the filter.
|
||||||
if it.checkFilter(it.loopIt.Result()) {
|
if it.checkFilter(it.loopIt.Result()) {
|
||||||
// A value has been found.
|
// A value has been found.
|
||||||
it.result = it.loopIt.Result()
|
it.result = it.loopIt.Result()
|
||||||
|
|
@ -168,10 +178,12 @@ func (it *Loop) Result() graph.Value {
|
||||||
return it.result
|
return it.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) NextPath() bool {
|
func (it *Loop) NextPath() bool {
|
||||||
return it.loopIt.NextPath()
|
return it.loopIt.NextPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) Stats() graph.IteratorStats {
|
func (it *Loop) Stats() graph.IteratorStats {
|
||||||
subitStats := it.loopIt.Stats()
|
subitStats := it.loopIt.Stats()
|
||||||
// TODO(barakmich): These should really come from the triplestore itself
|
// TODO(barakmich): These should really come from the triplestore itself
|
||||||
|
|
@ -197,10 +209,12 @@ func (it *Loop) Optimize() (graph.Iterator, bool) {
|
||||||
return it, false
|
return it, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) SubIterators() []graph.Iterator {
|
func (it *Loop) SubIterators() []graph.Iterator {
|
||||||
return []graph.Iterator{it.baseIt, it.loopIt}
|
return []graph.Iterator{it.baseIt, it.loopIt}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
func (it *Loop) DebugString(indent int) string {
|
func (it *Loop) DebugString(indent int) string {
|
||||||
return fmt.Sprintf("%s(%s %d \n%s)",
|
return fmt.Sprintf("%s(%s %d \n%s)",
|
||||||
strings.Repeat(" ", indent),
|
strings.Repeat(" ", indent),
|
||||||
|
|
@ -210,6 +224,7 @@ func (it *Loop) DebugString(indent int) string {
|
||||||
func (it *Loop) Close() {
|
func (it *Loop) Close() {
|
||||||
it.baseIt.Close()
|
it.baseIt.Close()
|
||||||
it.loopIt.Close()
|
it.loopIt.Close()
|
||||||
|
it.filterIt.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEPRECATED
|
// DEPRECATED
|
||||||
|
|
|
||||||
|
|
@ -328,15 +328,17 @@ func buildIteratorTreeHelper(obj *otto.Object, ts graph.TripleStore, base graph.
|
||||||
thirdArg, _ := arg.Object().Get("2")
|
thirdArg, _ := arg.Object().Get("2")
|
||||||
|
|
||||||
// Parse the loop iterating sequence
|
// Parse the loop iterating sequence
|
||||||
// Check if the first argument is a vertex chain
|
|
||||||
if isVertexChain(firstArg.Object()) {
|
if isVertexChain(firstArg.Object()) {
|
||||||
return iterator.NewNull()
|
return iterator.NewNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the loop iterator: first, create an entry point iterator.
|
||||||
loopEntryIt := iterator.NewEntryPoint(subIt)
|
loopEntryIt := iterator.NewEntryPoint(subIt)
|
||||||
|
// Then create a loop iterator on top of the entry point.
|
||||||
loopIt := buildIteratorTreeHelper(firstArg.Object(), ts, loopEntryIt)
|
loopIt := buildIteratorTreeHelper(firstArg.Object(), ts, loopEntryIt)
|
||||||
|
|
||||||
// Parse the number of loops to execute
|
// Parse the number of loops to execute.
|
||||||
|
// bounded=false means it will loop until no more results are produced.
|
||||||
noLoops := 0
|
noLoops := 0
|
||||||
bounded := false
|
bounded := false
|
||||||
if secondArg.IsNumber() {
|
if secondArg.IsNumber() {
|
||||||
|
|
@ -356,20 +358,23 @@ func buildIteratorTreeHelper(obj *otto.Object, ts graph.TripleStore, base graph.
|
||||||
thirdArg = secondArg
|
thirdArg = secondArg
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the number of loops is negative, the loop is unbounded
|
// If the number of loops is le 0, the loop is unbounded
|
||||||
if noLoops <= 0 {
|
if noLoops <= 0 {
|
||||||
bounded = false
|
bounded = false
|
||||||
} else {
|
} else {
|
||||||
bounded = true
|
bounded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the filter iterator
|
||||||
filterEntryIt := iterator.NewEntryPoint(nil)
|
filterEntryIt := iterator.NewEntryPoint(nil)
|
||||||
var filterIt graph.Iterator
|
var filterIt graph.Iterator
|
||||||
if thirdArg.IsNull() || thirdArg.IsUndefined() {
|
if thirdArg.IsNull() || thirdArg.IsUndefined() {
|
||||||
|
// There is no filter morphism, use the entry point as a filter.
|
||||||
filterIt = filterEntryIt
|
filterIt = filterEntryIt
|
||||||
} else if isVertexChain(thirdArg.Object()) {
|
} else if isVertexChain(thirdArg.Object()) {
|
||||||
return iterator.NewNull()
|
return iterator.NewNull()
|
||||||
} else {
|
} else {
|
||||||
|
// There is a filter morphism, create the filter iterator based on the entry point.
|
||||||
filterIt = buildIteratorTreeHelper(thirdArg.Object(), ts, filterEntryIt)
|
filterIt = buildIteratorTreeHelper(thirdArg.Object(), ts, filterEntryIt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue