From 82e74cb55fc827afa924fe29fef2d8ffb81562d3 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Mon, 27 Dec 2021 14:20:50 -0700 Subject: [PATCH] Improvements to gg.Graph An empty `Value` is now valid. It is now possibly to change the edgeVal of an OpenEdge. It feels like this shouldn't be necessary, but it greatly simplifies the decoding logic to have this. A tuple which is created with just one input edge, and with no edge value of its own, is now automatically simplified to just that input edge. --- gg/gg.go | 28 +++++++++++++++++++--------- gg/gg_test.go | 9 +++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/gg/gg.go b/gg/gg.go index 9d938c1..a006280 100644 --- a/gg/gg.go +++ b/gg/gg.go @@ -1,8 +1,8 @@ // Package gg implements ginger graph creation, traversal, and (de)serialization package gg -// Value represents a value being stored in a Graph. Exactly one field must be -// non-nil. +// Value represents a value being stored in a Graph. No more than one field may +// be non-nil. No fields being set indicates lack of value. type Value struct { Name *string Number *int64 @@ -16,6 +16,9 @@ type Value struct { func (v Value) Equal(v2 Value) bool { switch { + case v == Value{} && v2 == Value{}: + return true + case v.Name != nil && v2.Name != nil && *v.Name == *v2.Name: return true @@ -54,13 +57,16 @@ type OpenEdge struct { val Value } +// WithEdgeVal returns a copy of the OpenEdge with the edge value replaced by +// the given one. +func (oe OpenEdge) WithEdgeVal(val Value) OpenEdge { + oe.val = val + return oe +} + // ValueOut creates a OpenEdge which, when used to construct a Graph, represents // an edge (with edgeVal attached to it) coming from the ValueVertex containing // val. -// -// When constructing Graphs, Value vertices are de-duplicated on their Value. So -// multiple ValueOut OpenEdges constructed with the same val will be leaving the -// same Vertex instance in the constructed Graph. func ValueOut(val, edgeVal Value) OpenEdge { return OpenEdge{fromV: mkVertex(ValueVertex, val), val: edgeVal} } @@ -69,10 +75,14 @@ func ValueOut(val, edgeVal Value) OpenEdge { // represents an edge (with edgeVal attached to it) coming from the // TupleVertex comprised of the given ordered-set of input edges. // -// When constructing Graphs Tuple vertices are de-duplicated on their input -// edges. So multiple Tuple OpenEdges constructed with the same set of input -// edges will be leaving the same Tuple instance in the constructed Graph. +// If len(ins) == 1 and edgeVal == Value{}, then that single OpenEdge is +// returned as-is. func TupleOut(ins []OpenEdge, edgeVal Value) OpenEdge { + + if len(ins) == 1 && edgeVal == (Value{}) { + return ins[0] + } + return OpenEdge{ fromV: mkVertex(TupleVertex, Value{}, ins...), val: edgeVal, diff --git a/gg/gg_test.go b/gg/gg_test.go index a33d3cb..96e6d5a 100644 --- a/gg/gg_test.go +++ b/gg/gg_test.go @@ -56,6 +56,15 @@ func TestEqual(t *testing.T) { }, n("add")), n("out")), exp: false, }, + { + // tuple with a single input edge that has no edgeVal should be + // equivalent to just that edge. + a: ZeroGraph.AddValueIn(TupleOut([]OpenEdge{ + ValueOut(i(1), n("ident")), + }, Value{}), n("out")), + b: ZeroGraph.AddValueIn(ValueOut(i(1), n("ident")), n("out")), + exp: true, + }, { a: ZeroGraph. AddValueIn(ValueOut(n("in"), n("incr")), n("out")).