[
https://issues.apache.org/jira/browse/TINKERPOP-3261?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18094636#comment-18094636
]
ASF GitHub Bot commented on TINKERPOP-3261:
-------------------------------------------
spmallette commented on code in PR #3483:
URL: https://github.com/apache/tinkerpop/pull/3483#discussion_r3545955917
##########
tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerVertex.java:
##########
@@ -54,31 +57,150 @@ public class TinkerVertex extends TinkerElement implements
Vertex {
private boolean allowNullPropertyValues;
private final boolean isTxMode;
+ /**
+ * Multi-label storage for this vertex. Starts as an immutable set
(lightweight) and is
+ * upgraded to a mutable ConcurrentHashMap-backed set on first label
mutation.
+ */
+ protected Set<String> vertexLabels;
+
protected TinkerVertex(final Object id, final String label, final
AbstractTinkerGraph graph) {
- super(id, label);
- this.graph = graph;
- this.isTxMode = graph instanceof TinkerTransactionGraph;
- this.allowNullPropertyValues =
graph.features().vertex().supportsNullPropertyValues();
+ this(id, Collections.singleton(label != null ? label :
Vertex.DEFAULT_LABEL), graph, -1);
}
protected TinkerVertex(final Object id, final String label, final
AbstractTinkerGraph graph, final long currentVersion) {
- super(id, label, currentVersion);
+ this(id, Collections.singleton(label != null ? label :
Vertex.DEFAULT_LABEL), graph, currentVersion);
+ }
+
+ /**
+ * Constructs a TinkerVertex with multiple labels.
+ */
+ protected TinkerVertex(final Object id, final Set<String> labels, final
AbstractTinkerGraph graph) {
+ this(id, labels, graph, -1);
+ }
+
+ /**
+ * Canonical constructor. Constructs a TinkerVertex with multiple labels
and a specific version (for transactional graphs).
+ * Uses a single-switch pattern to handle default label injection per the
configured cardinality.
+ */
+ protected TinkerVertex(final Object id, final Set<String> labels, final
AbstractTinkerGraph graph, final long currentVersion) {
+ super(id, null, currentVersion); // label field set below
this.graph = graph;
this.isTxMode = graph instanceof TinkerTransactionGraph;
this.allowNullPropertyValues =
graph.features().vertex().supportsNullPropertyValues();
+
+ // Build the initial label set. Use lightweight immutable sets when
possible.
+ final Set<String> initial = new LinkedHashSet<>();
+ switch (graph.vertexLabelCardinality) {
+ case ONE:
+ // Exactly 1 label: use provided or default
+ if (labels != null && !labels.isEmpty())
+ initial.addAll(labels);
+ else
+ initial.add(graph.defaultVertexLabel);
+ break;
+ case ONE_OR_MORE:
+ // Default label always present alongside any user labels
+ initial.add(graph.defaultVertexLabel);
+ if (labels != null) initial.addAll(labels);
+ break;
+ case ZERO_OR_MORE:
+ if (labels != null) initial.addAll(labels);
+ break;
+ }
+
+ // Validate the resulting set conforms to cardinality
+
LabelCardinalityValidator.validateCreation(graph.vertexLabelCardinality,
initial);
+
+ // Store as immutable — will be upgraded on first mutation via
ensureMutableLabels()
+ this.vertexLabels = initial.size() <= 1
+ ? (initial.isEmpty() ? Collections.emptySet() :
Collections.singleton(initial.iterator().next()))
+ : Collections.unmodifiableSet(initial);
+
+ this.label = this.vertexLabels.isEmpty() ? "" :
this.vertexLabels.iterator().next();
+ }
+
+ /**
+ * Upgrades the label set to a mutable ConcurrentHashMap-backed set on
first mutation.
+ * This is a one-time cost per vertex that actually needs label mutation.
+ */
+ private void ensureMutableLabels() {
Review Comment:
TinkerGraph isn't built for concurrency i guess, but it might be good to
update the javadoc to make it clear that we actively decided that concurrent
label mutation on the same vertex is not safe.
> Enable multiple label support on vertex with configurable label cardinality
> ---------------------------------------------------------------------------
>
> Key: TINKERPOP-3261
> URL: https://issues.apache.org/jira/browse/TINKERPOP-3261
> Project: TinkerPop
> Issue Type: Task
> Affects Versions: 4.0.0
> Reporter: Yang Xia
> Priority: Major
>
> Vertices are currently limited to a single immutable label assigned at
> creation. This prevents modeling common real-world scenarios where entities
> naturally belong to multiple categories (e.g., a person who is both an
> employee and a manager).
>
> Introduce a configurable LabelCardinality that controls how many labels a
> vertex may have and whether they can be mutated after creation. Three
> proposed modes: ONE (current behavior, default), ONE_OR_MORE (mutable,
> minimum one), ZERO_OR_MORE (fully flexible).
>
> New steps:
>
> - labels() — flatMap step emitting each label as a traverser
> - addLabel(String, String...) — add labels to a vertex
> - dropLabel(String, String...) — remove specific labels
> - dropLabels() — remove all labels
> Edge labels remain at cardinality ONE. The infrastructure would support
> future edge multi-label enablement without wire format changes.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)