From 355c8ee6bcb296ff0ec6a2dac68ac73ddfeb7b6a Mon Sep 17 00:00:00 2001 From: Barak Michener Date: Sun, 19 Apr 2015 20:07:14 -0400 Subject: [PATCH] generalize Linkage, add relevant comments --- graph/iterator.go | 9 ++++++++- graph/iterator/and_iterator.go | 3 ++- graph/iterator/and_iterator_optimize.go | 10 ++++++---- graph/mongo/indexed_linksto.go | 27 ++++++++++++++++----------- graph/mongo/quadstore_iterator_optimize.go | 2 +- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/graph/iterator.go b/graph/iterator.go index 65bbcc8..17bcec0 100644 --- a/graph/iterator.go +++ b/graph/iterator.go @@ -30,7 +30,14 @@ type Tagger struct { fixedTags map[string]Value } -type LinkageSet struct { +// TODO(barakmich): Linkage is general enough that there are places we take +//the combined arguments `quad.Direction, graph.Value` that it may be worth +//converting these into Linkages. If nothing else, future indexed iterators may +//benefit from the shared representation + +// Linkage is a union type representing a set of values established for a given +// quad direction. +type Linkage struct { Dir quad.Direction Values []Value } diff --git a/graph/iterator/and_iterator.go b/graph/iterator/and_iterator.go index 4e57672..f315878 100644 --- a/graph/iterator/and_iterator.go +++ b/graph/iterator/and_iterator.go @@ -34,7 +34,8 @@ type And struct { qs graph.QuadStore } -// Creates a new And iterator. +// NewAnd creates an And iterator. `qs` is only required when needing a handle +// for QuadStore-specific optimizations, otherwise nil is acceptable. func NewAnd(qs graph.QuadStore) *And { return &And{ uid: NextUID(), diff --git a/graph/iterator/and_iterator_optimize.go b/graph/iterator/and_iterator_optimize.go index 062df52..05dc85d 100644 --- a/graph/iterator/and_iterator_optimize.go +++ b/graph/iterator/and_iterator_optimize.go @@ -99,10 +99,12 @@ func (it *And) Optimize() (graph.Iterator, bool) { // Ask the graph.QuadStore if we can be replaced. Often times, this is a great // optimization opportunity (there's a fixed iterator underneath us, for // example). - newReplacement, hasOne := it.qs.OptimizeIterator(newAnd) - if hasOne { - newAnd.Close() - return newReplacement, true + if it.qs != nil { + newReplacement, hasOne := it.qs.OptimizeIterator(newAnd) + if hasOne { + newAnd.Close() + return newReplacement, true + } } return newAnd, true diff --git a/graph/mongo/indexed_linksto.go b/graph/mongo/indexed_linksto.go index 7406143..3830390 100644 --- a/graph/mongo/indexed_linksto.go +++ b/graph/mongo/indexed_linksto.go @@ -23,6 +23,19 @@ import ( "github.com/google/cayley/quad" ) +var _ graph.Nexter = &LinksTo{} + +var linksToType graph.Type + +func init() { + linksToType = graph.RegisterIterator("mongo-linksto") +} + +// LinksTo is a MongoDB-dependent version of a LinksTo iterator. Like the normal +// LinksTo, it represents a set of links to a set of nodes, represented by its +// subiterator. However, this iterator may often be faster than the generic +// LinksTo, as it can use the secondary indices in Mongo as features within the +// Mongo query, reducing the size of the result set and speeding up iteration. type LinksTo struct { uid uint64 collection string @@ -33,13 +46,13 @@ type LinksTo struct { nextIt *mgo.Iter result graph.Value runstats graph.IteratorStats + lset []graph.Linkage err error - lset []graph.LinkageSet } // NewLinksTo constructs a new indexed LinksTo iterator for Mongo around a direction // and a subiterator of nodes. -func NewLinksTo(qs *QuadStore, it graph.Iterator, collection string, d quad.Direction, lset []graph.LinkageSet) *LinksTo { +func NewLinksTo(qs *QuadStore, it graph.Iterator, collection string, d quad.Direction, lset []graph.Linkage) *LinksTo { return &LinksTo{ uid: iterator.NextUID(), qs: qs, @@ -181,18 +194,10 @@ func (it *LinksTo) NextPath() bool { return ok } -var mongoIndexedLinksToType graph.Type - -func init() { - mongoIndexedLinksToType = graph.RegisterIterator("mongo-indexed-linksto") -} - func (it *LinksTo) Type() graph.Type { - return mongoIndexedLinksToType + return linksToType } -var _ graph.Nexter = &LinksTo{} - func (it *LinksTo) Clone() graph.Iterator { m := NewLinksTo(it.qs, it.primaryIt.Clone(), it.collection, it.dir, it.lset) m.tags.CopyFrom(it) diff --git a/graph/mongo/quadstore_iterator_optimize.go b/graph/mongo/quadstore_iterator_optimize.go index 57d257a..6cbc270 100644 --- a/graph/mongo/quadstore_iterator_optimize.go +++ b/graph/mongo/quadstore_iterator_optimize.go @@ -65,7 +65,7 @@ func (qs *QuadStore) optimizeAndIterator(it *iterator.And) (graph.Iterator, bool } mongostats := firstmongo.Stats() - lset := []graph.LinkageSet{ + lset := []graph.Linkage{ { Dir: firstmongo.dir, Values: []graph.Value{qs.ValueOf(firstmongo.name)},