From 255df7e9458b7bf080d1a34e3753c148c15fd224 Mon Sep 17 00:00:00 2001 From: zhangyi51 Date: Mon, 6 Aug 2018 17:19:53 +0800 Subject: [PATCH] hugegraph-1379 support restore graph in restoring mode and merging mode implement: #182 Change-Id: I7c2c85435af01c5d27279076d0473685b8f23f34 --- hugegraph-api/pom.xml | 2 +- .../com/baidu/hugegraph/api/GraphsAPI.java | 36 +- .../hugegraph/api/schema/EdgeLabelAPI.java | 11 + .../hugegraph/api/schema/IndexLabelAPI.java | 11 + .../hugegraph/api/schema/PropertyKeyAPI.java | 11 + .../hugegraph/api/schema/VertexLabelAPI.java | 11 + .../hugegraph/auth/HugeGraphAuthProxy.java | 12 - .../baidu/hugegraph/version/ApiVersion.java | 3 +- .../store/cassandra/CassandraStore.java | 23 +- .../store/cassandra/CassandraTables.java | 44 +- .../com/baidu/hugegraph/GremlinGraph.java | 3 - .../java/com/baidu/hugegraph/HugeGraph.java | 16 +- .../baidu/hugegraph/backend/LocalCounter.java | 28 +- .../backend/cache/CachedBackendStore.java | 10 + .../hugegraph/backend/store/BackendStore.java | 44 +- .../backend/store/memory/InMemoryDBStore.java | 45 +- .../backend/tx/GraphTransaction.java | 4 +- .../backend/tx/SchemaTransaction.java | 60 ++ .../schema/builder/EdgeLabelBuilder.java | 24 +- .../schema/builder/IndexLabelBuilder.java | 25 +- .../schema/builder/PropertyKeyBuilder.java | 24 +- .../schema/builder/SchemaBuilder.java | 2 + .../schema/builder/VertexLabelBuilder.java | 23 +- .../hugegraph/structure/HugeSearchIndex.java | 56 -- .../structure/HugeSecondaryIndex.java | 55 -- .../com/baidu/hugegraph/type/HugeType.java | 3 + .../hugegraph/type/define/GraphMode.java | 65 ++ .../backend/store/hbase/HbaseStore.java | 23 +- .../backend/store/hbase/HbaseTables.java | 19 +- .../backend/store/mysql/MysqlStore.java | 23 +- .../backend/store/mysql/MysqlTables.java | 67 +- .../backend/store/palo/PaloStoreProvider.java | 23 + .../store/rocksdb/RocksDBSessions.java | 1 + .../store/rocksdb/RocksDBStdSessions.java | 16 +- .../backend/store/rocksdb/RocksDBStore.java | 23 +- .../backend/store/rocksdb/RocksDBTables.java | 38 +- .../store/rocksdbsst/RocksDBSstSessions.java | 8 + .../store/rocksdbsst/RocksDBSstStore.java | 12 + .../baidu/hugegraph/core/CoreTestSuite.java | 3 +- .../baidu/hugegraph/core/RestoreCoreTest.java | 727 ++++++++++++++++++ .../unit/rocksdb/RocksDBCountersTest.java | 49 +- 41 files changed, 1367 insertions(+), 316 deletions(-) delete mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSearchIndex.java delete mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSecondaryIndex.java create mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphMode.java create mode 100644 hugegraph-test/src/main/java/com/baidu/hugegraph/core/RestoreCoreTest.java diff --git a/hugegraph-api/pom.xml b/hugegraph-api/pom.xml index 36b837946e..c71ed27c90 100644 --- a/hugegraph-api/pom.xml +++ b/hugegraph-api/pom.xml @@ -101,7 +101,7 @@ - 0.30.0.0 + 0.31.0.0 diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/GraphsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/GraphsAPI.java index 8c1f2e3c9e..16f15c2923 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/GraphsAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/GraphsAPI.java @@ -20,6 +20,7 @@ package com.baidu.hugegraph.api; import java.io.File; +import java.util.Map; import java.util.Set; import javax.annotation.security.RolesAllowed; @@ -44,9 +45,10 @@ import com.baidu.hugegraph.core.GraphManager; import com.baidu.hugegraph.schema.SchemaManager; import com.baidu.hugegraph.server.RestServer; +import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.codahale.metrics.annotation.Timed; -import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -152,38 +154,32 @@ public void clear(@Context GraphManager manager, @PUT @Timed - @Path("{name}/restoring") + @Path("{name}/mode") @Consumes(APPLICATION_JSON) @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") - public Object restoring(@Context GraphManager manager, - @PathParam("name") String name, - JsonRestoring jsonRestoring) { - LOG.debug("Set restoring status to: '{}' of graph '{}'", - jsonRestoring, name); + public Map mode(@Context GraphManager manager, + @PathParam("name") String name, + GraphMode mode) { + LOG.debug("Set mode to: '{}' of graph '{}'", mode, name); + E.checkArgument(mode != null, "Graph mode can't be null"); HugeGraph g = graph(manager, name); - g.restoring(jsonRestoring.restoring); - return jsonRestoring; + g.mode(mode); + return ImmutableMap.of("mode", mode); } @GET @Timed - @Path("{name}/restoring") + @Path("{name}/mode") @Consumes(APPLICATION_JSON) @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") - public Object restoring(@Context GraphManager manager, - @PathParam("name") String name) { - LOG.debug("Get restoring status of graph '{}'", name); + public Map mode(@Context GraphManager manager, + @PathParam("name") String name) { + LOG.debug("Get mode of graph '{}'", name); HugeGraph g = graph(manager, name); - return ImmutableMap.of("restoring", g.restoring()); - } - - private static class JsonRestoring { - - @JsonProperty("restoring") - public boolean restoring; + return ImmutableMap.of("mode", g.mode()); } } diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/EdgeLabelAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/EdgeLabelAPI.java index c529b974cf..0acd268084 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/EdgeLabelAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/EdgeLabelAPI.java @@ -43,6 +43,7 @@ import com.baidu.hugegraph.core.GraphManager; import com.baidu.hugegraph.schema.EdgeLabel; import com.baidu.hugegraph.type.define.Frequency; +import com.baidu.hugegraph.type.define.GraphMode; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.codahale.metrics.annotation.Timed; @@ -178,6 +179,16 @@ public void checkCreate(boolean isBatch) { private EdgeLabel.Builder convert2Builder(HugeGraph g) { EdgeLabel.Builder builder = g.schema().edgeLabel(this.name); + if (this.id != 0) { + E.checkArgument(this.id > 0, + "Only positive number can be assign as " + + "edge label id"); + E.checkArgument(g.mode() == GraphMode.RESTORING, + "Only accept edge label id when graph in " + + "RESTORING mode, but '%s' is in mode '%s'", + g, g.mode()); + builder.id(this.id); + } if (this.sourceLabel != null) { builder.sourceLabel(this.sourceLabel); } diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/IndexLabelAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/IndexLabelAPI.java index 19ffcf5a30..9850208e98 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/IndexLabelAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/IndexLabelAPI.java @@ -41,6 +41,7 @@ import com.baidu.hugegraph.core.GraphManager; import com.baidu.hugegraph.schema.IndexLabel; import com.baidu.hugegraph.type.HugeType; +import com.baidu.hugegraph.type.define.GraphMode; import com.baidu.hugegraph.type.define.IndexType; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; @@ -153,6 +154,16 @@ public void checkCreate(boolean isBatch) { private IndexLabel.Builder convert2Builder(HugeGraph g) { IndexLabel.Builder builder = g.schema().indexLabel(this.name); + if (this.id != 0) { + E.checkArgument(this.id > 0, + "Only positive number can be assign as " + + "index label id"); + E.checkArgument(g.mode() == GraphMode.RESTORING, + "Only accept index label id when graph in " + + "RESTORING mode, but '%s' is in mode '%s'", + g, g.mode()); + builder.id(this.id); + } builder.on(this.baseType, this.baseValue); if (this.indexType != null) { builder.indexType(this.indexType); diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/PropertyKeyAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/PropertyKeyAPI.java index 3649434b95..b774ef0b5e 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/PropertyKeyAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/PropertyKeyAPI.java @@ -43,6 +43,7 @@ import com.baidu.hugegraph.schema.PropertyKey; import com.baidu.hugegraph.type.define.Cardinality; import com.baidu.hugegraph.type.define.DataType; +import com.baidu.hugegraph.type.define.GraphMode; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.codahale.metrics.annotation.Timed; @@ -173,6 +174,16 @@ public void checkCreate(boolean isBatch) { private PropertyKey.Builder convert2Builder(HugeGraph g) { PropertyKey.Builder builder = g.schema().propertyKey(this.name); + if (this.id != 0) { + E.checkArgument(this.id > 0, + "Only positive number can be assign as " + + "property key id"); + E.checkArgument(g.mode() == GraphMode.RESTORING, + "Only accept property key id when graph in " + + "RESTORING mode, but '%s' is in mode '%s'", + g, g.mode()); + builder.id(this.id); + } if (this.cardinality != null) { builder.cardinality(this.cardinality); } diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/VertexLabelAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/VertexLabelAPI.java index 383dcd6623..6f28709678 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/VertexLabelAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/schema/VertexLabelAPI.java @@ -42,6 +42,7 @@ import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.core.GraphManager; import com.baidu.hugegraph.schema.VertexLabel; +import com.baidu.hugegraph.type.define.GraphMode; import com.baidu.hugegraph.type.define.IdStrategy; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; @@ -177,6 +178,16 @@ public void checkCreate(boolean isBatch) { private VertexLabel.Builder convert2Builder(HugeGraph g) { VertexLabel.Builder builder = g.schema().vertexLabel(this.name); + if (this.id != 0) { + E.checkArgument(this.id > 0, + "Only positive number can be assign as " + + "vertex label id"); + E.checkArgument(g.mode() == GraphMode.RESTORING, + "Only accept vertex label id when graph in " + + "RESTORING mode, but '%s' is in mode '%s'", + g, g.mode()); + builder.id(this.id); + } if (this.idStrategy != null) { builder.idStrategy(this.idStrategy); } diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java index 7236534fd4..765ed7141d 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java @@ -178,18 +178,6 @@ public void clearBackend() { this.hugegraph.clearBackend(); } - @Override - public void restoring(boolean restoring) { - this.verifyPermission(ROLE_ADMIN); - this.hugegraph.restoring(restoring); - } - - @Override - public boolean restoring() { - this.verifyPermission(ROLE_ADMIN); - return this.hugegraph.restoring(); - } - private void verifyPermission() { /* * The owner role should match the graph name diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/version/ApiVersion.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/version/ApiVersion.java index a3bbf34aa2..316ce88cfd 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/version/ApiVersion.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/version/ApiVersion.java @@ -74,10 +74,11 @@ public final class ApiVersion { * [0.28] Issue-153: Add task-cancel API * [0.29] Issue-39: Add rays and rings RESTful API * [0.30] Issue-32: Change index create API to return indexLabel and task id + * [0.31] Issue-182: Support restore graph in restoring and merging mode */ // The second parameter of Version.of() is for IDE running without JAR - public static final Version VERSION = Version.of(ApiVersion.class, "0.30"); + public static final Version VERSION = Version.of(ApiVersion.class, "0.31"); public static final void check() { // Check version of hugegraph-core. Firstly do check from version 0.3 diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java index 669f52be1d..3c8caec96e 100644 --- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java +++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java @@ -488,10 +488,17 @@ protected void clearTables() { } @Override - public Id nextId(HugeType type) { + public void increaseCounter(HugeType type, long increment) { this.checkSessionConnected(); CassandraSessionPool.Session session = super.sessions.session(); - return this.counters.nextId(session, type); + this.counters.increaseCounter(session, type, increment); + } + + @Override + public long getCounter(HugeType type) { + this.checkSessionConnected(); + CassandraSessionPool.Session session = super.sessions.session(); + return this.counters.getCounter(session, type); } } @@ -522,5 +529,17 @@ public Id nextId(HugeType type) { throw new UnsupportedOperationException( "CassandraGraphStore.nextId()"); } + + @Override + public void increaseCounter(HugeType type, long num) { + throw new UnsupportedOperationException( + "CassandraGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "CassandraGraphStore.getCounter()"); + } } } diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraTables.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraTables.java index fdef295655..cedf72c945 100644 --- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraTables.java +++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraTables.java @@ -65,8 +65,6 @@ public static class Counters extends CassandraTable { public static final String TABLE = "counters"; - public static final int MAX_TIMES = 1000; - public Counters() { super(TABLE); } @@ -84,40 +82,26 @@ public void init(CassandraSessionPool.Session session) { this.createTable(session, pkeys, ckeys, columns); } - public synchronized Id nextId(CassandraSessionPool.Session session, - HugeType type) { + public long getCounter(CassandraSessionPool.Session session, + HugeType type) { Clause where = formatEQ(HugeKeys.SCHEMA_TYPE, type.name()); Select select = QueryBuilder.select(formatKey(HugeKeys.ID)) .from(TABLE); select.where(where); - - Update update = QueryBuilder.update(TABLE); - // Id increase 1 - update.with(QueryBuilder.incr(formatKey(HugeKeys.ID), 1L)); - update.where(where); - - // Do get-increase-get-compare operation - long counter = 0L; - long expect = -1L; - - for (int i = 0; i < MAX_TIMES; i++) { - Row row = session.execute(select).one(); - if (row != null) { - counter = row.getLong(formatKey(HugeKeys.ID)); - } - if (counter == expect) { - break; - } - // Increase local counter - expect = counter + 1L; - // Increase remote counter - session.execute(update); + Row row = session.execute(select).one(); + if (row == null) { + return 0L; + } else { + return row.getLong(formatKey(HugeKeys.ID)); } + } - E.checkState(counter != 0L, "Please check whether Cassandra is OK"); - E.checkState(counter == expect, - "Cassandra is busy please try again"); - return IdGenerator.of(expect); + public void increaseCounter(CassandraSessionPool.Session session, + HugeType type, long increment) { + Update update = QueryBuilder.update(TABLE); + update.with(QueryBuilder.incr(formatKey(HugeKeys.ID), increment)); + update.where(formatEQ(HugeKeys.SCHEMA_TYPE, type.name())); + session.execute(update); } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java index beca257d1f..08400ded45 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java @@ -35,7 +35,4 @@ public interface GremlinGraph extends Graph { public String backend(); public void initBackend(); public void clearBackend(); - - public void restoring(boolean restoring); - public boolean restoring(); } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java index 06c012191d..27e806d954 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java @@ -66,10 +66,12 @@ import com.baidu.hugegraph.task.TaskScheduler; import com.baidu.hugegraph.traversal.optimize.HugeGraphStepStrategy; import com.baidu.hugegraph.traversal.optimize.HugeVertexStepStrategy; +import com.baidu.hugegraph.type.define.GraphMode; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.LockUtil; import com.baidu.hugegraph.util.Log; import com.baidu.hugegraph.variables.HugeVariables; +import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.RateLimiter; /** @@ -97,7 +99,7 @@ public class HugeGraph implements GremlinGraph { private final String name; private boolean closed; - private boolean restoring; + private GraphMode mode; private final HugeConfig configuration; @@ -128,7 +130,7 @@ public HugeGraph(HugeConfig configuration) { this.name = configuration.get(CoreOptions.STORE); this.closed = false; - this.restoring = false; + this.mode = GraphMode.NONE; try { this.storeProvider = this.loadStoreProvider(); @@ -163,14 +165,12 @@ public boolean closed() { return this.closed && this.tx.closed(); } - @Override - public boolean restoring() { - return this.restoring; + public GraphMode mode() { + return this.mode; } - @Override - public void restoring(boolean restoring) { - this.restoring = restoring; + public void mode(GraphMode mode) { + this.mode = mode; } public EventHub schemaEventHub() { diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/LocalCounter.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/LocalCounter.java index 074a1c61e6..16a7ed32bd 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/LocalCounter.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/LocalCounter.java @@ -35,7 +35,7 @@ public LocalCounter() { this.counters = new ConcurrentHashMap<>(); } - public Id nextId(HugeType type) { + public synchronized Id nextId(HugeType type) { AtomicLong counter = this.counters.get(type); if (counter == null) { counter = new AtomicLong(0); @@ -46,4 +46,30 @@ public Id nextId(HugeType type) { } return IdGenerator.of(counter.incrementAndGet()); } + + public long getCounter(HugeType type) { + AtomicLong counter = this.counters.get(type); + if (counter == null) { + counter = new AtomicLong(0); + AtomicLong previous = this.counters.putIfAbsent(type, counter); + if (previous != null) { + counter = previous; + } + } + return counter.longValue(); + } + + public synchronized void increaseCounter(HugeType type, long increment) { + AtomicLong counter = this.counters.get(type); + if (counter == null) { + counter = new AtomicLong(0); + AtomicLong previous = this.counters.putIfAbsent(type, counter); + if (previous != null) { + counter = previous; + } + } + long oldValue = counter.longValue(); + AtomicLong value = new AtomicLong(oldValue + increment); + this.counters.put(type, value); + } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedBackendStore.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedBackendStore.java index b875027aa2..baad4d8831 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedBackendStore.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedBackendStore.java @@ -111,6 +111,16 @@ public Id nextId(HugeType type) { return this.store.nextId(type); } + @Override + public void increaseCounter(HugeType type, long increment) { + this.store.increaseCounter(type, increment); + } + + @Override + public long getCounter(HugeType type) { + return this.store.getCounter(type); + } + @Override public void mutate(BackendMutation mutation) { // TODO: invalid cache, or set expire time at least diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendStore.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendStore.java index e5e47369af..a217158df6 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendStore.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendStore.java @@ -22,9 +22,11 @@ import java.util.Iterator; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.query.Query; import com.baidu.hugegraph.config.HugeConfig; import com.baidu.hugegraph.type.HugeType; +import com.baidu.hugegraph.util.E; public interface BackendStore { @@ -63,7 +65,47 @@ public interface BackendStore { public BackendFeatures features(); // Generate an id for a specific type - public Id nextId(HugeType type); + public default Id nextId(HugeType type) { + final int MAX_TIMES = 1000; + // Do get-increase-get-compare operation + long counter = 0L; + long expect = -1L; + synchronized(this) { + for (int i = 0; i < MAX_TIMES; i++) { + counter = this.getCounter(type); + + if (counter == expect) { + break; + } + // Increase local counter + expect = counter + 1L; + // Increase remote counter + this.increaseCounter(type, 1L); + } + } + + E.checkState(counter != 0L, "Please check whether '%s' is OK", + this.provider().type()); + E.checkState(counter == expect, "'%s' is busy please try again", + this.provider().type()); + return IdGenerator.of(expect); + } + + // Set next id >= lowest for a specific type + public default void setCounterLowest(HugeType type, long lowest) { + long current = this.getCounter(type); + if (current >= lowest) { + return; + } + long increment = lowest - current; + this.increaseCounter(type, increment); + } + + // Increase next id for specific type + public void increaseCounter(HugeType type, long increment); + + // Get current counter for a specific type + public long getCounter(HugeType type); static enum TxState { BEGIN, COMMITTING, COMMITT_FAIL, ROLLBACKING, ROLLBACK_FAIL, CLEAN diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java index d1d921b9c3..54c0149c27 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java @@ -56,7 +56,7 @@ * 1.remove by id + condition * 2.append/subtract edge-property */ -public class InMemoryDBStore extends AbstractBackendStore { +public abstract class InMemoryDBStore extends AbstractBackendStore { private static final Logger LOG = Log.logger(InMemoryDBStore.class); @@ -66,7 +66,6 @@ public class InMemoryDBStore extends AbstractBackendStore { private final String database; private final Map tables; - private final LocalCounter counter; public InMemoryDBStore(final BackendStoreProvider provider, final String database, final String store) { @@ -74,7 +73,6 @@ public InMemoryDBStore(final BackendStoreProvider provider, this.database = database; this.store = store; this.tables = new HashMap<>(); - this.counter = new LocalCounter(); } @Override @@ -217,11 +215,6 @@ public BackendFeatures features() { return FEATURES; } - @Override - public Id nextId(HugeType type) { - return this.counter.nextId(type); - } - @Override public String toString() { return this.store; @@ -231,9 +224,12 @@ public String toString() { public static class InMemorySchemaStore extends InMemoryDBStore { + private final LocalCounter counter; + public InMemorySchemaStore(BackendStoreProvider provider, String database, String store) { super(provider, database, store); + this.counter = new LocalCounter(); registerTableManager(HugeType.VERTEX_LABEL, new InMemoryDBTable(HugeType.VERTEX_LABEL)); @@ -246,6 +242,21 @@ public InMemorySchemaStore(BackendStoreProvider provider, registerTableManager(HugeType.SECONDARY_INDEX, new InMemoryDBTables.SecondaryIndex()); } + + @Override + public Id nextId(HugeType type) { + return this.counter.nextId(type); + } + + @Override + public void increaseCounter(HugeType type, long increment) { + this.counter.increaseCounter(type, increment); + } + + @Override + public long getCounter(HugeType type) { + return this.counter.getCounter(type); + } } public static class InMemoryGraphStore extends InMemoryDBStore { @@ -267,6 +278,24 @@ public InMemoryGraphStore(BackendStoreProvider provider, registerTableManager(HugeType.SEARCH_INDEX, new InMemoryDBTables.SearchIndex()); } + + @Override + public Id nextId(HugeType type) { + throw new UnsupportedOperationException( + "InMemoryGraphStore.nextId()"); + } + + @Override + public void increaseCounter(HugeType type, long num) { + throw new UnsupportedOperationException( + "InMemoryGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "InMemoryGraphStore.getCounter()"); + } } /** diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphTransaction.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphTransaction.java index 2476e5605b..11f2177032 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphTransaction.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/GraphTransaction.java @@ -411,7 +411,7 @@ public HugeVertex constructVertex(boolean verifyVL, Object... keyValues) { ElementHelper.attachProperties(vertex, keyValues); // Assign vertex id - if (this.graph().restoring() && + if (this.graph().mode().maintaining() && vertexLabel.idStrategy() == IdStrategy.AUTOMATIC) { // Resume id for AUTOMATIC id strategy in restoring mode vertex.assignId(id, true); @@ -1071,7 +1071,7 @@ private void checkId(Id id, List keys, VertexLabel vertexLabel) { vertexLabel.name(), strategy); break; case AUTOMATIC: - if (this.graph().restoring()) { + if (this.graph().mode().maintaining()) { E.checkArgument(id != null && id.number(), "Must customize vertex number id when " + "id strategy is '%s' for vertex label " + diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/SchemaTransaction.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/SchemaTransaction.java index ddebe6417f..f8a90de452 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/SchemaTransaction.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/tx/SchemaTransaction.java @@ -24,15 +24,19 @@ import java.util.List; import java.util.Set; +import org.apache.tinkerpop.gremlin.structure.Graph; + import com.baidu.hugegraph.HugeException; import com.baidu.hugegraph.HugeGraph; import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.query.ConditionQuery; import com.baidu.hugegraph.backend.query.Query; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.BackendStore; import com.baidu.hugegraph.config.CoreOptions; +import com.baidu.hugegraph.exception.ExistedException; import com.baidu.hugegraph.exception.NotAllowException; import com.baidu.hugegraph.job.JobBuilder; import com.baidu.hugegraph.job.schema.EdgeLabelRemoveCallable; @@ -49,6 +53,7 @@ import com.baidu.hugegraph.schema.VertexLabel; import com.baidu.hugegraph.task.HugeTask; import com.baidu.hugegraph.type.HugeType; +import com.baidu.hugegraph.type.define.GraphMode; import com.baidu.hugegraph.type.define.HugeKeys; import com.baidu.hugegraph.type.define.SchemaStatus; import com.baidu.hugegraph.util.E; @@ -328,6 +333,17 @@ public Id getNextId(HugeType type) { return this.store().nextId(type); } + public void setNextIdLowest(HugeType type, long lowest) { + LOG.debug("SchemaTransaction set next id to {} for {}", lowest, type); + this.store().setCounterLowest(type, lowest); + } + + public Id getNextSystemId() { + LOG.debug("SchemaTransaction get next system id"); + Id id = this.store().nextId(HugeType.SYS_SCHEMA); + return IdGenerator.of(-id.asLong()); + } + private BackendEntry serialize(SchemaElement schema) { switch (schema.type()) { case PROPERTY_KEY: @@ -361,6 +377,50 @@ private T deserialize(BackendEntry entry, HugeType type) { } } + public Id validOrGenerateId(HugeType type, Id id, String name) { + boolean forSystem = Graph.Hidden.isHidden(name); + if (id != null) { + this.checkIdAndUpdateNextId(type, id, name, forSystem); + } else { + if (forSystem) { + id = this.getNextSystemId(); + } else { + id = this.getNextId(type); + } + } + return id; + } + + private void checkIdAndUpdateNextId(HugeType type, Id id, + String name, boolean forSystem) { + if (forSystem) { + if (id.number() && id.asLong() < 0) { + return; + } + throw new IllegalStateException(String.format( + "Invalid system id '%s'", id)); + } + HugeGraph graph = this.graph(); + E.checkState(id.number() && id.asLong() > 0L, + "Schema id must be number and >0, but got '%s'", id); + E.checkState(graph.mode() == GraphMode.RESTORING, + "Can't build schema with provided id '%s' " + + "when graph '%s' in mode '%s'", + id, graph, graph.mode()); + this.setNextIdLowest(type, id.asLong()); + } + + public void checkIdIfRestoringMode(HugeType type, Id id) { + if (this.graph().mode() == GraphMode.RESTORING) { + E.checkArgument(id != null, + "Must provide schema id if in RESTORING mode"); + SchemaElement element = this.getSchema(type, id); + if (element != null) { + throw new ExistedException(type.toString() + " id", id); + } + } + } + private static Id asyncRun(HugeGraph graph, HugeType schemaType, Id schemaId, SchemaCallable callable) { return asyncRun(graph, schemaType, schemaId, diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/EdgeLabelBuilder.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/EdgeLabelBuilder.java index 526ef03b07..a3d7f94564 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/EdgeLabelBuilder.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/EdgeLabelBuilder.java @@ -32,6 +32,7 @@ import com.baidu.hugegraph.HugeGraph; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.tx.SchemaTransaction; import com.baidu.hugegraph.exception.ExistedException; import com.baidu.hugegraph.exception.NotAllowException; @@ -48,6 +49,7 @@ public class EdgeLabelBuilder implements EdgeLabel.Builder { + private Id id; private String name; private String sourceLabel; private String targetLabel; @@ -64,6 +66,7 @@ public class EdgeLabelBuilder implements EdgeLabel.Builder { public EdgeLabelBuilder(String name, SchemaTransaction transaction) { E.checkNotNull(name, "name"); E.checkNotNull(transaction, "transaction"); + this.id = null; this.name = name; this.sourceLabel = null; this.targetLabel = null; @@ -77,10 +80,12 @@ public EdgeLabelBuilder(String name, SchemaTransaction transaction) { this.transaction = transaction; } + @Override public EdgeLabel build() { + Id id = this.transaction.validOrGenerateId(HugeType.EDGE_LABEL, + this.id, this.name); HugeGraph graph = this.transaction.graph(); - Id id = this.transaction.getNextId(HugeType.EDGE_LABEL); EdgeLabel edgeLabel = new EdgeLabel(graph, id, this.name); edgeLabel.sourceLabel(this.transaction.getVertexLabel( this.sourceLabel).id()); @@ -109,16 +114,16 @@ public EdgeLabel build() { @Override public EdgeLabel create() { - SchemaElement.checkName(this.name, - this.transaction.graph().configuration()); - - EdgeLabel edgeLabel = this.transaction.getEdgeLabel(this.name); + SchemaTransaction tx = this.transaction; + SchemaElement.checkName(this.name, tx.graph().configuration()); + EdgeLabel edgeLabel = tx.getEdgeLabel(this.name); if (edgeLabel != null) { if (this.checkExist) { throw new ExistedException("edge label", this.name); } return edgeLabel; } + tx.checkIdIfRestoringMode(HugeType.EDGE_LABEL, this.id); if (this.frequency == Frequency.DEFAULT) { this.frequency = Frequency.SINGLE; @@ -131,7 +136,7 @@ public EdgeLabel create() { this.checkNullableKeys(Action.INSERT); edgeLabel = this.build(); - this.transaction.addEdgeLabel(edgeLabel); + tx.addEdgeLabel(edgeLabel); return edgeLabel; } @@ -201,6 +206,13 @@ public Id rebuildIndex() { return this.transaction.rebuildIndex(edgeLabel); } + @Override + public EdgeLabelBuilder id(long id) { + E.checkArgument(id != 0L, "Not allowed to assign 0 as edge label id"); + this.id = IdGenerator.of(id); + return this; + } + @Override public EdgeLabelBuilder properties(String... properties) { this.properties.addAll(Arrays.asList(properties)); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/IndexLabelBuilder.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/IndexLabelBuilder.java index b97c6521f8..95b025d2d3 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/IndexLabelBuilder.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/IndexLabelBuilder.java @@ -28,10 +28,9 @@ import com.baidu.hugegraph.HugeException; import com.baidu.hugegraph.HugeGraph; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.tx.GraphTransaction; import com.baidu.hugegraph.backend.tx.SchemaTransaction; -import com.baidu.hugegraph.config.CoreOptions; -import com.baidu.hugegraph.config.HugeConfig; import com.baidu.hugegraph.exception.ExistedException; import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.schema.EdgeLabel; @@ -52,6 +51,7 @@ public class IndexLabelBuilder implements IndexLabel.Builder { + private Id id; private String name; private HugeType baseType; private String baseValue; @@ -64,6 +64,7 @@ public class IndexLabelBuilder implements IndexLabel.Builder { public IndexLabelBuilder(String name, SchemaTransaction transaction) { E.checkNotNull(name, "name"); E.checkNotNull(transaction, "transaction"); + this.id = null; this.name = name; this.indexType = IndexType.SECONDARY; this.indexFields = new ArrayList<>(); @@ -73,8 +74,9 @@ public IndexLabelBuilder(String name, SchemaTransaction transaction) { @Override public IndexLabel build() { + Id id = this.transaction.validOrGenerateId(HugeType.INDEX_LABEL, + this.id, this.name); HugeGraph graph = this.transaction.graph(); - Id id = this.transaction.getNextId(HugeType.INDEX_LABEL); IndexLabel indexLabel = new IndexLabel(graph, id, this.name); indexLabel.baseType(this.baseType); SchemaLabel schemaLabel = this.loadElement(); @@ -89,15 +91,16 @@ public IndexLabel build() { @Override public IndexLabel.CreatedIndexLabel createWithTask() { - SchemaElement.checkName(this.name, - this.transaction.graph().configuration()); - IndexLabel indexLabel = this.transaction.getIndexLabel(this.name); + SchemaTransaction tx = this.transaction; + SchemaElement.checkName(this.name, tx.graph().configuration()); + IndexLabel indexLabel = tx.getIndexLabel(this.name); if (indexLabel != null) { if (this.checkExist) { throw new ExistedException("index label", this.name); } return new IndexLabel.CreatedIndexLabel(indexLabel, null); } + tx.checkIdIfRestoringMode(HugeType.INDEX_LABEL, this.id); SchemaLabel schemaLabel = this.loadElement(); @@ -115,7 +118,7 @@ public IndexLabel.CreatedIndexLabel createWithTask() { // Create index label indexLabel = this.build(); indexLabel.status(SchemaStatus.CREATING); - this.transaction.addIndexLabel(schemaLabel, indexLabel); + tx.addIndexLabel(schemaLabel, indexLabel); // TODO: use event to replace direct call Id rebuildTask = this.rebuildIndexIfNeeded(schemaLabel, indexLabel, @@ -172,6 +175,14 @@ public Id rebuild() { return this.transaction.rebuildIndex(indexLabel); } + @Override + public IndexLabelBuilder id(long id) { + E.checkArgument(id != 0L, + "Not allowed to assign 0 as index label id"); + this.id = IdGenerator.of(id); + return this; + } + @Override public IndexLabelBuilder onV(String baseValue) { this.baseType = HugeType.VERTEX_LABEL; diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/PropertyKeyBuilder.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/PropertyKeyBuilder.java index 3837df93bd..983b8cb5e4 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/PropertyKeyBuilder.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/PropertyKeyBuilder.java @@ -24,6 +24,7 @@ import com.baidu.hugegraph.HugeGraph; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.tx.SchemaTransaction; import com.baidu.hugegraph.exception.ExistedException; import com.baidu.hugegraph.exception.NotAllowException; @@ -38,6 +39,7 @@ public class PropertyKeyBuilder implements PropertyKey.Builder { + private Id id; private String name; private DataType dataType; private Cardinality cardinality; @@ -49,6 +51,7 @@ public class PropertyKeyBuilder implements PropertyKey.Builder { public PropertyKeyBuilder(String name, SchemaTransaction transaction) { E.checkNotNull(name, "name"); E.checkNotNull(transaction, "transaction"); + this.id = null; this.name = name; this.dataType = DataType.TEXT; this.cardinality = Cardinality.SINGLE; @@ -59,8 +62,9 @@ public PropertyKeyBuilder(String name, SchemaTransaction transaction) { @Override public PropertyKey build() { + Id id = this.transaction.validOrGenerateId(HugeType.PROPERTY_KEY, + this.id, this.name); HugeGraph graph = this.transaction.graph(); - Id id = this.transaction.getNextId(HugeType.PROPERTY_KEY); PropertyKey propertyKey = new PropertyKey(graph, id, this.name); propertyKey.dataType(this.dataType); propertyKey.cardinality(this.cardinality); @@ -72,19 +76,21 @@ public PropertyKey build() { @Override public PropertyKey create() { - SchemaElement.checkName(this.name, - this.transaction.graph().configuration()); - PropertyKey propertyKey = this.transaction.getPropertyKey(this.name); + SchemaTransaction tx = this.transaction; + SchemaElement.checkName(this.name, tx.graph().configuration()); + PropertyKey propertyKey = tx.getPropertyKey(this.name); if (propertyKey != null) { if (this.checkExist) { throw new ExistedException("property key", this.name); } return propertyKey; } + tx.checkIdIfRestoringMode(HugeType.PROPERTY_KEY, this.id); + this.checkUserData(Action.INSERT); propertyKey = this.build(); - this.transaction.addPropertyKey(propertyKey); + tx.addPropertyKey(propertyKey); return propertyKey; } @@ -132,6 +138,14 @@ public Id remove() { return null; } + @Override + public PropertyKeyBuilder id(long id) { + E.checkArgument(id != 0L, + "Not allowed to assign 0 as property key id"); + this.id = IdGenerator.of(id); + return this; + } + @Override public PropertyKeyBuilder asText() { this.dataType = DataType.TEXT; diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/SchemaBuilder.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/SchemaBuilder.java index 3781fb3a51..8f0b74e78f 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/SchemaBuilder.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/SchemaBuilder.java @@ -24,6 +24,8 @@ public interface SchemaBuilder { + public SchemaBuilder id(long id); + public T build(); public T create(); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/VertexLabelBuilder.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/VertexLabelBuilder.java index ab1e6652e1..9dfb7e9666 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/VertexLabelBuilder.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/builder/VertexLabelBuilder.java @@ -32,6 +32,7 @@ import com.baidu.hugegraph.HugeGraph; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.tx.SchemaTransaction; import com.baidu.hugegraph.exception.ExistedException; import com.baidu.hugegraph.exception.NotAllowException; @@ -48,6 +49,7 @@ public class VertexLabelBuilder implements VertexLabel.Builder { + private Id id; private String name; private IdStrategy idStrategy; private Set properties; @@ -62,6 +64,7 @@ public class VertexLabelBuilder implements VertexLabel.Builder { public VertexLabelBuilder(String name, SchemaTransaction transaction) { E.checkNotNull(name, "name"); E.checkNotNull(transaction, "transaction"); + this.id = null; this.name = name; this.idStrategy = IdStrategy.DEFAULT; this.properties = new HashSet<>(); @@ -76,8 +79,9 @@ public VertexLabelBuilder(String name, SchemaTransaction transaction) { @Override public VertexLabel build() { + Id id = this.transaction.validOrGenerateId(HugeType.VERTEX_LABEL, + this.id, this.name); HugeGraph graph = this.transaction.graph(); - Id id = this.transaction.getNextId(HugeType.VERTEX_LABEL); VertexLabel vertexLabel = new VertexLabel(graph, id, this.name); vertexLabel.idStrategy(this.idStrategy); vertexLabel.enableLabelIndex(this.enableLabelIndex == null || @@ -103,15 +107,16 @@ public VertexLabel build() { @Override public VertexLabel create() { - SchemaElement.checkName(this.name, - this.transaction.graph().configuration()); - VertexLabel vertexLabel = this.transaction.getVertexLabel(this.name); + SchemaTransaction tx = this.transaction; + SchemaElement.checkName(this.name, tx.graph().configuration()); + VertexLabel vertexLabel = tx.getVertexLabel(this.name); if (vertexLabel != null) { if (this.checkExist) { throw new ExistedException("vertex label", this.name); } return vertexLabel; } + tx.checkIdIfRestoringMode(HugeType.VERTEX_LABEL, this.id); this.checkProperties(Action.INSERT); this.checkIdStrategy(); @@ -119,7 +124,7 @@ public VertexLabel create() { this.checkUserData(Action.INSERT); vertexLabel = this.build(); - this.transaction.addVertexLabel(vertexLabel); + tx.addVertexLabel(vertexLabel); return vertexLabel; } @@ -190,6 +195,14 @@ public Id rebuildIndex() { return this.transaction.rebuildIndex(vertexLabel); } + @Override + public VertexLabelBuilder id(long id) { + E.checkArgument(id != 0L, + "Not allowed to assign 0 as vertex label id"); + this.id = IdGenerator.of(id); + return this; + } + @Override public VertexLabelBuilder idStrategy(IdStrategy idStrategy) { E.checkArgument(this.idStrategy == IdStrategy.DEFAULT || diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSearchIndex.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSearchIndex.java deleted file mode 100644 index 25a3d3a67d..0000000000 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSearchIndex.java +++ /dev/null @@ -1,56 +0,0 @@ -//package com.baidu.hugegraph.structure; -// -//import java.util.Arrays; -//import java.util.List; -//import java.util.Set; -// -//import com.baidu.hugegraph.backend.id.Id; -//import com.baidu.hugegraph.backend.id.IdGeneratorFactory; -//import com.baidu.hugegraph.type.HugeTypes; -// -///** -// * Created by liningrui on 2017/4/25. -// */ -//public class HugeSearchIndex extends HugeIndex { -// -// private String indexLabelId; -// private List propertyValues; -// private Set elementIds; -// -// public HugeTypes type() { -// return HugeTypes.SEARCH_INDEX; -// } -// -// @Override -// protected Id generateId() { -// return IdGeneratorFactory.generator().generate(this); -// } -// -// public List getPropertyValues() { -// return propertyValues; -// } -// -// public void setPropertyValues(List propertyValues) { -// this.propertyValues = propertyValues; -// } -// -// public String getIndexLabelId() { -// return indexLabelId; -// } -// -// public void setIndexLabelId(String indexLabelId) { -// this.indexLabelId = indexLabelId; -// } -// -// public Set getElementIds() { -// return elementIds; -// } -// -// public void setElementIds(Set elementIds) { -// this.elementIds = elementIds; -// } -// -// public void setElementIds(String... elementIds) { -// this.elementIds.addAll(Arrays.asList(elementIds)); -// } -//} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSecondaryIndex.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSecondaryIndex.java deleted file mode 100644 index 7c270c93f9..0000000000 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/structure/HugeSecondaryIndex.java +++ /dev/null @@ -1,55 +0,0 @@ -//package com.baidu.hugegraph.structure; -// -//import java.util.Arrays; -//import java.util.List; -//import java.util.Set; -// -//import com.baidu.hugegraph.backend.id.Id; -//import com.baidu.hugegraph.backend.id.IdGeneratorFactory; -//import com.baidu.hugegraph.type.HugeTypes; -// -///** -// * Created by liningrui on 2017/4/25. -// */ -//public class HugeSecondaryIndex extends HugeIndex { -// -// private List propertyValues; -// private String indexLabelId; -// private Set elementIds; -// -// public HugeTypes type() { -// return HugeTypes.SECONDARY_INDEX; -// } -// -// protected Id generateId() { -// return IdGeneratorFactory.generator().generate(this); -// } -// -// public List getPropertyValues() { -// return propertyValues; -// } -// -// public void setPropertyValues(List propertyValues) { -// this.propertyValues = propertyValues; -// } -// -// public String getIndexLabelId() { -// return indexLabelId; -// } -// -// public void setIndexLabelId(String indexLabelId) { -// this.indexLabelId = indexLabelId; -// } -// -// public Set getElementIds() { -// return elementIds; -// } -// -// public void setElementIds(Set elementIds) { -// this.elementIds = elementIds; -// } -// -// public void setElementIds(String... elementIds) { -// this.elementIds.addAll(Arrays.asList(elementIds)); -// } -//} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/HugeType.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/HugeType.java index 5db8e7624c..7ffcc09050 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/HugeType.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/HugeType.java @@ -53,6 +53,9 @@ public enum HugeType implements SerialEnum { TASK(180, "T"), + // System schema + SYS_SCHEMA(250, "SS"), + MAX_TYPE(255, "~"); private byte type = 0; diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphMode.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphMode.java new file mode 100644 index 0000000000..846c6d40c2 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphMode.java @@ -0,0 +1,65 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.type.define; + +public enum GraphMode { + + /* + * None mode is regular mode + * 1. Not allowed create schema with specified id + * 2. Not support create vertex with id for AUTOMATIC id strategy + */ + NONE(1, "none"), + + /* + * Restoring mode is used to restore schema and graph data to an new graph. + * 1. Support create schema with specified id + * 2. Support create vertex with id for AUTOMATIC id strategy + */ + RESTORING(2, "restoring"), + + /* + * MERGING mode is used to merge schema and graph data to an existing graph. + * 1. Not allowed create schema with specified id + * 2. Support create vertex with id for AUTOMATIC id strategy + */ + MERGING(3, "merging"); + + private final byte code; + private final String name; + + private GraphMode(int code, String name) { + assert code < 256; + this.code = (byte) code; + this.name = name; + } + + public byte code() { + return this.code; + } + + public String string() { + return this.name; + } + + public boolean maintaining() { + return this == RESTORING || this == MERGING; + } +} diff --git a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java index 8db4972e2f..0db9184494 100644 --- a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java +++ b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java @@ -334,9 +334,16 @@ protected List tableNames() { } @Override - public Id nextId(HugeType type) { + public void increaseCounter(HugeType type, long increment) { super.checkOpened(); - return this.counters.nextId(super.sessions.session(), type); + this.counters.increaseCounter(super.sessions.session(), + type, increment); + } + + @Override + public long getCounter(HugeType type) { + super.checkOpened(); + return this.counters.getCounter(super.sessions.session(), type); } } @@ -367,5 +374,17 @@ public Id nextId(HugeType type) { throw new UnsupportedOperationException( "HbaseGraphStore.nextId()"); } + + @Override + public void increaseCounter(HugeType type, long num) { + throw new UnsupportedOperationException( + "HbaseGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "HbaseGraphStore.getCounter()"); + } } } diff --git a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseTables.java b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseTables.java index 1c8f6c843e..7b6fc7d067 100644 --- a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseTables.java +++ b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseTables.java @@ -30,7 +30,6 @@ import org.apache.hadoop.hbase.util.Bytes; import com.baidu.hugegraph.backend.id.Id; -import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.query.Condition; import com.baidu.hugegraph.backend.query.Condition.Relation; import com.baidu.hugegraph.backend.query.ConditionQuery; @@ -42,6 +41,7 @@ import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.type.define.HugeKeys; import com.baidu.hugegraph.util.E; +import com.baidu.hugegraph.util.NumericUtil; public class HbaseTables { @@ -54,10 +54,21 @@ public Counters() { super(TABLE); } - public synchronized Id nextId(Session session, HugeType type) { + public long getCounter(Session session, HugeType type) { byte[] key = new byte[]{type.code()}; - long counter = session.increase(this.table(), CF, key, COL, 1L); - return IdGenerator.of(counter); + RowIterator results = session.get(this.table(), CF, key); + if (results.hasNext()) { + Result row = results.next(); + return NumericUtil.bytesToLong(row.getValue(CF, COL)); + } else { + return 0L; + } + } + + public void increaseCounter(Session session, HugeType type, + long increment) { + byte[] key = new byte[]{type.code()}; + session.increase(this.table(), CF, key, COL, increment); } } diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java index 5fab742c0c..5884829fb9 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java @@ -356,10 +356,17 @@ protected void clearTables() { } @Override - public Id nextId(HugeType type) { + public void increaseCounter(HugeType type, long increment) { + this.checkSessionConnected(); + MysqlSessions.Session session = super.sessions.session(); + this.counters.increaseCounter(session, type, increment); + } + + @Override + public long getCounter(HugeType type) { this.checkSessionConnected(); MysqlSessions.Session session = super.sessions.session(); - return this.counters.nextId(session, type); + return this.counters.getCounter(session, type); } } @@ -389,5 +396,17 @@ public MysqlGraphStore(BackendStoreProvider provider, public Id nextId(HugeType type) { throw new UnsupportedOperationException("MysqlGraphStore.nextId()"); } + + @Override + public void increaseCounter(HugeType type, long num) { + throw new UnsupportedOperationException( + "MysqlGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "MysqlGraphStore.getCounter()"); + } } } diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java index 118bece88c..b0d1e65b5e 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java @@ -72,8 +72,6 @@ public static class Counters extends MysqlTableTemplate { public static final String TABLE = "counters"; - public static final int MAX_TIMES = 10; - public Counters() { super(TABLE); @@ -83,55 +81,38 @@ public Counters() { this.define.keys(HugeKeys.SCHEMA_TYPE); } - public synchronized Id nextId(MysqlSessions.Session session, - HugeType type) { - + public long getCounter(MysqlSessions.Session session, HugeType type) { String schemaCol = formatKey(HugeKeys.SCHEMA_TYPE); String idCol = formatKey(HugeKeys.ID); String select = String.format("SELECT ID FROM %s WHERE %s = '%s';", TABLE, schemaCol, type.name()); - /* - * If the current schema record does not exist then insert, - * otherwise update it. - */ - String update = String.format("INSERT INTO %s VALUES ('%s', 1) " + - "ON DUPLICATE KEY UPDATE " + - "ID = ID + 1;", TABLE, type.name()); - - // Do get-increase-get-compare operation - long counter = 0L; - long expect = -1L; - - for (int i = 0; i < MAX_TIMES; i++) { - try { - ResultSet resultSet = session.select(select); - if (resultSet.next()) { - counter = resultSet.getLong(idCol); - } - } catch (SQLException e) { - throw new BackendException("Failed to get id from " + - "counters with schema type '%s'", - e, type); - } - - if (counter == expect) { - break; - } - // Increase local counter - expect = counter + 1L; - // Increase remote counter - try { - session.execute(update); - } catch (SQLException e) { - throw new BackendException("Failed to update counter " + - "for schema type '%s'", e, type); + try { + ResultSet resultSet = session.select(select); + if (resultSet.next()) { + return resultSet.getLong(idCol); + } else { + return 0L; } + } catch (SQLException e) { + throw new BackendException( + "Failed to get id from counters with type '%s'", + e, type); } + } - E.checkState(counter != 0L, "Please check whether MySQL is OK"); - E.checkState(counter == expect, "MySQL is busy please try again"); - return IdGenerator.of(expect); + public void increaseCounter(MysqlSessions.Session session, + HugeType type, long increment) { + String update = String.format( + "INSERT INTO %s VALUES ('%s', %s) " + + "ON DUPLICATE KEY UPDATE " + + "ID = ID + 1;", TABLE, type.name(), increment); + try { + session.execute(update); + } catch (SQLException e) { + throw new BackendException("Failed to update counters " + + "with '%s'", e, update); + } } } diff --git a/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloStoreProvider.java b/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloStoreProvider.java index 4563cb68c6..4db19d3614 100644 --- a/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloStoreProvider.java +++ b/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloStoreProvider.java @@ -86,6 +86,17 @@ public BackendFeatures features() { public Id nextId(HugeType type) { return this.counter.nextId(type); } + + @Override + public void increaseCounter(HugeType type, long increment) { + this.counter.increaseCounter(type, increment); + } + + @Override + public long getCounter(HugeType type) { + return this.counter.getCounter(type); + } + } public static class PaloGraphStore extends PaloStore { @@ -117,5 +128,17 @@ public BackendFeatures features() { public Id nextId(HugeType type) { throw new UnsupportedOperationException("PaloGraphStore.nextId()"); } + + @Override + public void increaseCounter(HugeType type, long num) { + throw new UnsupportedOperationException( + "PaloGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "PaloGraphStore.getCounter()"); + } } } diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java index 1500e8d6d1..55744d2406 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java @@ -59,6 +59,7 @@ public static abstract class Session extends BackendSession { public abstract void put(String table, byte[] key, byte[] value); public abstract void merge(String table, byte[] key, byte[] value); + public abstract void increase(String table, byte[] key, byte[] value); public abstract void remove(String table, byte[] key); public abstract void delete(String table, byte[] keyFrom, byte[] keyTo); diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java index 16f64462c9..127cfd18a3 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java @@ -350,7 +350,7 @@ public static final String decode(byte[] bytes) { return StringEncoding.decode(bytes); } - public static final byte[] increase(byte[] bytes) { + public static final byte[] increaseOne(byte[] bytes) { final byte BYTE_MAX_VALUE = (byte) 0xff; assert bytes.length > 0; byte last = bytes[bytes.length - 1]; @@ -484,6 +484,18 @@ public void merge(String table, byte[] key, byte[] value) { this.batch.merge(cf(table), key, value); } + /** + * Merge a record to an existing key to a table and commit immediately + */ + @Override + public void increase(String table, byte[] key, byte[] value) { + try { + rocksdb().merge(cf(table), key, value); + } catch (RocksDBException e) { + throw new BackendException(e); + } + } + /** * Delete a record by key from a table */ @@ -499,7 +511,7 @@ public void remove(String table, byte[] key) { public void delete(String table, byte[] key) { byte[] keyFrom = key; byte[] keyTo = Arrays.copyOf(key, key.length); - keyTo = increase(keyTo); + keyTo = increaseOne(keyTo); this.batch.deleteRange(cf(table), keyFrom, keyTo); } diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java index d78fddfe5c..64ebd2e9ee 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java @@ -503,10 +503,17 @@ protected List tableNames() { } @Override - public Id nextId(HugeType type) { + public void increaseCounter(HugeType type, long increment) { super.checkOpened(); Session session = super.sessions.session(); - return this.counters.nextId(session, type); + this.counters.increaseCounter(session, type, increment); + } + + @Override + public long getCounter(HugeType type) { + super.checkOpened(); + Session session = super.sessions.session(); + return this.counters.getCounter(session, type); } } @@ -537,5 +544,17 @@ public Id nextId(HugeType type) { throw new UnsupportedOperationException( "RocksDBGraphStore.nextId()"); } + + @Override + public void increaseCounter(HugeType type, long num) { + throw new UnsupportedOperationException( + "RocksDBGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "RocksDBGraphStore.getCounter()"); + } } } diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBTables.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBTables.java index 610dd61336..300bb46ade 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBTables.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBTables.java @@ -41,38 +41,24 @@ public static class Counters extends RocksDBTable { private static final String TABLE = "c"; - private static final int MAX_TIMES = 1000; - private static final byte[] ONE = b(1L); - public Counters(String database) { super(database, TABLE); } - public synchronized Id nextId(Session session, HugeType type) { + public long getCounter(Session session, HugeType type) { byte[] key = new byte[]{type.code()}; - - // Do get-increase-get-compare operation - long counter = 0L; - long expect = -1L; - for (int i = 0; i < MAX_TIMES; i++) { - // Get the latest value - byte[] value = session.get(this.table(), key); - if (value != null) { - counter = l(value); - } - if (counter == expect) { - break; - } - // Increase local counter - expect = counter + 1L; - // Increase 1, the default value of counter is 0 in RocksDB - session.merge(this.table(), key, ONE); - session.commit(); + byte[] value = session.get(this.table(), key); + if (value != null) { + return l(value); + } else { + return 0L; } + } - E.checkState(counter != 0L, "Please check whether RocksDB is OK"); - E.checkState(counter == expect, "RocksDB is busy please try again"); - return IdGenerator.of(counter); + public void increaseCounter(Session session, HugeType type, + long increment) { + byte[] key = new byte[]{type.code()}; + session.increase(this.table(), key, b(increment)); } private static byte[] b(long value) { @@ -234,7 +220,7 @@ protected BackendColumnIterator queryByCond(Session session, E.checkArgumentNotNull(min, "Range index begin key is missing"); byte[] begin = min.asBytes(); if (!minEq) { - begin = RocksDBStdSessions.increase(begin); + begin = RocksDBStdSessions.increaseOne(begin); } if (max == null) { diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java index 0deecbd3cf..5ac476b901 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java @@ -256,6 +256,14 @@ public void merge(String table, byte[] key, byte[] value) { throw new NotSupportException("RocksDBSstStore merge()"); } + /** + * Merge a record to an existing key to a table and commit immediately + */ + @Override + public void increase(String table, byte[] key, byte[] value) { + throw new NotSupportException("RocksDBSstStore increase()"); + } + /** * Delete a record by key from a table */ diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java index 8709a2aad8..83453e692b 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstStore.java @@ -79,5 +79,17 @@ public Id nextId(HugeType type) { throw new UnsupportedOperationException( "RocksDBSstGraphStore.nextId()"); } + + @Override + public void increaseCounter(HugeType type, long increment) { + throw new UnsupportedOperationException( + "RocksDBSstGraphStore.increaseCounter()"); + } + + @Override + public long getCounter(HugeType type) { + throw new UnsupportedOperationException( + "RocksDBSstGraphStore.getCounter()"); + } } } diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/CoreTestSuite.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/CoreTestSuite.java index aec80f8da7..85da8b9906 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/CoreTestSuite.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/CoreTestSuite.java @@ -43,7 +43,8 @@ VertexCoreTest.class, EdgeCoreTest.class, VertexPropertyCoreTest.class, - EdgePropertyCoreTest.class + EdgePropertyCoreTest.class, + RestoreCoreTest.class }) public class CoreTestSuite { diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RestoreCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RestoreCoreTest.java new file mode 100644 index 0000000000..f9313f481e --- /dev/null +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RestoreCoreTest.java @@ -0,0 +1,727 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.core; + +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.After; +import org.junit.Test; + +import com.baidu.hugegraph.HugeGraph; +import com.baidu.hugegraph.exception.ExistedException; +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.type.define.IdStrategy; + +public class RestoreCoreTest extends BaseCoreTest { + + @After + public void teardown() throws Exception { + super.teardown(); + graph().mode(GraphMode.NONE); + } + + @Test + public void testCreateVertexLabelWithId0InNoneMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().vertexLabel("person").id(0L).create() + ); + } + + @Test + public void testCreateVertexLabelWithId0InMergingMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().vertexLabel("person").id(0L).create() + ); + } + + @Test + public void testCreateVertexLabelWithId0InRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().vertexLabel("person").id(0L).create() + ); + } + + @Test + public void testCreateVertexLabelWithNegativeIdInNoneMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().vertexLabel("person").id(-100L).create() + ); + } + + @Test + public void testCreateVertexLabelWithNegativeIdInMergingMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().vertexLabel("person").id(-100L).create() + ); + } + + @Test + public void testCreateVertexLabelWithNegativeIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().vertexLabel("person").id(-100L).create() + ); + } + + @Test + public void testCreateVertexLabelWithPositiveIdInNoneMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().vertexLabel("person").id(100L).create() + ); + } + + @Test + public void testCreateVertexLabelWithPositiveIdInMergingMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().vertexLabel("person").id(100L).create() + ); + } + + @Test + public void testCreateVertexLabelWithPositiveIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().vertexLabel("person").id(100L).create(); + } + + @Test + public void testCreateVertexLabelWithNonExistNameAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().vertexLabel("non-exist").id(100000L).create(); + } + + @Test + public void testCreateVertexLabelWithNameExistWithIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().vertexLabel("person").id(100L).create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().vertexLabel("person").id(100L).create() + ); + } + + @Test + public void testCreateVertexLabelWithIdExistInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().vertexLabel("person").id(100L).create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().vertexLabel("person1").id(100L).create() + ); + } + + @Test + public void testCreateSystemVertexLabelWith0Id() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().vertexLabel("~person").id(0L).create() + ); + } + + @Test + public void testCreateSystemVertexLabelWithPositiveId() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().vertexLabel("~person").id(100L).build() + ); + } + + @Test + public void testCreateSystemVertexLabelWithNegativeId() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().vertexLabel("~person").id(-100L).build(); + } + + @Test + public void testCreateVertexWithAutomaticStrategyAndIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.AUTOMATIC).create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.addVertex(T.label, "person", T.id, 100L) + ); + } + + @Test + public void testCreateVertexWithAutomaticStrategyAndIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.AUTOMATIC).create(); + graph.mode(GraphMode.MERGING); + graph.addVertex(T.label, "person", T.id, 100L); + } + + @Test + public void testCreateVertexWithAutomaticStrategyAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.AUTOMATIC).create(); + graph.mode(GraphMode.RESTORING); + graph.addVertex(T.label, "person", T.id, 100L); + } + + @Test + public void testCreateVertexWithPrimaryKeyStrategyAndIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().vertexLabel("person").properties("name") + .idStrategy(IdStrategy.PRIMARY_KEY).primaryKeys("name").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.addVertex(T.label, "person", T.id, 100L, "name", "Tom") + ); + } + + @Test + public void testCreateVertexWithPrimaryKeyStrategyAndIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().vertexLabel("person").properties("name") + .idStrategy(IdStrategy.PRIMARY_KEY).primaryKeys("name").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.addVertex(T.label, "person", T.id, 100L, "name", "Tom") + ); + } + + @Test + public void testCreateVertexWithPrimaryKeyStrategyAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().vertexLabel("person").properties("name") + .idStrategy(IdStrategy.PRIMARY_KEY).primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.addVertex(T.label, "person", T.id, 100L, "name", "Tom") + ); + } + + @Test + public void testCreateVertexWithCustomizeStrategyAndIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.CUSTOMIZE_NUMBER).create(); + graph.mode(GraphMode.NONE); + graph.addVertex(T.label, "person", T.id, 100L); + } + + @Test + public void testCreateVertexWithCustomizeStrategyAndIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.CUSTOMIZE_NUMBER).create(); + graph.mode(GraphMode.MERGING); + graph.addVertex(T.label, "person", T.id, 100L); + } + + @Test + public void testCreateVertexWithCustomizeStrategyAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.CUSTOMIZE_NUMBER).create(); + graph.mode(GraphMode.RESTORING); + graph.addVertex(T.label, "person", T.id, 100L); + } + + @Test + public void testCreateEdgeLabelWithId0InNoneMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(0L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithId0InMergingMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(0L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithId0InRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(0L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithNegativeIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(-100L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithNegativeIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(-100L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithNegativeIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(-100L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithPositiveIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(100L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithPositiveIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(100L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithPositiveIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(100L) + .create(); + } + + @Test + public void testCreateEdgeLabelWithNonExistNameAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().edgeLabel("non-exist").sourceLabel("person") + .targetLabel("person").id(100000L) + .create(); + } + + @Test + public void testCreateEdgeLabelWithNameExistWithIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(100L) + .create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(100L) + .create() + ); + } + + @Test + public void testCreateEdgeLabelWithIdExistInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().vertexLabel("person").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").id(100L) + .create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().edgeLabel("knows1").sourceLabel("person") + .targetLabel("person").id(100L) + .create() + ); + } + + @Test + public void testCreateEdgeWithIdInAllMode() { + HugeGraph graph = graph(); + + graph.schema().vertexLabel("person") + .idStrategy(IdStrategy.AUTOMATIC).create(); + graph.schema().edgeLabel("knows").sourceLabel("person") + .targetLabel("person").create(); + Vertex v1 = graph.addVertex(T.label, "person"); + Vertex v2 = graph.addVertex(T.label, "person"); + + graph.mode(GraphMode.NONE); + Assert.assertThrows(UnsupportedOperationException.class, () -> + v1.addEdge("knows", v2, T.id, "id") + ); + + graph.mode(GraphMode.MERGING); + Assert.assertThrows(UnsupportedOperationException.class, () -> + v1.addEdge("knows", v2, T.id, "id") + ); + + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(UnsupportedOperationException.class, () -> + v1.addEdge("knows", v2, T.id, "id") + ); + } + + @Test + public void testCreatePropertyKeyWithId0InNoneMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().propertyKey("name").id(0L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithId0InMergingMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().propertyKey("name").id(0L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithId0InRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().propertyKey("name").id(0L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithNegativeIdInNoneMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().propertyKey("name").id(-100L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithNegativeIdInMergingMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().propertyKey("name").id(-100L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithNegativeIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().propertyKey("name").id(-100L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithPositiveIdInNoneMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().propertyKey("name").id(100L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithPositiveIdInMergingMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().propertyKey("name").id(100L).create() + + ); + } + + @Test + public void testCreatePropertyKeyWithPositiveIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().propertyKey("name").id(100L).create(); + } + + @Test + public void testCreatePropertyKeyWithNonExistNameAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().propertyKey("non-exist").id(100000L).create(); + + } + + @Test + public void testCreatePropertyKeyWithNameExistWithIdInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().propertyKey("name").id(100L).create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().propertyKey("name").id(1000L).create() + ); + } + + @Test + public void testCreatePropertyKeyWithIdExistInRestoringMode() { + HugeGraph graph = graph(); + graph.mode(GraphMode.RESTORING); + graph.schema().propertyKey("name").id(100L).create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().propertyKey("name1").id(100L).create() + ); + } + + @Test + public void testCreateIndexLabelWithId0InNoneMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(0L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithId0InMergingMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(0L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithId0InRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalArgumentException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(0L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithNegativeIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(-100L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithNegativeIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(-100L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithNegativeIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(-100L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithPositiveIdInNoneMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.NONE); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(100L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithPositiveIdInMergingMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.MERGING); + Assert.assertThrows(IllegalStateException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(100L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithPositiveIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(100L) + .create(); + } + + @Test + public void testCreateIndexLabelWithNonExistNameAndIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().indexLabel("non-exist") + .onV("person").by("city").secondary().id(10000L) + .create(); + } + + @Test + public void testCreateIndexLabelWithNameExistWithIdInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(100L) + .create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(100L) + .create() + ); + } + + @Test + public void testCreateIndexLabelWithIdExistInRestoringMode() { + HugeGraph graph = graph(); + graph.schema().propertyKey("name").create(); + graph.schema().propertyKey("city").create(); + graph.schema().vertexLabel("person").properties("name", "city") + .primaryKeys("name").create(); + graph.mode(GraphMode.RESTORING); + graph.schema().indexLabel("personByCity") + .onV("person").by("city").secondary().id(100L) + .create(); + Assert.assertThrows(ExistedException.class, () -> + graph.schema().indexLabel("personByCity1") + .onV("person").by("city").secondary().id(100L) + .create() + ); + } + +} diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/rocksdb/RocksDBCountersTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/rocksdb/RocksDBCountersTest.java index e12fccf363..9767ceeca9 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/rocksdb/RocksDBCountersTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/rocksdb/RocksDBCountersTest.java @@ -28,6 +28,7 @@ import org.rocksdb.RocksDBException; import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.backend.store.rocksdb.RocksDBSessions.Session; import com.baidu.hugegraph.backend.store.rocksdb.RocksDBTables; import com.baidu.hugegraph.testutil.Assert; @@ -52,8 +53,9 @@ public void setup() throws RocksDBException { public void testCounter() throws RocksDBException { Session session = this.rocks.session(); for (int i = 1; i < 10000; i++) { - Id id = this.counters.nextId(session, HugeType.PROPERTY_KEY); - Assert.assertEquals(i, id.asLong()); + this.counters.increaseCounter(session, HugeType.PROPERTY_KEY, 1L); + long id = this.counters.getCounter(session, HugeType.PROPERTY_KEY); + Assert.assertEquals(i, id); } } @@ -61,17 +63,21 @@ public void testCounter() throws RocksDBException { public void testCounterWithMultiTypes() throws RocksDBException { Session session = this.rocks.session(); for (int i = 1; i < 1000; i++) { - Id id = this.counters.nextId(session, HugeType.PROPERTY_KEY); - Assert.assertEquals(i, id.asLong()); + this.counters.increaseCounter(session, HugeType.PROPERTY_KEY, 1L); + long id = this.counters.getCounter(session, HugeType.PROPERTY_KEY); + Assert.assertEquals(i, id); - id = this.counters.nextId(session, HugeType.VERTEX_LABEL); - Assert.assertEquals(i, id.asLong()); + this.counters.increaseCounter(session, HugeType.VERTEX_LABEL, 1L); + id = this.counters.getCounter(session, HugeType.VERTEX_LABEL); + Assert.assertEquals(i, id); - id = this.counters.nextId(session, HugeType.EDGE_LABEL); - Assert.assertEquals(i, id.asLong()); + this.counters.increaseCounter(session, HugeType.EDGE_LABEL, 1L); + id = this.counters.getCounter(session, HugeType.EDGE_LABEL); + Assert.assertEquals(i, id); - id = this.counters.nextId(session, HugeType.INDEX_LABEL); - Assert.assertEquals(i, id.asLong()); + this.counters.increaseCounter(session, HugeType.INDEX_LABEL, 1L); + id = this.counters.getCounter(session, HugeType.INDEX_LABEL); + Assert.assertEquals(i, id); } } @@ -86,7 +92,7 @@ public void testCounterWithMutiThreads() { Session session = this.rocks.session(); for (int i = 0; i < TIMES; i++) { - Id id = this.counters.nextId(session, HugeType.PROPERTY_KEY); + Id id = nextId(session, HugeType.PROPERTY_KEY); Assert.assertFalse(ids.containsKey(id)); ids.put(id, true); @@ -96,4 +102,25 @@ public void testCounterWithMutiThreads() { }); Assert.assertEquals(THREADS_NUM * TIMES, times.get()); } + + private Id nextId(Session session, HugeType type) { + final int MAX_TIMES = 1000; + // Do get-increase-get-compare operation + long counter = 0L; + long expect = -1L; + synchronized(this) { + for (int i = 0; i < MAX_TIMES; i++) { + counter = this.counters.getCounter(session, type); + + if (counter == expect) { + break; + } + // Increase local counter + expect = counter + 1L; + // Increase remote counter + this.counters.increaseCounter(session, type, 1L); + } + } + return IdGenerator.of(expect); + } }