Add The Zoo graph to demo Multi-Label#3509
Conversation
Adds ZOO to the GraphData enum and wires it into every test harness that already supports the other named toy graphs: TinkerWorld (embedded, transaction, and shuffle graph variants), RemoteWorld/TinkerFactoryDataLoader for server-backed tests, both gremlin-server-integration.yaml configs, and the Python, JavaScript, Go, and .NET GLV Gherkin runners. The zoo graph uses tinkergraph-multilabel.properties since it requires ZERO_OR_MORE vertex label cardinality. Updated the two graph-manager tests whose assertions hardcoded the total configured graph count, which shifted by one with the new entry. Converts scenarios in ElementMap.feature, ValueMap.feature, and Labels.feature from a bespoke empty-graph-plus-initializer fixture to the zoo graph wherever the traversal under test is read-only and the zoo's pre-populated multi-label vertices/edges (tux, lagoon, canopy, atlas, etc.) can express the same shape deterministically. Scenarios that mutate the graph, need a vertex with zero or exactly-one label, or depend on a provider's implicit default label-rendering mode (which is a per-World configuration switch independent of graph data) remain on the empty graph. Assisted-by: Claude Code:claude-sonnet-5
Converts 7 of the 14 executable gremlin-groovy examples added for
multi-label support in the-traversal.asciidoc to use [gremlin-groovy,theZoo]
instead of hand-building a single-vertex TinkerGraph inline:
- By Step: group().by(label) vs by(labels().fold())
- Choose Step: choose(T.label) non-determinism
- ElementMap: with("multilabel") example
- Has Step: chained hasLabel() AND/OR semantics
- Label Step
- Labels Step
- ValueMap: with("multilabel") example
Each converted example is read-only after the block's own setup, so there
is no risk of mutation leaking across examples: the docs preprocessor opens
a fresh TinkerFactory.createTheZoo() graph for every [gremlin-groovy,theZoo]
block. Kept the AddLabel, DropLabel, and mergeV examples on hand-built empty
graphs since they depend on precise, narrative-driven mutation sequences or
a LabelCardinality.ONE case the zoo graph can't represent.
Assisted-by: Kiro:claude-sonnet-5
DeepEqualityExtensions.DeepEqual compared IEnumerable values with an
order-sensitive SequenceEqual, including HashSet values nested inside a
result Dictionary (e.g. the t[label] entry of an elementMap()/valueMap()
result under with("multilabel")). Single-element label sets never
surfaced this, but the zoo graph's multi-label vertices (e.g. tux with
4 labels) exposed it: the expected HashSet built from the s[...] Gherkin
token and the actual HashSet deserialized by GraphBinary4's SetSerializer
can differ in iteration order despite containing identical elements,
causing SequenceEqual to spuriously fail.
Adds an ISet-aware branch that uses SetEquals before falling back to
SequenceEqual for ordered collections.
Fixes 3 failing scenarios under the GraphBinary4MessageSerializer variant
of RunGherkinBasedTests: g_withXmultilabelX_V_elementMap_multilabel,
g_withXmultilabelX_V_valueMap_withXtokensX_multilabel, and
g_withXmultilabelX_E_elementMap.
Also includes the regenerated Gremlin.cs reflecting the zoo-graph feature
file conversions already committed to this branch.
Assisted-by: Kiro:claude-sonnet-5
Introduces the zoo graph to readers in the reference docs, following the same TIP + diagram + example pattern used for "The Crew" (createTheZoo(), data/tinkerpop-zoo*, LabelCardinality requirements), and adds it to the Gremlin Console tutorial's toy graph catalogue alongside classic, modern, and the crew. The diagram (the-zoo-graph.png) is generated with Graphviz's fdp layout engine, styled to match the existing modern/crew diagrams: filled circles labeled with vertex id + labels, rounded property callouts, and curved edges labeled with the edge label plus its id. It reflects all 13 vertices and 20 edges from TinkerFactory.generateTheZoo(). Assisted-by: Kiro:claude-sonnet-5
Removes the tinkerpop-zoo-v3.kryo file mapping and feature-requirement list for LoadGraphWith.GraphData.ZOO. Neither the current Gryo nor GraphSON writers preserve multi-label vertices when serializing a whole graph (both StarGraphGraphSONSerializer and the Gryo VertexSerializer write a single label string, not the full label set), so a generated data file for the zoo graph would silently drop the multi-label vertices it exists to showcase. ZOO remains in the GraphData enum since it's still used successfully via the Gherkin 'Given the zoo graph' step, which builds the graph directly in memory through TinkerFactory.createTheZoo()/generateTheZoo() rather than deserializing a file, and is unaffected by this gap. Calling location() or featuresRequired() on ZOO now falls through to the existing 'No file/features for this GraphData type' exceptions rather than pointing at a nonexistent resource. Assisted-by: Kiro:claude-sonnet-5
StarGraphGraphSONSerializerV4/StarGraphGraphSONDeserializer only ever wrote/read a vertex's label as a single string, even under GraphSON V4, so a multi-label vertex silently lost all but one of its labels when serialized through the StarGraph codec. Fixes the V4 serializer to write the full label set as an array (matching the convention already used by the element-level V4 serializers for the driver protocol) and the shared deserializer to read either a single string (V1/V2/V3) or an array (V4) back into a StarVertex's label set. Adds a tinkerpop-zoo-v4.json GraphSON V4 fixture (generated from TinkerFactory.createTheZoo()) and registers it in TestFiles so HadoopGraphWorld can load the zoo graph for @multilabel Gherkin scenarios, using GraphSONInputFormat/V4_0 instead of Gryo since Gryo's StarGraph codec (StarGraphSerializer) has the same single-label limitation and is being left as-is for a later follow-up. Also fixes HadoopElement, which delegated label() to its wrapped element but never overrode labels(), silently falling back to Element's single-label default (Collections.singleton(label())) regardless of how many labels the underlying vertex actually had. Spark's equivalent SparkGraphWorld wiring is left for a follow-up; it shares the same HadoopGraph/StarGraph machinery as Hadoop but hasn't been updated yet. Assisted-by: Kiro:claude-sonnet-5
…d Spark StarGraphSerializer's Kryo format only ever wrote/read a vertex's label as a single string, so a multi-label vertex silently lost all but one label when serialized. Introduces a VERSION_2 format byte that writes the full label set as a list; VERSION_1 (single label) data written by prior versions of this serializer remains readable via a version-branched reader, so existing .kryo fixtures are unaffected. Attachable.Method.createVertex (used by GryoReader.readGraph and other providers' attach-to-host-graph logic) had the same gap - it read a multi-label source vertex correctly but only ever passed a single label to the new vertex. Fixed to call addLabel() for any labels beyond the first. Adds a tinkerpop-zoo-v3.kryo fixture (generated via the existing IoDataGenerationTest convention) and registers it in TestFiles, replacing the GraphSON V4-only workaround from the prior commit. HadoopGraphWorld and SparkGraphWorld now both load the zoo graph the same way as every other reference graph, via plain Gryo. GraphSON V1/V2/V3 remain single-label-only, so requesting the zoo graph via useGraphSON=true now fails with a clear error rather than silently truncating labels. The StarGraphGraphSONSerializerV4/StarGraphGraphSONDeserializer fix from the prior commit is unchanged and still exercised by its own test; it remains a legitimate improvement to the V4 GraphSON wire format independent of how Hadoop/Spark load their reference graphs. Verified against HadoopGraphFeatureIntegrateTest (2129 scenarios), HadoopGraphProcessStandardIntegrateTest (206 tests), and SparkGraphFeatureIntegrateTest (1448 scenarios) - all passing with zero failures/errors. Assisted-by: Kiro:claude-sonnet-5
|
|
||
| [[the-zoo-toy-graph]] | ||
| TIP: A toy graph demonstrating multi-label vertices alongside a variety of property types is available at | ||
| `TinkerFactory.createTheZoo()` and `data/tinkerpop-zoo*`. Unlike "The Crew" above, which requires a graph configured |
There was a problem hiding this comment.
doesn't this sentence read strangely?
Unlike "The Crew" above, which requires a graph configured for vertex multi-properties and meta-properties, "The Zoo" requires a
LabelCardinalityofONE_OR_MOREorZERO_OR_MORE.
We don't "configure" graphs for multi/meta-properties. A graph "supports" those things. You might say that you "configure" label cardinality for "TinkerGraph" but not every graph will have a "configuration" for that (i.e. some graphs will just support it or not) so you'd have to be specific.
| `ZERO_OR_MORE`. | ||
|
|
||
| .The Zoo | ||
| image::the-zoo-graph.png[width=685] |
There was a problem hiding this comment.
Can't help wondering if this graph carries too much to display nicely for folks to follow as an image. I won't let it block the PR but maybe we just need do showcase the multilabels for the graph visually or a core subgraph...
Summary
This PR adds a new toy graph, "the zoo," and uses it to replace bespoke empty-graph-plus-initializer fixtures in the multi-label test suite and reference documentation with a shared, deterministic dataset.
Changes
New toy graph (TinkerFactory.createTheZoo() / generateTheZoo())
Note that this PR is meant to stack on top of the #3483 which introduces multilabel as part of https://issues.apache.org/jira/browse/TINKERPOP-3261