document path context, pipe it through Reversal() as well, and update the godoc

This commit is contained in:
Barak Michener 2015-10-28 23:12:37 -04:00
parent f74051a520
commit 3d286f5245
2 changed files with 64 additions and 35 deletions

View file

@ -38,7 +38,7 @@ func join(qs graph.QuadStore, itL, itR graph.Iterator) graph.Iterator {
func isMorphism(nodes ...string) morphism {
return morphism{
Name: "is",
Reversal: func() morphism { return isMorphism(nodes...) },
Reversal: func(ctx *context) (morphism, *context) { return isMorphism(nodes...), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
if len(nodes) == 0 {
// Acting as a passthrough here is equivalent to
@ -64,7 +64,7 @@ func isMorphism(nodes ...string) morphism {
func hasMorphism(via interface{}, nodes ...string) morphism {
return morphism{
Name: "has",
Reversal: func() morphism { return hasMorphism(via, nodes...) },
Reversal: func(ctx *context) (morphism, *context) { return hasMorphism(via, nodes...), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
viaIter := buildViaPath(qs, via).
BuildIterator()
@ -104,7 +104,7 @@ func hasMorphism(via interface{}, nodes ...string) morphism {
func tagMorphism(tags ...string) morphism {
return morphism{
Name: "tag",
Reversal: func() morphism { return tagMorphism(tags...) },
Reversal: func(ctx *context) (morphism, *context) { return tagMorphism(tags...), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
for _, t := range tags {
in.Tagger().Add(t)
@ -119,7 +119,7 @@ func tagMorphism(tags ...string) morphism {
func outMorphism(tags []string, via ...interface{}) morphism {
return morphism{
Name: "out",
Reversal: func() morphism { return inMorphism(tags, via...) },
Reversal: func(ctx *context) (morphism, *context) { return inMorphism(tags, via...), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
path := buildViaPath(qs, via...)
return inOutIterator(path, in, false, tags), ctx
@ -131,7 +131,7 @@ func outMorphism(tags []string, via ...interface{}) morphism {
func inMorphism(tags []string, via ...interface{}) morphism {
return morphism{
Name: "in",
Reversal: func() morphism { return outMorphism(tags, via...) },
Reversal: func(ctx *context) (morphism, *context) { return outMorphism(tags, via...), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
path := buildViaPath(qs, via...)
return inOutIterator(path, in, true, tags), ctx
@ -142,7 +142,7 @@ func inMorphism(tags []string, via ...interface{}) morphism {
func bothMorphism(tags []string, via ...interface{}) morphism {
return morphism{
Name: "in",
Reversal: func() morphism { return bothMorphism(tags, via...) },
Reversal: func(ctx *context) (morphism, *context) { return bothMorphism(tags, via...), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
path := buildViaPath(qs, via...)
inSide := inOutIterator(path, in, true, tags)
@ -160,7 +160,9 @@ func bothMorphism(tags []string, via ...interface{}) morphism {
func predicatesMorphism(isIn bool) morphism {
m := morphism{
Name: "out_predicates",
Reversal: func() morphism { panic("not implemented: need a function from predicates to their associated edges") },
Reversal: func(ctx *context) (morphism, *context) {
panic("not implemented: need a function from predicates to their associated edges")
},
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
dir := quad.Subject
if isIn {
@ -181,7 +183,7 @@ func predicatesMorphism(isIn bool) morphism {
func iteratorMorphism(it graph.Iterator) morphism {
return morphism{
Name: "iterator",
Reversal: func() morphism { return iteratorMorphism(it) },
Reversal: func(ctx *context) (morphism, *context) { return iteratorMorphism(it), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
return join(qs, it, in), ctx
},
@ -192,7 +194,7 @@ func iteratorMorphism(it graph.Iterator) morphism {
func andMorphism(p *Path) morphism {
return morphism{
Name: "and",
Reversal: func() morphism { return andMorphism(p) },
Reversal: func(ctx *context) (morphism, *context) { return andMorphism(p), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
itR := p.BuildIteratorOn(qs)
@ -205,7 +207,7 @@ func andMorphism(p *Path) morphism {
func orMorphism(p *Path) morphism {
return morphism{
Name: "or",
Reversal: func() morphism { return orMorphism(p) },
Reversal: func(ctx *context) (morphism, *context) { return orMorphism(p), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
itR := p.BuildIteratorOn(qs)
@ -220,7 +222,7 @@ func orMorphism(p *Path) morphism {
func followMorphism(p *Path) morphism {
return morphism{
Name: "follow",
Reversal: func() morphism { return followMorphism(p.Reverse()) },
Reversal: func(ctx *context) (morphism, *context) { return followMorphism(p.Reverse()), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
return p.Morphism()(qs, in), ctx
},
@ -231,7 +233,7 @@ func followMorphism(p *Path) morphism {
func exceptMorphism(p *Path) morphism {
return morphism{
Name: "except",
Reversal: func() morphism { return exceptMorphism(p) },
Reversal: func(ctx *context) (morphism, *context) { return exceptMorphism(p), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
subIt := p.BuildIteratorOn(qs)
allNodes := qs.NodesAllIterator()
@ -245,7 +247,7 @@ func exceptMorphism(p *Path) morphism {
func saveMorphism(via interface{}, tag string) morphism {
return morphism{
Name: "save",
Reversal: func() morphism { return saveMorphism(via, tag) },
Reversal: func(ctx *context) (morphism, *context) { return saveMorphism(via, tag), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
return buildSave(qs, via, tag, in, false), ctx
},
@ -256,7 +258,7 @@ func saveMorphism(via interface{}, tag string) morphism {
func saveReverseMorphism(via interface{}, tag string) morphism {
return morphism{
Name: "saver",
Reversal: func() morphism { return saveReverseMorphism(via, tag) },
Reversal: func(ctx *context) (morphism, *context) { return saveReverseMorphism(via, tag), ctx },
Apply: func(qs graph.QuadStore, in graph.Iterator, ctx *context) (graph.Iterator, *context) {
return buildSave(qs, via, tag, in, true), ctx
},

View file

@ -20,13 +20,35 @@ type applyMorphism func(graph.QuadStore, graph.Iterator, *context) (graph.Iterat
type morphism struct {
Name string
Reversal func() morphism
Reversal func(*context) (morphism, *context)
Apply applyMorphism
tags []string
context context
}
// context allows a high-level change to the way paths are constructed. Some
// functions may change the context, causing following chained calls to act
// cdifferently.
//
// In a sense, this is a global state which can be changed as the path
// continues. And as with dealing with any global state, care should be taken:
//
// When modifying the context in Apply(), please copy the passed struct,
// modifying the relevant fields if need be (or pass the given context onward).
//
// Under Reversal(), any functions that wish to change the context should
// appropriately change the passed context (that is, the context that came after
// them will now be what the application of the function would have been) and
// then yield a pointer to their own member context as the return value.
//
// For more examples, look at the morphisms which claim the individual fields.
type context struct {
labelSet Path
// Represents the path to the limiting set of labels that should be considered under traversal.
// inMorphism, outMorphism, et al should constrain edges by this set.
// A nil in this field represents all labels.
//
// Claimed by the withLabel morphism
labelSet *Path
}
// Path represents either a morphism (a pre-defined path stored for later use),
@ -34,7 +56,7 @@ type context struct {
type Path struct {
stack []morphism
qs graph.QuadStore // Optionally. A nil qs is equivalent to a morphism.
baseContext *context
baseContext context
}
// IsMorphism returns whether this Path is a morphism.
@ -74,8 +96,11 @@ func NewPath(qs graph.QuadStore) *Path {
// Reverse returns a new Path that is the reverse of the current one.
func (p *Path) Reverse() *Path {
newPath := NewPath(p.qs)
ctx := &newPath.baseContext
for i := len(p.stack) - 1; i >= 0; i-- {
newPath.stack = append(newPath.stack, p.stack[i].Reversal())
var revMorphism morphism
revMorphism, ctx = p.stack[i].Reversal(ctx)
newPath.stack = append(newPath.stack, revMorphism)
}
return newPath
}
@ -249,7 +274,7 @@ func (p *Path) Has(via interface{}, nodes ...string) *Path {
func (p *Path) Back(tag string) *Path {
newPath := NewPath(p.qs)
i := len(p.stack) - 1
ctx := &newPath.baseContext
for {
if i < 0 {
return p.Reverse()
@ -263,7 +288,9 @@ func (p *Path) Back(tag string) *Path {
}
}
}
newPath.stack = append(newPath.stack, p.stack[i].Reversal())
var revMorphism morphism
revMorphism, ctx = p.stack[i].Reversal(ctx)
newPath.stack = append(newPath.stack, revMorphism)
i--
}
}
@ -291,7 +318,7 @@ func (p *Path) BuildIteratorOn(qs graph.QuadStore) graph.Iterator {
func (p *Path) Morphism() graph.ApplyMorphism {
return func(qs graph.QuadStore, it graph.Iterator) graph.Iterator {
i := it.Clone()
ctx := p.baseContext
ctx := &p.baseContext
for _, m := range p.stack {
i, ctx = m.Apply(qs, i, ctx)
}