This is an automated email from the ASF dual-hosted git repository.
vaughn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph.git
The following commit(s) were added to refs/heads/master by this push:
new e0f572b54 refactor(server): support update TTL in labels & enhance
configs (#2938)
e0f572b54 is described below
commit e0f572b54ce2ede420d45133405c4b3224a806ea
Author: imbajin <[email protected]>
AuthorDate: Thu Jan 22 16:38:44 2026 +0800
refactor(server): support update TTL in labels & enhance configs (#2938)
---
.asf.yaml | 8 +-
.../org/apache/hugegraph/config/ServerOptions.java | 6 +-
.../hugegraph/schema/builder/EdgeLabelBuilder.java | 43 ++++++--
.../schema/builder/VertexLabelBuilder.java | 76 +++++++------
.../apache/hugegraph/core/EdgeLabelCoreTest.java | 120 ++++++++++++++++++++-
.../apache/hugegraph/core/VertexLabelCoreTest.java | 87 ++++++++++++++-
6 files changed, 291 insertions(+), 49 deletions(-)
diff --git a/.asf.yaml b/.asf.yaml
index 3f53bf588..2cc4b1d1b 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -18,9 +18,8 @@
github:
features:
issues: true
- # Enable wiki for documentation
wiki: true
- # Enable projects for project management boards
+ # Enable projects for project (task)management boards
projects: true
discussions: true
description: A graph database that supports more than 100+ billion data,
high performance and scalability (Include OLTP Engine & REST-API & Backends)
@@ -46,11 +45,12 @@ github:
required_pull_request_reviews:
dismiss_stale_reviews: true
require_code_owner_reviews: false
- required_approving_review_count: 2
+ required_approving_review_count: 1
# (for non-committer): assign/edit/close issues & PR, without write access
to the code
collaborators:
- - Pengzna
- haohao0103
+ - kenssa4eedfd
+ - Tsukilc
# refer
https://cwiki.apache.org/confluence/display/INFRA/Git+-+.asf.yaml+features#Git.asf.yamlfeatures-Notificationsettingsforrepositories
notifications:
diff --git
a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java
b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java
index c94725737..920d119d4 100644
---
a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java
+++
b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java
@@ -389,7 +389,7 @@ public class ServerOptions extends OptionHolder {
"batch.max_vertices_per_batch",
"The maximum number of vertices submitted per batch.",
positiveInt(),
- 500
+ 2500
);
public static final ConfigOption<Integer> MAX_EDGES_PER_BATCH =
@@ -397,7 +397,7 @@ public class ServerOptions extends OptionHolder {
"batch.max_edges_per_batch",
"The maximum number of edges submitted per batch.",
positiveInt(),
- 500
+ 2500
);
public static final ConfigOption<Integer> MAX_WRITE_RATIO =
@@ -406,7 +406,7 @@ public class ServerOptions extends OptionHolder {
"The maximum thread ratio for batch writing, " +
"only take effect if the batch.max_write_threads is 0.",
rangeInt(0, 100),
- 50
+ 70
);
public static final ConfigOption<Integer> MAX_WRITE_THREADS =
diff --git
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java
index 410b094fb..32937a2cf 100644
---
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java
+++
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/EdgeLabelBuilder.java
@@ -61,7 +61,7 @@ public class EdgeLabelBuilder extends AbstractBuilder
private Set<String> properties;
private List<String> sortKeys;
private Set<String> nullableKeys;
- private long ttl;
+ private Long ttl;
private String ttlStartTime;
private Boolean enableLabelIndex;
private Userdata userdata;
@@ -80,7 +80,7 @@ public class EdgeLabelBuilder extends AbstractBuilder
this.properties = new HashSet<>();
this.sortKeys = new ArrayList<>();
this.nullableKeys = new HashSet<>();
- this.ttl = 0L;
+ this.ttl = null;
this.ttlStartTime = null;
this.enableLabelIndex = null;
this.userdata = new Userdata();
@@ -122,11 +122,7 @@ public class EdgeLabelBuilder extends AbstractBuilder
}
edgeLabel.frequency(this.frequency == Frequency.DEFAULT ?
Frequency.SINGLE : this.frequency);
- edgeLabel.ttl(this.ttl);
- if (this.ttlStartTime != null) {
- edgeLabel.ttlStartTime(this.graph().propertyKey(
- this.ttlStartTime).id());
- }
+ this.updateTTL(edgeLabel);
edgeLabel.enableLabelIndex(this.enableLabelIndex == null ||
this.enableLabelIndex);
for (String key : this.properties) {
@@ -209,7 +205,7 @@ public class EdgeLabelBuilder extends AbstractBuilder
this.checkSortKeys();
this.checkNullableKeys(Action.INSERT);
Userdata.check(this.userdata, Action.INSERT);
- this.checkTtl();
+ this.checkTTL();
this.checkUserdata(Action.INSERT);
edgeLabel = this.build();
@@ -312,6 +308,7 @@ public class EdgeLabelBuilder extends AbstractBuilder
PropertyKey propertyKey = this.graph().propertyKey(key);
edgeLabel.nullableKey(propertyKey.id());
}
+ this.updateTTL(edgeLabel);
edgeLabel.userdata(this.userdata);
this.graph().updateEdgeLabel(edgeLabel);
return edgeLabel;
@@ -670,7 +667,35 @@ public class EdgeLabelBuilder extends AbstractBuilder
}
}
- private void checkTtl() {
+ /**
+ * Update TTL in two cases:
+ * 1) ttl > 0L: set or change a positive TTL
+ * 2) ttl == 0L and existing ttl > 0L: explicitly clear an existing TTL
+ * This allows removing TTL from a label that previously had TTL
configured.
+ * Note: ttl == null means not set, so we skip the update.
+ */
+ private void updateTTL(EdgeLabel edgeLabel) {
+ if (this.ttl == null) {
+ return;
+ }
+ if (this.ttl > 0L) {
+ edgeLabel.ttl(this.ttl);
+ if (this.ttlStartTime != null) {
+
edgeLabel.ttlStartTime(this.graph().propertyKey(this.ttlStartTime).id());
+ }
+ } else if (this.ttl == 0L && edgeLabel.ttl() > 0L) {
+ // Clear TTL and ttlStartTime
+ edgeLabel.ttl(0L);
+ edgeLabel.ttlStartTime(IdGenerator.ZERO);
+ }
+ }
+
+ private void checkTTL() {
+ if (this.ttl == null) {
+ E.checkArgument(this.ttlStartTime == null,
+ "Can't set ttl start time if ttl is not set");
+ return;
+ }
E.checkArgument(this.ttl >= 0,
"The ttl must be >= 0, but got: %s", this.ttl);
if (this.ttl == 0L) {
diff --git
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java
index 53b6cabdd..496264620 100644
---
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java
+++
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/builder/VertexLabelBuilder.java
@@ -52,7 +52,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
private final Set<String> properties;
private final List<String> primaryKeys;
private final Set<String> nullableKeys;
- private long ttl;
+ private Long ttl;
private String ttlStartTime;
private Boolean enableLabelIndex;
private final Userdata userdata;
@@ -68,7 +68,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
this.properties = new HashSet<>();
this.primaryKeys = new ArrayList<>();
this.nullableKeys = new HashSet<>();
- this.ttl = 0L;
+ this.ttl = null;
this.ttlStartTime = null;
this.enableLabelIndex = null;
this.userdata = new Userdata();
@@ -99,13 +99,8 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
this.id, this.name);
VertexLabel vertexLabel = new VertexLabel(this.graph(), id, this.name);
vertexLabel.idStrategy(this.idStrategy);
- vertexLabel.enableLabelIndex(this.enableLabelIndex == null ||
- this.enableLabelIndex);
- vertexLabel.ttl(this.ttl);
- if (this.ttlStartTime != null) {
- vertexLabel.ttlStartTime(this.graph().propertyKey(
- this.ttlStartTime).id());
- }
+ vertexLabel.enableLabelIndex(this.enableLabelIndex == null ||
this.enableLabelIndex);
+ this.updateTTL(vertexLabel);
// Assign properties
for (String key : this.properties) {
PropertyKey propertyKey = this.graph().propertyKey(key);
@@ -142,7 +137,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
this.checkIdStrategy();
this.checkNullableKeys(Action.INSERT);
Userdata.check(this.userdata, Action.INSERT);
- this.checkTtl();
+ this.checkTTL();
this.checkUserdata(Action.INSERT);
vertexLabel = this.build();
@@ -225,6 +220,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
PropertyKey propertyKey = this.graph().propertyKey(key);
vertexLabel.nullableKey(propertyKey.id());
}
+ this.updateTTL(vertexLabel);
vertexLabel.userdata(this.userdata);
this.graph().updateVertexLabel(vertexLabel);
return vertexLabel;
@@ -276,8 +272,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
@Override
public VertexLabelBuilder idStrategy(IdStrategy idStrategy) {
- E.checkArgument(this.idStrategy == IdStrategy.DEFAULT ||
- this.idStrategy == idStrategy,
+ E.checkArgument(this.idStrategy == IdStrategy.DEFAULT ||
this.idStrategy == idStrategy,
"Not allowed to change id strategy for " +
"vertex label '%s'", this.name);
this.idStrategy = idStrategy;
@@ -434,18 +429,15 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
if (action == Action.ELIMINATE) {
if (!this.nullableKeys.isEmpty()) {
throw new NotAllowException(
- "Not support to eliminate nullableKeys " +
- "for vertex label currently");
+ "Not support to eliminate nullableKeys for vertex
label currently");
}
return;
}
VertexLabel vertexLabel = this.vertexLabelOrNull(this.name);
// The originProps is empty when firstly create vertex label
- List<String> originProps = vertexLabel == null ?
- ImmutableList.of() :
- this.graph()
- .mapPkId2Name(vertexLabel.properties());
+ List<String> originProps = vertexLabel == null ? ImmutableList.of() :
+
this.graph().mapPkId2Name(vertexLabel.properties());
Set<String> appendProps = this.properties;
E.checkArgument(CollectionUtil.union(originProps, appendProps)
@@ -454,10 +446,8 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
"must belong to the origin/new properties: %s/%s",
this.nullableKeys, originProps, appendProps);
- List<String> primaryKeys = vertexLabel == null ?
- this.primaryKeys :
- this.graph()
-
.mapPkId2Name(vertexLabel.primaryKeys());
+ List<String> primaryKeys = vertexLabel == null ? this.primaryKeys :
+
this.graph().mapPkId2Name(vertexLabel.primaryKeys());
E.checkArgument(!CollectionUtil.hasIntersection(primaryKeys,
this.nullableKeys),
"The nullableKeys: %s are not allowed to " +
@@ -465,11 +455,9 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
this.nullableKeys, primaryKeys, this.name);
if (action == Action.APPEND) {
- Collection<String> newAddedProps = CollectionUtils.subtract(
- appendProps, originProps);
+ Collection<String> newAddedProps =
CollectionUtils.subtract(appendProps, originProps);
E.checkArgument(this.nullableKeys.containsAll(newAddedProps),
- "The new added properties: %s must be nullable",
- newAddedProps);
+ "The new added properties: %s must be nullable",
newAddedProps);
}
}
@@ -498,8 +486,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
"when using '%s' id strategy", strategy);
break;
default:
- throw new AssertionError(String.format(
- "Unknown id strategy '%s'", strategy));
+ throw new AssertionError(String.format("Unknown id strategy
'%s'", strategy));
}
if (this.idStrategy == IdStrategy.PRIMARY_KEY) {
this.checkPrimaryKeys();
@@ -546,7 +533,35 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
}
}
- private void checkTtl() {
+ /**
+ * Update TTL in two cases:
+ * 1) ttl > 0L: set or change a positive TTL
+ * 2) ttl == 0L and existing ttl > 0L: explicitly clear an existing TTL
+ * This allows removing TTL from a label that previously had TTL
configured.
+ * Note: ttl == null means not set, so we skip the update.
+ */
+ private void updateTTL(VertexLabel vertexLabel) {
+ if (this.ttl == null) {
+ return;
+ }
+ if (this.ttl > 0L) {
+ vertexLabel.ttl(this.ttl);
+ if (this.ttlStartTime != null) {
+
vertexLabel.ttlStartTime(this.graph().propertyKey(this.ttlStartTime).id());
+ }
+ } else if (this.ttl == 0L && vertexLabel.ttl() > 0L) {
+ // Clear TTL and ttlStartTime
+ vertexLabel.ttl(0L);
+ vertexLabel.ttlStartTime(IdGenerator.ZERO);
+ }
+ }
+
+ private void checkTTL() {
+ if (this.ttl == null) {
+ E.checkArgument(this.ttlStartTime == null,
+ "Can't set ttl start time if ttl is not set");
+ return;
+ }
E.checkArgument(this.ttl >= 0,
"The ttl must be >= 0, but got: %s", this.ttl);
if (this.ttl == 0L) {
@@ -588,8 +603,7 @@ public class VertexLabelBuilder extends AbstractBuilder
implements VertexLabel.B
// pass
break;
default:
- throw new AssertionError(String.format(
- "Unknown schema action '%s'", action));
+ throw new AssertionError(String.format("Unknown schema action
'%s'", action));
}
}
diff --git
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java
index 3b81c2f16..8629f78b3 100644
---
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java
+++
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeLabelCoreTest.java
@@ -480,7 +480,7 @@ public class EdgeLabelCoreTest extends SchemaCoreTest {
}
@Test
- public void testAddEdgeLabelWithTtl() {
+ public void testAddEdgeLabelWithTTL() {
super.initPropertyKeys();
SchemaManager schema = graph().schema();
@@ -561,6 +561,124 @@ public class EdgeLabelCoreTest extends SchemaCoreTest {
assertContainsPk(ImmutableSet.of(write.ttlStartTime()), "date");
}
+ @Test
+ public void testAppendEdgeLabelWithTTL() {
+ super.initPropertyKeys();
+
+ SchemaManager schema = graph().schema();
+
+ schema.propertyKey("date").asDate().ifNotExist().create();
+
+ schema.vertexLabel("person")
+ .properties("name", "age", "city")
+ .primaryKeys("name")
+ .nullableKeys("city")
+ .create();
+
+ schema.vertexLabel("book")
+ .properties("name")
+ .primaryKeys("name")
+ .create();
+
+ // Create an edge label without TTL
+ EdgeLabel read = schema.edgeLabel("read").link("person", "book")
+ .properties("date", "weight")
+ .create();
+
+ Assert.assertNotNull(read);
+ Assert.assertEquals("read", read.name());
+ Assert.assertEquals(0L, read.ttl());
+
+ // Update the edge label with TTL via append
+ read = schema.edgeLabel("read")
+ .ttl(86400L)
+ .append();
+
+ Assert.assertNotNull(read);
+ Assert.assertEquals("read", read.name());
+ Assert.assertEquals(86400L, read.ttl());
+ }
+
+ @Test
+ public void testAppendEdgeLabelResetTTL() {
+ super.initPropertyKeys();
+
+ SchemaManager schema = graph().schema();
+
+ schema.vertexLabel("person")
+ .properties("name", "age", "city")
+ .primaryKeys("name")
+ .nullableKeys("city")
+ .create();
+
+ schema.vertexLabel("book")
+ .properties("name")
+ .primaryKeys("name")
+ .create();
+
+ // Create an edge label with TTL
+ EdgeLabel read = schema.edgeLabel("read").link("person", "book")
+ .properties("time", "weight")
+ .ttl(86400L)
+ .create();
+
+ Assert.assertNotNull(read);
+ Assert.assertEquals("read", read.name());
+ Assert.assertEquals(86400L, read.ttl());
+
+ // Reset TTL to 0 via append
+ read = schema.edgeLabel("read")
+ .ttl(0L)
+ .append();
+
+ Assert.assertNotNull(read);
+ Assert.assertEquals("read", read.name());
+ Assert.assertEquals(0L, read.ttl());
+ }
+
+ @Test
+ public void testAppendEdgeLabelWithoutTTLShouldNotClearExistingTTL() {
+ super.initPropertyKeys();
+
+ SchemaManager schema = graph().schema();
+
+ schema.propertyKey("date").asDate().ifNotExist().create();
+
+ schema.vertexLabel("person")
+ .properties("name", "age", "city")
+ .primaryKeys("name")
+ .nullableKeys("city")
+ .create();
+
+ schema.vertexLabel("book")
+ .properties("name")
+ .primaryKeys("name")
+ .create();
+
+ // Create edge label with TTL and ttlStartTime
+ EdgeLabel read = schema.edgeLabel("read").link("person", "book")
+ .properties("date", "weight")
+ .ttl(86400L)
+ .ttlStartTime("date")
+ .create();
+
+ Assert.assertNotNull(read);
+ Assert.assertEquals(86400L, read.ttl());
+ Assert.assertNotNull(read.ttlStartTime());
+ assertContainsPk(ImmutableSet.of(read.ttlStartTime()), "date");
+
+ // Append property WITHOUT specifying ttl
+ read = schema.edgeLabel("read")
+ .nullableKeys("weight")
+ .append();
+
+ // Both TTL and ttlStartTime should remain unchanged
+ Assert.assertNotNull(read);
+ Assert.assertEquals(86400L, read.ttl());
+ Assert.assertNotNull(read.ttlStartTime());
+ assertContainsPk(ImmutableSet.of(read.ttlStartTime()), "date");
+ }
+
@Test
public void testAppendEdgeLabelWithUndefinedNullableKeys() {
super.initPropertyKeys();
diff --git
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java
index 8dafcc595..a43731f23 100644
---
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java
+++
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexLabelCoreTest.java
@@ -566,7 +566,7 @@ public class VertexLabelCoreTest extends SchemaCoreTest {
}
@Test
- public void testAddVertexLabelWithTtl() {
+ public void testAddVertexLabelWithTTL() {
super.initPropertyKeys();
SchemaManager schema = graph().schema();
@@ -633,6 +633,91 @@ public class VertexLabelCoreTest extends SchemaCoreTest {
assertContainsPk(ImmutableSet.of(student.ttlStartTime()), "born");
}
+ @Test
+ public void testAppendVertexLabelWithTTL() {
+ super.initPropertyKeys();
+
+ SchemaManager schema = graph().schema();
+
+ schema.propertyKey("born").asDate().ifNotExist().create();
+
+ // Create a vertex label without TTL
+ VertexLabel person = schema.vertexLabel("person")
+ .properties("name", "age", "city", "born")
+ .create();
+
+ Assert.assertNotNull(person);
+ Assert.assertEquals("person", person.name());
+ Assert.assertEquals(0L, person.ttl());
+
+ // Update the vertex label with TTL via append
+ person = schema.vertexLabel("person")
+ .ttl(86400L)
+ .append();
+
+ Assert.assertNotNull(person);
+ Assert.assertEquals("person", person.name());
+ Assert.assertEquals(86400L, person.ttl());
+ }
+
+ @Test
+ public void testAppendVertexLabelResetTTL() {
+ super.initPropertyKeys();
+
+ SchemaManager schema = graph().schema();
+
+ // Create a vertex label with TTL
+ VertexLabel person = schema.vertexLabel("person")
+ .properties("name", "age", "city")
+ .ttl(86400L)
+ .create();
+
+ Assert.assertNotNull(person);
+ Assert.assertEquals("person", person.name());
+ Assert.assertEquals(86400L, person.ttl());
+
+ // Reset TTL to 0 via append
+ person = schema.vertexLabel("person")
+ .ttl(0L)
+ .append();
+
+ Assert.assertNotNull(person);
+ Assert.assertEquals("person", person.name());
+ Assert.assertEquals(0L, person.ttl());
+ }
+
+ @Test
+ public void testAppendVertexLabelWithoutTTLShouldNotClearExistingTTL() {
+ super.initPropertyKeys();
+
+ SchemaManager schema = graph().schema();
+
+ schema.propertyKey("born").asDate().ifNotExist().create();
+
+ // Create label with TTL and ttlStartTime
+ VertexLabel person = schema.vertexLabel("person")
+ .properties("name", "age", "city", "born")
+ .ttl(86400L)
+ .ttlStartTime("born")
+ .create();
+
+ Assert.assertNotNull(person);
+ Assert.assertEquals(86400L, person.ttl());
+ Assert.assertNotNull(person.ttlStartTime());
+ assertContainsPk(ImmutableSet.of(person.ttlStartTime()), "born");
+
+ // Append property WITHOUT specifying ttl
+ person = schema.vertexLabel("person")
+ .nullableKeys("city")
+ .append();
+
+ // Both TTL and ttlStartTime should remain unchanged
+ Assert.assertNotNull(person);
+ Assert.assertEquals(86400L, person.ttl());
+ Assert.assertNotNull(person.ttlStartTime());
+ assertContainsPk(ImmutableSet.of(person.ttlStartTime()), "born");
+ }
+
@Test
public void testAppendVertexLabelWithUndefinedNullableKeys() {
super.initPropertyKeys();