Address review comments
This commit is contained in:
parent
430ff507f0
commit
5eed4d9667
19 changed files with 125 additions and 139 deletions
|
|
@ -100,7 +100,7 @@ type Iterator interface {
|
||||||
// Contains returns whether the value is within the set held by the iterator.
|
// Contains returns whether the value is within the set held by the iterator.
|
||||||
Contains(Value) bool
|
Contains(Value) bool
|
||||||
|
|
||||||
// Err returns the error (if any) encountered during iteration.
|
// Err returns any error that was encountered by the Iterator.
|
||||||
Err() error
|
Err() error
|
||||||
|
|
||||||
// Start iteration from the beginning
|
// Start iteration from the beginning
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,6 @@ func (it *Int64) Next() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Int64) Err() error {
|
func (it *Int64) Err() error {
|
||||||
// This iterator should never error.
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ type And struct {
|
||||||
primaryIt graph.Iterator
|
primaryIt graph.Iterator
|
||||||
checkList []graph.Iterator
|
checkList []graph.Iterator
|
||||||
result graph.Value
|
result graph.Value
|
||||||
err error
|
|
||||||
runstats graph.IteratorStats
|
runstats graph.IteratorStats
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new And iterator.
|
// Creates a new And iterator.
|
||||||
|
|
@ -154,9 +154,7 @@ func (it *And) Next() bool {
|
||||||
return graph.NextLogOut(it, curr, true)
|
return graph.NextLogOut(it, curr, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := it.primaryIt.Err(); err != nil {
|
it.err = it.primaryIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return graph.NextLogOut(it, nil, false)
|
return graph.NextLogOut(it, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,14 +188,26 @@ func (it *And) checkContainsList(val graph.Value, lastResult graph.Value) bool {
|
||||||
for i, c := range it.checkList {
|
for i, c := range it.checkList {
|
||||||
ok = c.Contains(val)
|
ok = c.Contains(val)
|
||||||
if !ok {
|
if !ok {
|
||||||
if err := c.Err(); err != nil {
|
it.err = c.Err()
|
||||||
it.err = err
|
if it.err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if lastResult != nil {
|
if lastResult != nil {
|
||||||
for j := 0; j < i; j++ {
|
for j := 0; j < i; j++ {
|
||||||
// TODO(andrew-d): Should this result actually be used?
|
// One of the iterators has determined that this value doesn't
|
||||||
|
// match. However, the iterators that came before in the list
|
||||||
|
// may have returned "ok" to Contains(). We need to set all
|
||||||
|
// the tags back to what the previous result was -- effectively
|
||||||
|
// seeking back exactly one -- so we check all the prior iterators
|
||||||
|
// with the (already verified) result and throw away the result,
|
||||||
|
// which will be 'true'
|
||||||
it.checkList[j].Contains(lastResult)
|
it.checkList[j].Contains(lastResult)
|
||||||
|
|
||||||
|
it.err = it.checkList[j].Err()
|
||||||
|
if it.err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
@ -254,16 +264,17 @@ func (it *And) NextPath() bool {
|
||||||
if it.primaryIt.NextPath() {
|
if it.primaryIt.NextPath() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if err := it.primaryIt.Err(); err != nil {
|
it.err = it.primaryIt.Err()
|
||||||
it.err = err
|
if it.err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, sub := range it.internalIterators {
|
for _, sub := range it.internalIterators {
|
||||||
if sub.NextPath() {
|
if sub.NextPath() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if err := sub.Err(); err != nil {
|
|
||||||
it.err = err
|
it.err = sub.Err()
|
||||||
|
if it.err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,23 +286,20 @@ func (it *And) cleanUp() {}
|
||||||
|
|
||||||
// Close this iterator, and, by extension, close the subiterators.
|
// Close this iterator, and, by extension, close the subiterators.
|
||||||
// Close should be idempotent, and it follows that if it's subiterators
|
// Close should be idempotent, and it follows that if it's subiterators
|
||||||
// follow this contract, the And follows the contract.
|
// follow this contract, the And follows the contract. It closes all
|
||||||
//
|
// subiterators it can, but returns the first error it encounters.
|
||||||
// Note: as this potentially involves closing multiple subiterators, only
|
|
||||||
// the first error encountered while closing will be reported (if any).
|
|
||||||
func (it *And) Close() error {
|
func (it *And) Close() error {
|
||||||
it.cleanUp()
|
it.cleanUp()
|
||||||
|
|
||||||
var ret error
|
err := it.primaryIt.Close()
|
||||||
|
|
||||||
ret = it.primaryIt.Close()
|
|
||||||
for _, sub := range it.internalIterators {
|
for _, sub := range it.internalIterators {
|
||||||
if err := sub.Close(); err != nil && ret != nil {
|
serr := sub.Close()
|
||||||
ret = err
|
if serr != nil && err == nil {
|
||||||
|
err = serr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register this as an "and" iterator.
|
// Register this as an "and" iterator.
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,8 @@ func TestAllIterators(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAndIteratorErr(t *testing.T) {
|
func TestAndIteratorErr(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
allErr := newTestIterator(false, retErr)
|
allErr := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
and := NewAnd()
|
and := NewAnd()
|
||||||
and.AddSubIterator(allErr)
|
and.AddSubIterator(allErr)
|
||||||
|
|
@ -152,7 +152,7 @@ func TestAndIteratorErr(t *testing.T) {
|
||||||
if and.Next() != false {
|
if and.Next() != false {
|
||||||
t.Errorf("And iterator did not pass through initial 'false'")
|
t.Errorf("And iterator did not pass through initial 'false'")
|
||||||
}
|
}
|
||||||
if and.Err() != retErr {
|
if and.Err() != wantErr {
|
||||||
t.Errorf("And iterator did not pass through underlying Err")
|
t.Errorf("And iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,6 @@ func (it *Fixed) Next() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Fixed) Err() error {
|
func (it *Fixed) Err() error {
|
||||||
// This iterator should never error.
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ type HasA struct {
|
||||||
dir quad.Direction
|
dir quad.Direction
|
||||||
resultIt graph.Iterator
|
resultIt graph.Iterator
|
||||||
result graph.Value
|
result graph.Value
|
||||||
err error
|
|
||||||
runstats graph.IteratorStats
|
runstats graph.IteratorStats
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a new HasA iterator, given the quad subiterator, and the quad
|
// Construct a new HasA iterator, given the quad subiterator, and the quad
|
||||||
|
|
@ -153,11 +153,11 @@ func (it *HasA) Contains(val graph.Value) bool {
|
||||||
it.resultIt.Close()
|
it.resultIt.Close()
|
||||||
}
|
}
|
||||||
it.resultIt = it.qs.QuadIterator(it.dir, val)
|
it.resultIt = it.qs.QuadIterator(it.dir, val)
|
||||||
ret := it.NextContains()
|
ok := it.NextContains()
|
||||||
if it.err != nil {
|
if it.err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return graph.ContainsLogOut(it, val, ret)
|
return graph.ContainsLogOut(it, val, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextContains() is shared code between Contains() and GetNextResult() -- calls next on the
|
// NextContains() is shared code between Contains() and GetNextResult() -- calls next on the
|
||||||
|
|
@ -175,9 +175,7 @@ func (it *HasA) NextContains() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := it.resultIt.Err(); err != nil {
|
it.err = it.resultIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,8 +191,8 @@ func (it *HasA) NextPath() bool {
|
||||||
if it.primaryIt.NextPath() {
|
if it.primaryIt.NextPath() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if err := it.primaryIt.Err(); err != nil {
|
it.err = it.primaryIt.Err()
|
||||||
it.err = err
|
if it.err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,9 +216,7 @@ func (it *HasA) Next() bool {
|
||||||
it.resultIt = &Null{}
|
it.resultIt = &Null{}
|
||||||
|
|
||||||
if !graph.Next(it.primaryIt) {
|
if !graph.Next(it.primaryIt) {
|
||||||
if err := it.primaryIt.Err(); err != nil {
|
it.err = it.primaryIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return graph.NextLogOut(it, 0, false)
|
return graph.NextLogOut(it, 0, false)
|
||||||
}
|
}
|
||||||
tID := it.primaryIt.Result()
|
tID := it.primaryIt.Result()
|
||||||
|
|
@ -261,21 +257,19 @@ func (it *HasA) Stats() graph.IteratorStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the subiterator, the result iterator (if any) and the HasA.
|
// Close the subiterator, the result iterator (if any) and the HasA. It closes
|
||||||
//
|
// all subiterators it can, but returns the first error it encounters.
|
||||||
// Note: as this involves closing multiple iterators, only the first error
|
|
||||||
// encountered while closing will be reported (if any).
|
|
||||||
func (it *HasA) Close() error {
|
func (it *HasA) Close() error {
|
||||||
var ret error
|
err := it.primaryIt.Close()
|
||||||
|
|
||||||
if it.resultIt != nil {
|
if it.resultIt != nil {
|
||||||
ret = it.resultIt.Close()
|
err2 := it.resultIt.Close()
|
||||||
}
|
if err == nil {
|
||||||
if err := it.primaryIt.Close(); err != nil && ret != nil {
|
err = err2
|
||||||
ret = err
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register this iterator as a HasA.
|
// Register this iterator as a HasA.
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHasAIteratorErr(t *testing.T) {
|
func TestHasAIteratorErr(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
errIt := newTestIterator(false, retErr)
|
errIt := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
// TODO(andrew-d): pass a non-nil quadstore
|
// TODO(andrew-d): pass a non-nil quadstore
|
||||||
hasa := NewHasA(nil, errIt, quad.Subject)
|
hasa := NewHasA(nil, errIt, quad.Subject)
|
||||||
|
|
@ -31,7 +31,7 @@ func TestHasAIteratorErr(t *testing.T) {
|
||||||
if hasa.Next() != false {
|
if hasa.Next() != false {
|
||||||
t.Errorf("HasA iterator did not pass through initial 'false'")
|
t.Errorf("HasA iterator did not pass through initial 'false'")
|
||||||
}
|
}
|
||||||
if hasa.Err() != retErr {
|
if hasa.Err() != wantErr {
|
||||||
t.Errorf("HasA iterator did not pass through underlying Err")
|
t.Errorf("HasA iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ type LinksTo struct {
|
||||||
dir quad.Direction
|
dir quad.Direction
|
||||||
nextIt graph.Iterator
|
nextIt graph.Iterator
|
||||||
result graph.Value
|
result graph.Value
|
||||||
err error
|
|
||||||
runstats graph.IteratorStats
|
runstats graph.IteratorStats
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a new LinksTo iterator around a direction and a subiterator of
|
// Construct a new LinksTo iterator around a direction and a subiterator of
|
||||||
|
|
@ -126,9 +126,7 @@ func (it *LinksTo) Contains(val graph.Value) bool {
|
||||||
it.result = val
|
it.result = val
|
||||||
return graph.ContainsLogOut(it, val, true)
|
return graph.ContainsLogOut(it, val, true)
|
||||||
}
|
}
|
||||||
if err := it.primaryIt.Err(); err != nil {
|
it.err = it.primaryIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return graph.ContainsLogOut(it, val, false)
|
return graph.ContainsLogOut(it, val, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,8 +167,8 @@ func (it *LinksTo) Next() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's an error in the 'next' iterator, we save it and we're done.
|
// If there's an error in the 'next' iterator, we save it and we're done.
|
||||||
if err := it.nextIt.Err(); err != nil {
|
it.err = it.nextIt.Err()
|
||||||
it.err = err
|
if it.err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,30 +195,26 @@ func (it *LinksTo) Result() graph.Value {
|
||||||
return it.result
|
return it.result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close our subiterators.
|
// Close our subiterators. It closes all subiterators it can, but
|
||||||
//
|
// returns the first error it encounters.
|
||||||
// Note: as this involves closing multiple subiterators, only the first error
|
|
||||||
// encountered while closing will be reported (if any).
|
|
||||||
func (it *LinksTo) Close() error {
|
func (it *LinksTo) Close() error {
|
||||||
var ret error
|
err := it.nextIt.Close()
|
||||||
|
|
||||||
if err := it.nextIt.Close(); err != nil && ret != nil {
|
err2 := it.primaryIt.Close()
|
||||||
ret = err
|
if err2 != nil && err == nil {
|
||||||
}
|
err = err2
|
||||||
if err := it.primaryIt.Close(); err != nil && ret != nil {
|
|
||||||
ret = err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We won't ever have a new result, but our subiterators might.
|
// We won't ever have a new result, but our subiterators might.
|
||||||
func (it *LinksTo) NextPath() bool {
|
func (it *LinksTo) NextPath() bool {
|
||||||
ret := it.primaryIt.NextPath()
|
ok := it.primaryIt.NextPath()
|
||||||
if !ret {
|
if !ok {
|
||||||
it.err = it.primaryIt.Err()
|
it.err = it.primaryIt.Err()
|
||||||
}
|
}
|
||||||
return ret
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the LinksTo.
|
// Register the LinksTo.
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ type Materialize struct {
|
||||||
subIt graph.Iterator
|
subIt graph.Iterator
|
||||||
hasRun bool
|
hasRun bool
|
||||||
aborted bool
|
aborted bool
|
||||||
err error
|
|
||||||
runstats graph.IteratorStats
|
runstats graph.IteratorStats
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMaterialize(sub graph.Iterator) *Materialize {
|
func NewMaterialize(sub graph.Iterator) *Materialize {
|
||||||
|
|
@ -206,9 +206,7 @@ func (it *Materialize) Next() bool {
|
||||||
}
|
}
|
||||||
if it.aborted {
|
if it.aborted {
|
||||||
n := graph.Next(it.subIt)
|
n := graph.Next(it.subIt)
|
||||||
if err := it.subIt.Err(); err != nil {
|
it.err = it.subIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,9 +300,8 @@ func (it *Materialize) materializeSet() {
|
||||||
it.actualSize += 1
|
it.actualSize += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := it.subIt.Err(); err != nil {
|
it.err = it.subIt.Err()
|
||||||
it.err = err
|
if it.err == nil && it.aborted {
|
||||||
} else if it.aborted {
|
|
||||||
if glog.V(2) {
|
if glog.V(2) {
|
||||||
glog.V(2).Infoln("Aborting subiterator")
|
glog.V(2).Infoln("Aborting subiterator")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,11 @@ package iterator
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
//"github.com/google/cayley/graph"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMaterializeIteratorError(t *testing.T) {
|
func TestMaterializeIteratorError(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
errIt := newTestIterator(false, retErr)
|
errIt := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
// This tests that we properly return 0 results and the error when the
|
// This tests that we properly return 0 results and the error when the
|
||||||
// underlying iterator returns an error.
|
// underlying iterator returns an error.
|
||||||
|
|
@ -32,14 +30,14 @@ func TestMaterializeIteratorError(t *testing.T) {
|
||||||
if mIt.Next() != false {
|
if mIt.Next() != false {
|
||||||
t.Errorf("Materialize iterator did not pass through underlying 'false'")
|
t.Errorf("Materialize iterator did not pass through underlying 'false'")
|
||||||
}
|
}
|
||||||
if mIt.Err() != retErr {
|
if mIt.Err() != wantErr {
|
||||||
t.Errorf("Materialize iterator did not pass through underlying Err")
|
t.Errorf("Materialize iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaterializeIteratorErrorAbort(t *testing.T) {
|
func TestMaterializeIteratorErrorAbort(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
errIt := newTestIterator(false, retErr)
|
errIt := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
// This tests that we properly return 0 results and the error when the
|
// This tests that we properly return 0 results and the error when the
|
||||||
// underlying iterator is larger than our 'abort at' value, and then
|
// underlying iterator is larger than our 'abort at' value, and then
|
||||||
|
|
@ -50,7 +48,7 @@ func TestMaterializeIteratorErrorAbort(t *testing.T) {
|
||||||
|
|
||||||
mIt := NewMaterialize(or)
|
mIt := NewMaterialize(or)
|
||||||
|
|
||||||
// Should get all the underlying values...
|
// We should get all the underlying values...
|
||||||
for i := 0; i < abortMaterializeAt+1; i++ {
|
for i := 0; i < abortMaterializeAt+1; i++ {
|
||||||
if !mIt.Next() {
|
if !mIt.Next() {
|
||||||
t.Errorf("Materialize iterator returned spurious 'false' on iteration %d", i)
|
t.Errorf("Materialize iterator returned spurious 'false' on iteration %d", i)
|
||||||
|
|
@ -62,11 +60,11 @@ func TestMaterializeIteratorErrorAbort(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and then the error value
|
// ... and then the error value.
|
||||||
if mIt.Next() != false {
|
if mIt.Next() != false {
|
||||||
t.Errorf("Materialize iterator did not pass through underlying 'false'")
|
t.Errorf("Materialize iterator did not pass through underlying 'false'")
|
||||||
}
|
}
|
||||||
if mIt.Err() != retErr {
|
if mIt.Err() != wantErr {
|
||||||
t.Errorf("Materialize iterator did not pass through underlying Err")
|
t.Errorf("Materialize iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ type Not struct {
|
||||||
primaryIt graph.Iterator
|
primaryIt graph.Iterator
|
||||||
allIt graph.Iterator
|
allIt graph.Iterator
|
||||||
result graph.Value
|
result graph.Value
|
||||||
err error
|
|
||||||
runstats graph.IteratorStats
|
runstats graph.IteratorStats
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNot(primaryIt, allIt graph.Iterator) *Not {
|
func NewNot(primaryIt, allIt graph.Iterator) *Not {
|
||||||
|
|
@ -88,9 +88,7 @@ func (it *Not) Next() bool {
|
||||||
return graph.NextLogOut(it, curr, true)
|
return graph.NextLogOut(it, curr, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := it.allIt.Err(); err != nil {
|
it.err = it.allIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return graph.NextLogOut(it, nil, false)
|
return graph.NextLogOut(it, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,9 +111,8 @@ func (it *Not) Contains(val graph.Value) bool {
|
||||||
return graph.ContainsLogOut(it, val, false)
|
return graph.ContainsLogOut(it, val, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := it.primaryIt.Err(); err != nil {
|
it.err = it.primaryIt.Err()
|
||||||
it.err = err
|
if it.err != nil {
|
||||||
|
|
||||||
// Explicitly return 'false', since an error occurred.
|
// Explicitly return 'false', since an error occurred.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -130,19 +127,17 @@ func (it *Not) NextPath() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the primary and all iterators. If an error occurs, only the
|
// Close closes the primary and all iterators. It closes all subiterators
|
||||||
// first one will be returned.
|
// it can, but returns the first error it encounters.
|
||||||
func (it *Not) Close() error {
|
func (it *Not) Close() error {
|
||||||
var ret error
|
err := it.primaryIt.Close()
|
||||||
|
|
||||||
if err := it.primaryIt.Close(); err != nil && ret != nil {
|
err2 := it.allIt.Close()
|
||||||
ret = err
|
if err2 != nil && err == nil {
|
||||||
}
|
err = err2
|
||||||
if err := it.allIt.Close(); err != nil && ret != nil {
|
|
||||||
ret = err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Not) Type() graph.Type { return graph.Not }
|
func (it *Not) Type() graph.Type { return graph.Not }
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ func TestNotIteratorBasics(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotIteratorErr(t *testing.T) {
|
func TestNotIteratorErr(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
allIt := newTestIterator(false, retErr)
|
allIt := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
toComplementIt := NewFixed(Identity)
|
toComplementIt := NewFixed(Identity)
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ func TestNotIteratorErr(t *testing.T) {
|
||||||
if not.Next() != false {
|
if not.Next() != false {
|
||||||
t.Errorf("Not iterator did not pass through initial 'false'")
|
t.Errorf("Not iterator did not pass through initial 'false'")
|
||||||
}
|
}
|
||||||
if not.Err() != retErr {
|
if not.Err() != wantErr {
|
||||||
t.Errorf("Not iterator did not pass through underlying Err")
|
t.Errorf("Not iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,11 +90,11 @@ func (it *Optional) Result() graph.Value {
|
||||||
// optional subbranch.
|
// optional subbranch.
|
||||||
func (it *Optional) NextPath() bool {
|
func (it *Optional) NextPath() bool {
|
||||||
if it.lastCheck {
|
if it.lastCheck {
|
||||||
ret := it.subIt.NextPath()
|
ok := it.subIt.NextPath()
|
||||||
if !ret {
|
if !ok {
|
||||||
it.err = it.subIt.Err()
|
it.err = it.subIt.Err()
|
||||||
}
|
}
|
||||||
return ret
|
return ok
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,8 +148,8 @@ func (it *Or) Next() bool {
|
||||||
return graph.NextLogOut(it, it.result, true)
|
return graph.NextLogOut(it, it.result, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := curIt.Err(); err != nil {
|
it.err = curIt.Err()
|
||||||
it.err = err
|
if it.err != nil {
|
||||||
return graph.NextLogOut(it, nil, false)
|
return graph.NextLogOut(it, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +182,9 @@ func (it *Or) subItsContain(val graph.Value) (bool, error) {
|
||||||
it.currentIterator = i
|
it.currentIterator = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if err := sub.Err(); err != nil {
|
|
||||||
|
err := sub.Err()
|
||||||
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -238,11 +240,11 @@ func (it *Or) Size() (int64, bool) {
|
||||||
func (it *Or) NextPath() bool {
|
func (it *Or) NextPath() bool {
|
||||||
if it.currentIterator != -1 {
|
if it.currentIterator != -1 {
|
||||||
currIt := it.internalIterators[it.currentIterator]
|
currIt := it.internalIterators[it.currentIterator]
|
||||||
ret := currIt.NextPath()
|
ok := currIt.NextPath()
|
||||||
if !ret {
|
if !ok {
|
||||||
it.err = currIt.Err()
|
it.err = currIt.Err()
|
||||||
}
|
}
|
||||||
return ret
|
return ok
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -252,16 +254,15 @@ func (it *Or) cleanUp() {}
|
||||||
|
|
||||||
// Close this graph.iterator, and, by extension, close the subiterators.
|
// Close this graph.iterator, and, by extension, close the subiterators.
|
||||||
// Close should be idempotent, and it follows that if it's subiterators
|
// Close should be idempotent, and it follows that if it's subiterators
|
||||||
// follow this contract, the Or follows the contract.
|
// follow this contract, the Or follows the contract. It closes all
|
||||||
//
|
// subiterators it can, but returns the first error it encounters.
|
||||||
// Note: as this potentially involves closing multiple subiterators, only
|
|
||||||
// the first error encountered while closing will be reported (if any).
|
|
||||||
func (it *Or) Close() error {
|
func (it *Or) Close() error {
|
||||||
it.cleanUp()
|
it.cleanUp()
|
||||||
|
|
||||||
var ret error
|
var ret error
|
||||||
for _, sub := range it.internalIterators {
|
for _, sub := range it.internalIterators {
|
||||||
if err := sub.Close(); err != nil && ret != nil {
|
err := sub.Close()
|
||||||
|
if err != nil && ret == nil {
|
||||||
ret = err
|
ret = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ func TestShortCircuitingOrBasics(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrIteratorErr(t *testing.T) {
|
func TestOrIteratorErr(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
orErr := newTestIterator(false, retErr)
|
orErr := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
fix1 := NewFixed(Identity)
|
fix1 := NewFixed(Identity)
|
||||||
fix1.Add(1)
|
fix1.Add(1)
|
||||||
|
|
@ -172,14 +172,14 @@ func TestOrIteratorErr(t *testing.T) {
|
||||||
if or.Next() != false {
|
if or.Next() != false {
|
||||||
t.Errorf("Or iterator did not pass through underlying 'false'")
|
t.Errorf("Or iterator did not pass through underlying 'false'")
|
||||||
}
|
}
|
||||||
if or.Err() != retErr {
|
if or.Err() != wantErr {
|
||||||
t.Errorf("Or iterator did not pass through underlying Err")
|
t.Errorf("Or iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShortCircuitOrIteratorErr(t *testing.T) {
|
func TestShortCircuitOrIteratorErr(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
orErr := newTestIterator(false, retErr)
|
orErr := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
or := NewOr()
|
or := NewOr()
|
||||||
or.AddSubIterator(orErr)
|
or.AddSubIterator(orErr)
|
||||||
|
|
@ -188,7 +188,7 @@ func TestShortCircuitOrIteratorErr(t *testing.T) {
|
||||||
if or.Next() != false {
|
if or.Next() != false {
|
||||||
t.Errorf("Or iterator did not pass through underlying 'false'")
|
t.Errorf("Or iterator did not pass through underlying 'false'")
|
||||||
}
|
}
|
||||||
if or.Err() != retErr {
|
if or.Err() != wantErr {
|
||||||
t.Errorf("Or iterator did not pass through underlying Err")
|
t.Errorf("Or iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,9 +132,7 @@ func (it *Comparison) Next() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := it.subIt.Err(); err != nil {
|
it.err = it.subIt.Err()
|
||||||
it.err = err
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,11 +173,11 @@ func (it *Comparison) Contains(val graph.Value) bool {
|
||||||
if !it.doComparison(val) {
|
if !it.doComparison(val) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
ret := it.subIt.Contains(val)
|
ok := it.subIt.Contains(val)
|
||||||
if !ret {
|
if !ok {
|
||||||
it.err = it.subIt.Err()
|
it.err = it.subIt.Err()
|
||||||
}
|
}
|
||||||
return ret
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we failed the check, then the subiterator should not contribute to the result
|
// If we failed the check, then the subiterator should not contribute to the result
|
||||||
|
|
|
||||||
|
|
@ -121,15 +121,15 @@ func TestVCIContains(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestComparisonIteratorErr(t *testing.T) {
|
func TestComparisonIteratorErr(t *testing.T) {
|
||||||
retErr := errors.New("unique")
|
wantErr := errors.New("unique")
|
||||||
errIt := newTestIterator(false, retErr)
|
errIt := newTestIterator(false, wantErr)
|
||||||
|
|
||||||
vc := NewComparison(errIt, compareLT, int64(2), simpleStore)
|
vc := NewComparison(errIt, compareLT, int64(2), simpleStore)
|
||||||
|
|
||||||
if vc.Next() != false {
|
if vc.Next() != false {
|
||||||
t.Errorf("Comparison iterator did not pass through initial 'false'")
|
t.Errorf("Comparison iterator did not pass through initial 'false'")
|
||||||
}
|
}
|
||||||
if vc.Err() != retErr {
|
if vc.Err() != wantErr {
|
||||||
t.Errorf("Comparison iterator did not pass through underlying Err")
|
t.Errorf("Comparison iterator did not pass through underlying Err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ func (p *PrimaryKey) Int() int64 {
|
||||||
case sequential:
|
case sequential:
|
||||||
return p.sequentialID
|
return p.sequentialID
|
||||||
case unique:
|
case unique:
|
||||||
msg := "UUID cannot be cast to an int64"
|
msg := "UUID cannot be converted to an int64"
|
||||||
glog.Errorln(msg)
|
glog.Errorln(msg)
|
||||||
panic(msg)
|
panic(msg)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,11 @@ type Single struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSingleReplication(qs graph.QuadStore, opts graph.Options) (graph.QuadWriter, error) {
|
func NewSingleReplication(qs graph.QuadStore, opts graph.Options) (graph.QuadWriter, error) {
|
||||||
var ignoreMissing, ignoreDuplicate bool
|
var (
|
||||||
var err error
|
ignoreMissing bool
|
||||||
|
ignoreDuplicate bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
if *graph.IgnoreMissing {
|
if *graph.IgnoreMissing {
|
||||||
ignoreMissing = true
|
ignoreMissing = true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue