diff --git a/graph/bolt/all_iterator.go b/graph/bolt/all_iterator.go index b5d0632c2..d3e8f25dc 100644 --- a/graph/bolt/all_iterator.go +++ b/graph/bolt/all_iterator.go @@ -26,6 +26,8 @@ import ( "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &AllIterator{} + type AllIterator struct { nodes bool uid uint64 @@ -176,15 +178,8 @@ func (it *AllIterator) Size() (int64, bool) { return it.qs.Size(), true } -func (it *AllIterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: size, - Direction: it.dir, - } +func (it *AllIterator) String() string { + return fmt.Sprintf("BoltAll(%q)", it.bucket) } func (it *AllIterator) Type() graph.Type { return graph.All } @@ -203,5 +198,3 @@ func (it *AllIterator) Stats() graph.IteratorStats { ExactSize: exact, } } - -var _ graph.Iterator = &AllIterator{} diff --git a/graph/bolt/iterator.go b/graph/bolt/iterator.go index 8cd21540c..9c7254881 100644 --- a/graph/bolt/iterator.go +++ b/graph/bolt/iterator.go @@ -27,6 +27,8 @@ import ( "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &Iterator{} + var ( bufferSize = 50 errNotExist = errors.New("quad does not exist") @@ -269,20 +271,8 @@ func (it *Iterator) Size() (int64, bool) { return it.size, true } -func (it *Iterator) Describe() graph.Description { - nameOf := it.qs.NameOf(&Token{ - nodes: true, - bucket: it.bucket, - key: it.checkID, - }) - return graph.Description{ - UID: it.UID(), - Name: quad.StringOf(nameOf), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: it.size, - Direction: it.dir, - } +func (it *Iterator) String() string { + return fmt.Sprintf("BoltIter(%q)", it.bucket) } func (it *Iterator) Type() graph.Type { return "bolt" } @@ -301,5 +291,3 @@ func (it *Iterator) Stats() graph.IteratorStats { ExactSize: exact, } } - -var _ graph.Iterator = &Iterator{} diff --git a/graph/elastic/iterator.go b/graph/elastic/iterator.go index bc694c853..763964352 100644 --- a/graph/elastic/iterator.go +++ b/graph/elastic/iterator.go @@ -16,11 +16,12 @@ package elastic import ( "context" + "fmt" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/graph/iterator" "github.com/cayleygraph/cayley/quad" - elastic "gopkg.in/olivere/elastic.v5" + "gopkg.in/olivere/elastic.v5" ) // Iterator struct used for elastic backend @@ -232,15 +233,8 @@ func (it *Iterator) SubIterators() []graph.Iterator { return nil } -// Describe gives the graph description -func (it *Iterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Name: string(it.hash), - Type: it.Type(), - Size: size, - } +func (it *Iterator) String() string { + return fmt.Sprintf("Elastic(%v)", it.resultType) } // Close closes the iterator diff --git a/graph/gaedatastore/iterator.go b/graph/gaedatastore/iterator.go index a13394d0f..7a18d86c7 100644 --- a/graph/gaedatastore/iterator.go +++ b/graph/gaedatastore/iterator.go @@ -297,16 +297,8 @@ func (it *Iterator) Type() graph.Type { } func (it *Iterator) Sorted() bool { return false } func (it *Iterator) Optimize() (graph.Iterator, bool) { return it, false } -func (it *Iterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Name: fmt.Sprintf("%s/%s", it.name, it.hash), - Type: it.Type(), - Size: size, - Tags: it.tags.Tags(), - Direction: it.dir, - } +func (it *Iterator) String() string { + return fmt.Sprintf("GAE(%s/%s)", it.name, it.hash) } // TODO (panamafrancis) calculate costs diff --git a/graph/gaedatastore/quadstore_test.go b/graph/gaedatastore/quadstore_test.go index 54ead1c9e..ababe3d95 100644 --- a/graph/gaedatastore/quadstore_test.go +++ b/graph/gaedatastore/quadstore_test.go @@ -125,8 +125,8 @@ func TestIterators(t *testing.T) { // Test cloning an iterator var it2 graph.Iterator it2 = it.Clone() - x := it2.Describe() - y := it.Describe() + x := graph.DescribeIterator(it2) + y := graph.DescribeIterator(it) require.Equal(t, y.Name, x.Name, "Iterator Clone was not successful") } diff --git a/graph/iterate.go b/graph/iterate.go index b066b519c..130980133 100644 --- a/graph/iterate.go +++ b/graph/iterate.go @@ -70,7 +70,7 @@ func (c *IterateChain) start() { if !clog.V(2) { return } - if b, err := json.MarshalIndent(c.it.Describe(), "", " "); err != nil { + if b, err := json.MarshalIndent(DescribeIterator(c.it), "", " "); err != nil { clog.Infof("failed to format description: %v", err) } else { clog.Infof("%s", b) diff --git a/graph/iterator.go b/graph/iterator.go index ba593ce14..baf07cc9b 100644 --- a/graph/iterator.go +++ b/graph/iterator.go @@ -90,6 +90,9 @@ func (t *Tagger) CopyFromTagger(st *Tagger) { } type Iterator interface { + // String returns a short textual representation of an iterator. + String() string + Tagger() *Tagger // Fills a tag-to-result-value map. @@ -162,9 +165,6 @@ type Iterator interface { // Return a slice of the subiterators for this iterator. SubIterators() []Iterator - // Return a string representation of the iterator. - Describe() Description - // Close the iterator and do internal cleanup. Close() error @@ -172,15 +172,32 @@ type Iterator interface { UID() uint64 } +// DescribeIterator returns a description of the iterator tree. +func DescribeIterator(it Iterator) Description { + sz, _ := it.Size() + d := Description{ + UID: it.UID(), + Name: it.String(), + Type: it.Type(), + Tags: it.Tagger().Tags(), + Size: sz, + } + if sub := it.SubIterators(); len(sub) != 0 { + d.Iterators = make([]Description, 0, len(sub)) + for _, sit := range sub { + d.Iterators = append(d.Iterators, DescribeIterator(sit)) + } + } + return d +} + type Description struct { - UID uint64 `json:",omitempty"` - Name string `json:",omitempty"` - Type Type `json:",omitempty"` - Tags []string `json:",omitempty"` - Size int64 `json:",omitempty"` - Direction quad.Direction `json:",omitempty"` - Iterator *Description `json:",omitempty"` - Iterators []Description `json:",omitempty"` + UID uint64 `json:",omitempty"` + Name string `json:",omitempty"` + Type Type `json:",omitempty"` + Tags []string `json:",omitempty"` + Size int64 `json:",omitempty"` + Iterators []Description `json:",omitempty"` } // ApplyMorphism is a curried function that can generates a new iterator based on some prior iterator. diff --git a/graph/iterator/all.go b/graph/iterator/all.go index 5507d607b..65344e03b 100644 --- a/graph/iterator/all.go +++ b/graph/iterator/all.go @@ -23,9 +23,12 @@ package iterator // the base iterators, and it helps just to see it here. import ( + "fmt" "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Int64{} + // An All iterator across a range of int64 values, from `max` to `min`. type Int64 struct { node bool @@ -88,12 +91,8 @@ func (it *Int64) TagResults(dst map[string]graph.Value) { it.tags.TagResult(dst, it.Result()) } -func (it *Int64) Describe() graph.Description { - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - } +func (it *Int64) String() string { + return fmt.Sprintf("Int64(%d-%d)", it.min, it.max) } // Next() on an Int64 all iterator is a simple incrementing counter. @@ -140,8 +139,8 @@ func (it *Int64) SubIterators() []graph.Iterator { // The number of elements in an Int64 is the size of the range. // The size is exact. func (it *Int64) Size() (int64, bool) { - Size := ((it.max - it.min) + 1) - return Size, true + sz := (it.max - it.min) + 1 + return sz, true } func valToInt64(v graph.Value) int64 { @@ -184,5 +183,3 @@ func (it *Int64) Stats() graph.IteratorStats { Contains: it.runstats.Contains, } } - -var _ graph.Iterator = &Int64{} diff --git a/graph/iterator/and.go b/graph/iterator/and.go index 7530554df..0e98370a5 100644 --- a/graph/iterator/and.go +++ b/graph/iterator/and.go @@ -19,6 +19,8 @@ import ( "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &And{} + // The And iterator. Consists of a number of subiterators, the primary of which will // be Next()ed if next is called. type And struct { @@ -100,19 +102,8 @@ func (it *And) SubIterators() []graph.Iterator { return iters } -func (it *And) Describe() graph.Description { - subIts := make([]graph.Description, len(it.internalIterators)) - for i, sub := range it.internalIterators { - subIts[i] = sub.Describe() - } - primary := it.primaryIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Iterator: &primary, - Iterators: subIts, - } +func (it *And) String() string { + return "And" } // Add a subiterator to this And iterator. @@ -306,5 +297,3 @@ func (it *And) Close() error { // Register this as an "and" iterator. func (it *And) Type() graph.Type { return graph.And } - -var _ graph.Iterator = &And{} diff --git a/graph/iterator/count.go b/graph/iterator/count.go index f1a27aa20..93e14496c 100644 --- a/graph/iterator/count.go +++ b/graph/iterator/count.go @@ -5,6 +5,8 @@ import ( "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &Count{} + // Count iterator returns one element with size of underlying iterator. type Count struct { uid uint64 @@ -128,16 +130,4 @@ func (it *Count) Size() (int64, bool) { return 1, true } -func (it *Count) Describe() graph.Description { - subIts := []graph.Description{ - it.it.Describe(), - } - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.Tagger().Tags(), - Iterators: subIts, - } -} - -var _ graph.Iterator = &Count{} +func (it *Count) String() string { return "Count" } diff --git a/graph/iterator/fixed.go b/graph/iterator/fixed.go index f45c6d294..c856e8415 100644 --- a/graph/iterator/fixed.go +++ b/graph/iterator/fixed.go @@ -22,11 +22,12 @@ package iterator import ( "fmt" - "sort" "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Fixed{} + // 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 { @@ -93,23 +94,8 @@ func (it *Fixed) Add(v graph.Value) { it.values = append(it.values, v) } -func (it *Fixed) Describe() graph.Description { - var value string - if len(it.values) > 0 { - value = fmt.Sprint(it.values[0]) - } - fixed := make([]string, 0, len(it.tags.Fixed())) - for k := range it.tags.Fixed() { - fixed = append(fixed, k) - } - sort.Strings(fixed) - return graph.Description{ - UID: it.UID(), - Name: value, - Type: it.Type(), - Tags: fixed, - Size: int64(len(it.values)), - } +func (it *Fixed) String() string { + return fmt.Sprintf("Fixed(%v)", it.values) } // Register this iterator as a Fixed iterator. @@ -186,5 +172,3 @@ func (it *Fixed) Stats() graph.IteratorStats { ExactSize: exact, } } - -var _ graph.Iterator = &Fixed{} diff --git a/graph/iterator/hasa.go b/graph/iterator/hasa.go index 85d5089a5..888c98506 100644 --- a/graph/iterator/hasa.go +++ b/graph/iterator/hasa.go @@ -36,10 +36,13 @@ package iterator import ( "github.com/cayleygraph/cayley/clog" + "fmt" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &HasA{} + // A HasA consists of a reference back to the graph.QuadStore that it references, // a primary subiterator, a direction in which the quads for that subiterator point, // and a temporary holder for the iterator generated on Contains(). @@ -123,15 +126,8 @@ func (it *HasA) TagResults(dst map[string]graph.Value) { it.primaryIt.TagResults(dst) } -func (it *HasA) Describe() graph.Description { - primary := it.primaryIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Direction: it.dir, - Iterator: &primary, - } +func (it *HasA) String() string { + return fmt.Sprintf("HasA(%v)", it.dir) } // Check a value against our internal iterator. In order to do this, we must first open a new @@ -281,5 +277,3 @@ func (it *HasA) Size() (int64, bool) { st := it.Stats() return st.Size, st.ExactSize } - -var _ graph.Iterator = &HasA{} diff --git a/graph/iterator/iterator.go b/graph/iterator/iterator.go index ffe55aace..857d7ae54 100644 --- a/graph/iterator/iterator.go +++ b/graph/iterator/iterator.go @@ -19,6 +19,7 @@ package iterator import ( "sync/atomic" + "fmt" "github.com/cayleygraph/cayley/graph" ) @@ -76,11 +77,8 @@ func (it *Null) Type() graph.Type { return graph.Null } // Null has nothing it needs to do. func (it *Null) Optimize() (graph.Iterator, bool) { return it, false } -func (it *Null) Describe() graph.Description { - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - } +func (it *Null) String() string { + return "Null" } func (it *Null) Next() bool { @@ -152,11 +150,8 @@ func (it *Error) Type() graph.Type { return graph.Null } func (it *Error) Optimize() (graph.Iterator, bool) { return it, false } -func (it *Error) Describe() graph.Description { - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - } +func (it *Error) String() string { + return fmt.Sprintf("Error(%v)", it.err) } func (it *Error) Next() bool { diff --git a/graph/iterator/limit.go b/graph/iterator/limit.go index 01ac1f9a5..00d7f5f19 100644 --- a/graph/iterator/limit.go +++ b/graph/iterator/limit.go @@ -1,9 +1,12 @@ package iterator import ( + "fmt" "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Limit{} + // Limit iterator will stop iterating if certain a number of values were encountered. // Zero and negative limit values means no limit. type Limit struct { @@ -119,17 +122,6 @@ func (it *Limit) Size() (int64, bool) { return primarySize, exact } -func (it *Limit) Describe() graph.Description { - subIts := []graph.Description{ - it.primaryIt.Describe(), - } - - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.Tagger().Tags(), - Iterators: subIts, - } +func (it *Limit) String() string { + return fmt.Sprintf("Limit(%d)", it.limit) } - -var _ graph.Iterator = &Limit{} diff --git a/graph/iterator/linksto.go b/graph/iterator/linksto.go index c3ef45a61..2b82343e6 100644 --- a/graph/iterator/linksto.go +++ b/graph/iterator/linksto.go @@ -30,10 +30,13 @@ package iterator // Can be seen as the dual of the HasA iterator. import ( + "fmt" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &LinksTo{} + // A LinksTo has a reference back to the graph.QuadStore (to create the iterators // for each node) the subiterator, and the direction the iterator comes from. // `next_it` is the tempoarary iterator held per result in `primary_it`. @@ -93,14 +96,8 @@ func (it *LinksTo) TagResults(dst map[string]graph.Value) { it.primaryIt.TagResults(dst) } -func (it *LinksTo) Describe() graph.Description { - primary := it.primaryIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Direction: it.dir, - Iterator: &primary, - } +func (it *LinksTo) String() string { + return fmt.Sprintf("LinksTo(%v)", it.dir) } // If it checks in the right direction for the subiterator, it is a valid link @@ -230,5 +227,3 @@ func (it *LinksTo) Size() (int64, bool) { st := it.Stats() return st.Size, st.ExactSize } - -var _ graph.Iterator = &LinksTo{} diff --git a/graph/iterator/materialize.go b/graph/iterator/materialize.go index ebafbf7ca..38d5868cc 100644 --- a/graph/iterator/materialize.go +++ b/graph/iterator/materialize.go @@ -22,6 +22,8 @@ import ( "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Materialize{} + const MaterializeLimit = 1000 type result struct { @@ -115,15 +117,8 @@ func (it *Materialize) Clone() graph.Iterator { return out } -func (it *Materialize) Describe() graph.Description { - primary := it.subIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: int64(len(it.values)), - Iterator: &primary, - } +func (it *Materialize) String() string { + return "Materialize" } // Register this iterator as a Materialize iterator. @@ -316,5 +311,3 @@ func (it *Materialize) materializeSet() { } it.hasRun = true } - -var _ graph.Iterator = &Materialize{} diff --git a/graph/iterator/not.go b/graph/iterator/not.go index 2c4dad8dc..4c3c5410b 100644 --- a/graph/iterator/not.go +++ b/graph/iterator/not.go @@ -4,6 +4,8 @@ import ( "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Not{} + // Not iterator acts like a complement for the primary iterator. // It will return all the vertices which are not part of the primary iterator. type Not struct { @@ -157,18 +159,6 @@ func (it *Not) Size() (int64, bool) { return st.Size, st.ExactSize } -func (it *Not) Describe() graph.Description { - subIts := []graph.Description{ - it.primaryIt.Describe(), - it.allIt.Describe(), - } - - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Iterators: subIts, - } +func (it *Not) String() string { + return "Not" } - -var _ graph.Iterator = &Not{} diff --git a/graph/iterator/optional.go b/graph/iterator/optional.go index eb150782a..f867d1152 100644 --- a/graph/iterator/optional.go +++ b/graph/iterator/optional.go @@ -31,6 +31,11 @@ import ( "github.com/cayleygraph/cayley/graph" ) +var ( + _ graph.Iterator = &Optional{} + _ graph.NoNext = &Optional{} +) + // An optional iterator has the sub-constraint iterator we wish to be optional // and whether the last check we received was true or false. type Optional struct { @@ -131,14 +136,8 @@ func (it *Optional) TagResults(dst map[string]graph.Value) { // Registers the optional iterator. func (it *Optional) Type() graph.Type { return graph.Optional } -func (it *Optional) Describe() graph.Description { - primary := it.subIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Iterator: &primary, - } +func (it *Optional) String() string { + return "Optional" } // There's nothing to optimize for an optional. Optimize the subiterator and @@ -167,8 +166,3 @@ func (it *Optional) Stats() graph.IteratorStats { func (it *Optional) Size() (int64, bool) { return it.Stats().Size, false } - -var ( - _ graph.Iterator = &Optional{} - _ graph.NoNext = &Optional{} -) diff --git a/graph/iterator/or.go b/graph/iterator/or.go index f8da30265..95932dad9 100644 --- a/graph/iterator/or.go +++ b/graph/iterator/or.go @@ -25,6 +25,8 @@ import ( "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Or{} + type Or struct { uid uint64 tags graph.Tagger @@ -99,17 +101,8 @@ func (it *Or) TagResults(dst map[string]graph.Value) { it.internalIterators[it.currentIterator].TagResults(dst) } -func (it *Or) Describe() graph.Description { - subIts := make([]graph.Description, len(it.internalIterators)) - for i, sub := range it.internalIterators { - subIts[i] = sub.Describe() - } - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Iterators: subIts, - } +func (it *Or) String() string { + return "Or" } // Add a subiterator to this Or graph.iterator. Order matters. @@ -314,5 +307,3 @@ func (it *Or) Stats() graph.IteratorStats { // Register this as an "or" graph.iterator. func (it *Or) Type() graph.Type { return graph.Or } - -var _ graph.Iterator = &Or{} diff --git a/graph/iterator/recursive.go b/graph/iterator/recursive.go index 2e51ecdb9..b0396474d 100644 --- a/graph/iterator/recursive.go +++ b/graph/iterator/recursive.go @@ -264,19 +264,6 @@ func (it *Recursive) Stats() graph.IteratorStats { } } -func (it *Recursive) Describe() graph.Description { - base := it.qs.FixedIterator() - base.Add(Int64Node(20)) - fanoutdesc := it.morphism(it.qs, base).Describe() - subIts := []graph.Description{ - it.subIt.Describe(), - fanoutdesc, - } - - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Iterators: subIts, - } +func (it *Recursive) String() string { + return "Recursive" } diff --git a/graph/iterator/regex.go b/graph/iterator/regex.go index f31155c5c..28eb590ec 100644 --- a/graph/iterator/regex.go +++ b/graph/iterator/regex.go @@ -17,10 +17,13 @@ package iterator import ( "regexp" + "fmt" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &Regex{} + // Regex is a unary operator -- a filter across the values in the relevant // subiterator. It works similarly to gremlin's filter{it.matches('exp')}, // reducing the iterator set to values whose string representation passes a @@ -164,13 +167,8 @@ func (it *Regex) Type() graph.Type { return graph.Regex } -func (it *Regex) Describe() graph.Description { - primary := it.subIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Iterator: &primary, - } +func (it *Regex) String() string { + return fmt.Sprintf("Regexp(%v)", it.re.String()) } // There's nothing to optimize, locally, for a Regex iterator. @@ -200,5 +198,3 @@ func (it *Regex) TagResults(dst map[string]graph.Value) { func (it *Regex) Size() (int64, bool) { return 0, false } - -var _ graph.Iterator = &Regex{} diff --git a/graph/iterator/skip.go b/graph/iterator/skip.go index 7a64af6d7..55cbc3ad1 100644 --- a/graph/iterator/skip.go +++ b/graph/iterator/skip.go @@ -1,9 +1,12 @@ package iterator import ( + "fmt" "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Skip{} + // Skip iterator will skip certain number of values from primary iterator. type Skip struct { uid uint64 @@ -122,17 +125,6 @@ func (it *Skip) Size() (int64, bool) { return primarySize, exact } -func (it *Skip) Describe() graph.Description { - subIts := []graph.Description{ - it.primaryIt.Describe(), - } - - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.Tagger().Tags(), - Iterators: subIts, - } +func (it *Skip) String() string { + return fmt.Sprintf("Skip(%d)", it.skip) } - -var _ graph.Iterator = &Skip{} diff --git a/graph/iterator/unique.go b/graph/iterator/unique.go index ce17380e1..91552d9d6 100644 --- a/graph/iterator/unique.go +++ b/graph/iterator/unique.go @@ -4,6 +4,8 @@ import ( "github.com/cayleygraph/cayley/graph" ) +var _ graph.Iterator = &Unique{} + // Unique iterator removes duplicate values from it's subiterator. type Unique struct { uid uint64 @@ -136,17 +138,6 @@ func (it *Unique) Size() (int64, bool) { return st.Size, st.ExactSize } -func (it *Unique) Describe() graph.Description { - subIts := []graph.Description{ - it.subIt.Describe(), - } - - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Iterators: subIts, - } +func (it *Unique) String() string { + return "Unique" } - -var _ graph.Iterator = &Unique{} diff --git a/graph/iterator/value_comparison.go b/graph/iterator/value_comparison.go index e59a1b771..38c7d5413 100644 --- a/graph/iterator/value_comparison.go +++ b/graph/iterator/value_comparison.go @@ -27,6 +27,7 @@ package iterator // In MQL terms, this is the [{"age>=": 21}] concept. import ( + "fmt" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/quad" "time" @@ -42,6 +43,8 @@ const ( // Why no Equals? Because that's usually an AndIterator. ) +var _ graph.Iterator = &Comparison{} + type Comparison struct { uid uint64 tags graph.Tagger @@ -253,13 +256,8 @@ func (it *Comparison) TagResults(dst map[string]graph.Value) { // Registers the value-comparison iterator. func (it *Comparison) Type() graph.Type { return graph.Comparison } -func (it *Comparison) Describe() graph.Description { - primary := it.subIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Iterator: &primary, - } +func (it *Comparison) String() string { + return fmt.Sprintf("Comparison(%v, %v)", it.op, it.val) } // There's nothing to optimize, locally, for a value-comparison iterator. @@ -283,5 +281,3 @@ func (it *Comparison) Stats() graph.IteratorStats { func (it *Comparison) Size() (int64, bool) { return 0, false } - -var _ graph.Iterator = &Comparison{} diff --git a/graph/kv/all_iterator.go b/graph/kv/all_iterator.go index 00afb0d7a..5da884055 100644 --- a/graph/kv/all_iterator.go +++ b/graph/kv/all_iterator.go @@ -185,15 +185,8 @@ func (it *AllIterator) Size() (int64, bool) { return it.qs.Size(), false } -func (it *AllIterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: size, - Direction: quad.Any, - } +func (it *AllIterator) String() string { + return "KVAll" } func (it *AllIterator) Type() graph.Type { diff --git a/graph/kv/quad_iterator.go b/graph/kv/quad_iterator.go index 6bcf14348..f6b037954 100644 --- a/graph/kv/quad_iterator.go +++ b/graph/kv/quad_iterator.go @@ -230,16 +230,8 @@ func (it *QuadIterator) Size() (int64, bool) { return 1 + it.qs.Size()/2, false } -func (it *QuadIterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: size, - Direction: it.ind.Dirs[0], - Name: fmt.Sprint(it.vals, it.ids), - } +func (it *QuadIterator) String() string { + return fmt.Sprintf("KVQuads(%v)", it.ind) } func (it *QuadIterator) Type() graph.Type { return "kv_quad" } diff --git a/graph/leveldb/all_iterator.go b/graph/leveldb/all_iterator.go index 79f9e7edd..6dc4ba58e 100644 --- a/graph/leveldb/all_iterator.go +++ b/graph/leveldb/all_iterator.go @@ -167,15 +167,8 @@ func (it *AllIterator) Size() (int64, bool) { return int64(^uint64(0) >> 1), false } -func (it *AllIterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: size, - Direction: it.dir, - } +func (it *AllIterator) String() string { + return "LeveldbAll" } func (it *AllIterator) Type() graph.Type { return graph.All } diff --git a/graph/leveldb/iterator.go b/graph/leveldb/iterator.go index f2a4899c5..484347b06 100644 --- a/graph/leveldb/iterator.go +++ b/graph/leveldb/iterator.go @@ -26,6 +26,8 @@ import ( "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &Iterator{} + type Iterator struct { uid uint64 tags graph.Tagger @@ -239,16 +241,8 @@ func (it *Iterator) Size() (int64, bool) { return it.qs.SizeOf(Token(it.checkID)), true } -func (it *Iterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Name: quad.StringOf(it.qs.NameOf(Token(it.checkID))), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: size, - Direction: it.dir, - } +func (it *Iterator) String() string { + return "Leveldb" } func (it *Iterator) Type() graph.Type { return "leveldb" } @@ -267,5 +261,3 @@ func (it *Iterator) Stats() graph.IteratorStats { ExactSize: exact, } } - -var _ graph.Iterator = &Iterator{} diff --git a/graph/memstore/all_iterator.go b/graph/memstore/all_iterator.go index 86fa8cc7f..35fae81a9 100644 --- a/graph/memstore/all_iterator.go +++ b/graph/memstore/all_iterator.go @@ -139,12 +139,8 @@ func (it *AllIterator) UID() uint64 { return it.uid } func (it *AllIterator) Type() graph.Type { return graph.All } -func (it *AllIterator) Describe() graph.Description { - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Tags: it.tags.Tags(), - } +func (it *AllIterator) String() string { + return "MemStoreAll" } func (it *AllIterator) NextPath() bool { return false } diff --git a/graph/memstore/iterator.go b/graph/memstore/iterator.go index 601d2351f..0188f28f7 100644 --- a/graph/memstore/iterator.go +++ b/graph/memstore/iterator.go @@ -24,6 +24,8 @@ import ( "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &Iterator{} + type Iterator struct { nodes bool uid uint64 @@ -146,15 +148,8 @@ func (it *Iterator) Contains(v graph.Value) bool { return graph.ContainsLogOut(it, v, false) } -func (it *Iterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Name: fmt.Sprintf("dir:%s val:%d", it.d, it.value), - Type: it.Type(), - Tags: it.tags.Tags(), - Size: size, - } +func (it *Iterator) String() string { + return fmt.Sprintf("MemStore(%v)", it.d) } func (it *Iterator) Type() graph.Type { return "b+tree" } @@ -173,5 +168,3 @@ func (it *Iterator) Stats() graph.IteratorStats { ExactSize: true, } } - -var _ graph.Iterator = &Iterator{} diff --git a/graph/memstore/quadstore_test.go b/graph/memstore/quadstore_test.go index f210e62cf..16cb606a5 100644 --- a/graph/memstore/quadstore_test.go +++ b/graph/memstore/quadstore_test.go @@ -173,8 +173,8 @@ func TestLinksToOptimization(t *testing.T) { v := newIt.(*Iterator) vClone := v.Clone() - origDesc := v.Describe() - cloneDesc := vClone.Describe() + origDesc := graph.DescribeIterator(v) + cloneDesc := graph.DescribeIterator(vClone) origDesc.UID, cloneDesc.UID = 0, 0 // We are more strict now, so fake UID equality. if !reflect.DeepEqual(cloneDesc, origDesc) { t.Fatalf("Unexpected iterator description.\ngot: %#v\nexpect: %#v", cloneDesc, origDesc) diff --git a/graph/mongo/indexed_linksto.go b/graph/mongo/indexed_linksto.go index 75e1657d5..931b6ebc2 100644 --- a/graph/mongo/indexed_linksto.go +++ b/graph/mongo/indexed_linksto.go @@ -18,6 +18,7 @@ import ( "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" + "fmt" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/graph/iterator" "github.com/cayleygraph/cayley/quad" @@ -200,14 +201,8 @@ func (it *LinksTo) Contains(val graph.Value) bool { return graph.ContainsLogOut(it, val, false) } -func (it *LinksTo) Describe() graph.Description { - primary := it.primaryIt.Describe() - return graph.Description{ - UID: it.UID(), - Type: it.Type(), - Direction: it.dir, - Iterator: &primary, - } +func (it *LinksTo) String() string { + return fmt.Sprintf("MongoLinks(%v)", it.lset) } func (it *LinksTo) Reset() { diff --git a/graph/mongo/iterator.go b/graph/mongo/iterator.go index b658527e9..e936ba321 100644 --- a/graph/mongo/iterator.go +++ b/graph/mongo/iterator.go @@ -18,12 +18,15 @@ import ( "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" + "fmt" "github.com/cayleygraph/cayley/clog" "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/graph/iterator" "github.com/cayleygraph/cayley/quad" ) +var _ graph.Iterator = &Iterator{} + type Iterator struct { uid uint64 tags graph.Tagger @@ -209,14 +212,8 @@ func (it *Iterator) Type() graph.Type { func (it *Iterator) Sorted() bool { return true } func (it *Iterator) Optimize() (graph.Iterator, bool) { return it, false } -func (it *Iterator) Describe() graph.Description { - size, _ := it.Size() - return graph.Description{ - UID: it.UID(), - Name: string(it.hash), - Type: it.Type(), - Size: size, - } +func (it *Iterator) String() string { + return fmt.Sprintf("Mongo(%v)", it.dir) } func (it *Iterator) Stats() graph.IteratorStats { @@ -228,5 +225,3 @@ func (it *Iterator) Stats() graph.IteratorStats { ExactSize: exact, } } - -var _ graph.Iterator = &Iterator{} diff --git a/graph/sql/iterator.go b/graph/sql/iterator.go index b5d8c1e86..0145906b9 100644 --- a/graph/sql/iterator.go +++ b/graph/sql/iterator.go @@ -296,14 +296,8 @@ func (it *Iterator) SubIterators() []graph.Iterator { return nil } -func (it *Iterator) Describe() graph.Description { - return graph.Description{ - UID: it.UID(), - Name: it.query.SQL(NewBuilder(it.qs.flavor.QueryDialect)), - Type: it.Type(), - Tags: it.tagger.Tags(), - Size: it.query.Limit, - } +func (it *Iterator) String() string { + return it.query.SQL(NewBuilder(it.qs.flavor.QueryDialect)) } func (it *Iterator) Close() error { diff --git a/query/sexp/parser_test.go b/query/sexp/parser_test.go index f287b17fb..eff9b9f11 100644 --- a/query/sexp/parser_test.go +++ b/query/sexp/parser_test.go @@ -91,7 +91,7 @@ func TestTreeConstraintParse(t *testing.T) { "($a (:is :good))))" it := BuildIteratorTreeForQuery(qs, query) if it.Type() != graph.And { - t.Errorf("Odd iterator tree. Got: %#v", it.Describe()) + t.Errorf("Odd iterator tree. Got: %#v", graph.DescribeIterator(it)) } if !it.Next() { t.Error("Got no results") @@ -139,7 +139,7 @@ func TestMultipleConstraintParse(t *testing.T) { )` it := BuildIteratorTreeForQuery(qs, query) if it.Type() != graph.And { - t.Errorf("Odd iterator tree. Got: %#v", it.Describe()) + t.Errorf("Odd iterator tree. Got: %#v", graph.DescribeIterator(it)) } if !it.Next() { t.Error("Got no results")