forked from hugegraph/hugegraph
hugegraph-1379 support restore graph in restoring mode and merging mode
implement: #182 Change-Id: I7c2c85435af01c5d27279076d0473685b8f23f34
This commit is contained in:
parent
2c356c8a1e
commit
255df7e945
|
|
@ -101,7 +101,7 @@
|
|||
</addDefaultSpecificationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Implementation-Version>0.30.0.0</Implementation-Version>
|
||||
<Implementation-Version>0.31.0.0</Implementation-Version>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
|
|
|
|||
|
|
@ -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.HugeGraph;
|
|||
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 class GraphsAPI extends API {
|
|||
|
||||
@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<String, GraphMode> 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<String, GraphMode> 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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import com.baidu.hugegraph.backend.id.Id;
|
|||
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 class EdgeLabelAPI extends API {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import com.baidu.hugegraph.backend.id.Id;
|
|||
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 class IndexLabelAPI extends API {
|
|||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import com.baidu.hugegraph.core.GraphManager;
|
|||
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 class PropertyKeyAPI extends API {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import com.baidu.hugegraph.api.filter.StatusFilter.Status;
|
|||
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 class VertexLabelAPI extends API {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,18 +178,6 @@ public class HugeGraphAuthProxy implements GremlinGraph {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -488,10 +488,17 @@ public abstract class CassandraStore extends AbstractBackendStore {
|
|||
}
|
||||
|
||||
@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 abstract class CassandraStore extends AbstractBackendStore {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,8 +65,6 @@ public class CassandraTables {
|
|||
|
||||
public static final String TABLE = "counters";
|
||||
|
||||
public static final int MAX_TIMES = 1000;
|
||||
|
||||
public Counters() {
|
||||
super(TABLE);
|
||||
}
|
||||
|
|
@ -84,40 +82,26 @@ public class CassandraTables {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,10 +66,12 @@ import com.baidu.hugegraph.task.TaskManager;
|
|||
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 class HugeGraph implements GremlinGraph {
|
|||
|
||||
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 class HugeGraph implements GremlinGraph {
|
|||
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() {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class 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 class LocalCounter {
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,16 @@ public class CachedBackendStore implements BackendStore {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@ package com.baidu.hugegraph.backend.store;
|
|||
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
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ import com.baidu.hugegraph.util.Log;
|
|||
* 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<HugeType, InMemoryDBTable> tables;
|
||||
private final LocalCounter counter;
|
||||
|
||||
public InMemoryDBStore(final BackendStoreProvider provider,
|
||||
final String database, final String store) {
|
||||
|
|
@ -74,7 +73,6 @@ public class InMemoryDBStore extends AbstractBackendStore {
|
|||
this.database = database;
|
||||
this.store = store;
|
||||
this.tables = new HashMap<>();
|
||||
this.counter = new LocalCounter();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -217,11 +215,6 @@ public class InMemoryDBStore extends AbstractBackendStore {
|
|||
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 class InMemoryDBStore extends AbstractBackendStore {
|
|||
|
||||
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 class InMemoryDBStore extends AbstractBackendStore {
|
|||
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 class InMemoryDBStore extends AbstractBackendStore {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ public class GraphTransaction extends IndexableTransaction {
|
|||
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 @@ public class GraphTransaction extends IndexableTransaction {
|
|||
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 " +
|
||||
|
|
|
|||
|
|
@ -24,15 +24,19 @@ import java.util.Iterator;
|
|||
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.SchemaLabel;
|
|||
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 class SchemaTransaction extends IndexableTransaction {
|
|||
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 @@ public class SchemaTransaction extends IndexableTransaction {
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
|
||||
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 @@ import com.google.common.collect.ImmutableList;
|
|||
|
||||
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 class EdgeLabelBuilder implements EdgeLabel.Builder {
|
|||
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 class EdgeLabelBuilder implements EdgeLabel.Builder {
|
|||
|
||||
@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 class EdgeLabelBuilder implements EdgeLabel.Builder {
|
|||
this.checkNullableKeys(Action.INSERT);
|
||||
|
||||
edgeLabel = this.build();
|
||||
this.transaction.addEdgeLabel(edgeLabel);
|
||||
tx.addEdgeLabel(edgeLabel);
|
||||
return edgeLabel;
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +206,13 @@ public class EdgeLabelBuilder implements EdgeLabel.Builder {
|
|||
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));
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@ import java.util.concurrent.TimeoutException;
|
|||
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 @@ import com.baidu.hugegraph.util.InsertionOrderUtil;
|
|||
|
||||
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 class IndexLabelBuilder implements IndexLabel.Builder {
|
|||
|
||||
@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 class IndexLabelBuilder implements IndexLabel.Builder {
|
|||
|
||||
@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 class IndexLabelBuilder implements IndexLabel.Builder {
|
|||
// 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 class IndexLabelBuilder implements IndexLabel.Builder {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.Map;
|
|||
|
||||
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 @@ import com.baidu.hugegraph.util.E;
|
|||
|
||||
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 class PropertyKeyBuilder implements PropertyKey.Builder {
|
|||
|
||||
@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 class PropertyKeyBuilder implements PropertyKey.Builder {
|
|||
|
||||
@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 class PropertyKeyBuilder implements PropertyKey.Builder {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import com.baidu.hugegraph.schema.SchemaElement;
|
|||
|
||||
public interface SchemaBuilder<T extends SchemaElement> {
|
||||
|
||||
public SchemaBuilder<T> id(long id);
|
||||
|
||||
public T build();
|
||||
|
||||
public T create();
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
|
||||
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 @@ import com.google.common.collect.ImmutableList;
|
|||
|
||||
public class VertexLabelBuilder implements VertexLabel.Builder {
|
||||
|
||||
private Id id;
|
||||
private String name;
|
||||
private IdStrategy idStrategy;
|
||||
private Set<String> 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 class VertexLabelBuilder implements VertexLabel.Builder {
|
|||
|
||||
@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 class VertexLabelBuilder implements VertexLabel.Builder {
|
|||
|
||||
@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 class VertexLabelBuilder implements VertexLabel.Builder {
|
|||
this.checkUserData(Action.INSERT);
|
||||
|
||||
vertexLabel = this.build();
|
||||
this.transaction.addVertexLabel(vertexLabel);
|
||||
tx.addVertexLabel(vertexLabel);
|
||||
return vertexLabel;
|
||||
}
|
||||
|
||||
|
|
@ -190,6 +195,14 @@ public class VertexLabelBuilder implements VertexLabel.Builder {
|
|||
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 ||
|
||||
|
|
|
|||
|
|
@ -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<String> propertyValues;
|
||||
// private Set<String> elementIds;
|
||||
//
|
||||
// public HugeTypes type() {
|
||||
// return HugeTypes.SEARCH_INDEX;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected Id generateId() {
|
||||
// return IdGeneratorFactory.generator().generate(this);
|
||||
// }
|
||||
//
|
||||
// public List<String> getPropertyValues() {
|
||||
// return propertyValues;
|
||||
// }
|
||||
//
|
||||
// public void setPropertyValues(List<String> propertyValues) {
|
||||
// this.propertyValues = propertyValues;
|
||||
// }
|
||||
//
|
||||
// public String getIndexLabelId() {
|
||||
// return indexLabelId;
|
||||
// }
|
||||
//
|
||||
// public void setIndexLabelId(String indexLabelId) {
|
||||
// this.indexLabelId = indexLabelId;
|
||||
// }
|
||||
//
|
||||
// public Set<String> getElementIds() {
|
||||
// return elementIds;
|
||||
// }
|
||||
//
|
||||
// public void setElementIds(Set<String> elementIds) {
|
||||
// this.elementIds = elementIds;
|
||||
// }
|
||||
//
|
||||
// public void setElementIds(String... elementIds) {
|
||||
// this.elementIds.addAll(Arrays.asList(elementIds));
|
||||
// }
|
||||
//}
|
||||
|
|
@ -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<String> propertyValues;
|
||||
// private String indexLabelId;
|
||||
// private Set<String> elementIds;
|
||||
//
|
||||
// public HugeTypes type() {
|
||||
// return HugeTypes.SECONDARY_INDEX;
|
||||
// }
|
||||
//
|
||||
// protected Id generateId() {
|
||||
// return IdGeneratorFactory.generator().generate(this);
|
||||
// }
|
||||
//
|
||||
// public List<String> getPropertyValues() {
|
||||
// return propertyValues;
|
||||
// }
|
||||
//
|
||||
// public void setPropertyValues(List<String> propertyValues) {
|
||||
// this.propertyValues = propertyValues;
|
||||
// }
|
||||
//
|
||||
// public String getIndexLabelId() {
|
||||
// return indexLabelId;
|
||||
// }
|
||||
//
|
||||
// public void setIndexLabelId(String indexLabelId) {
|
||||
// this.indexLabelId = indexLabelId;
|
||||
// }
|
||||
//
|
||||
// public Set<String> getElementIds() {
|
||||
// return elementIds;
|
||||
// }
|
||||
//
|
||||
// public void setElementIds(Set<String> elementIds) {
|
||||
// this.elementIds = elementIds;
|
||||
// }
|
||||
//
|
||||
// public void setElementIds(String... elementIds) {
|
||||
// this.elementIds.addAll(Arrays.asList(elementIds));
|
||||
// }
|
||||
//}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -334,9 +334,16 @@ public abstract class HbaseStore extends AbstractBackendStore {
|
|||
}
|
||||
|
||||
@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 abstract class HbaseStore extends AbstractBackendStore {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import org.apache.hadoop.hbase.client.Result;
|
|||
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.backend.store.hbase.HbaseSessions.Session;
|
|||
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 class HbaseTables {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -356,10 +356,17 @@ public abstract class MysqlStore extends AbstractBackendStore {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Id nextId(HugeType type) {
|
||||
public void increaseCounter(HugeType type, long increment) {
|
||||
this.checkSessionConnected();
|
||||
MysqlSessions.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();
|
||||
MysqlSessions.Session session = super.sessions.session();
|
||||
return this.counters.getCounter(session, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -389,5 +396,17 @@ public abstract class MysqlStore extends AbstractBackendStore {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ public class MysqlTables {
|
|||
|
||||
public static final String TABLE = "counters";
|
||||
|
||||
public static final int MAX_TIMES = 10;
|
||||
|
||||
public Counters() {
|
||||
super(TABLE);
|
||||
|
||||
|
|
@ -83,55 +81,38 @@ public class MysqlTables {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,17 @@ public class PaloStoreProvider extends MysqlStoreProvider {
|
|||
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 class PaloStoreProvider extends MysqlStoreProvider {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public abstract class RocksDBSessions extends BackendSessionPool {
|
|||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ public class RocksDBStdSessions extends RocksDBSessions {
|
|||
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 class RocksDBStdSessions extends RocksDBSessions {
|
|||
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 class RocksDBStdSessions extends RocksDBSessions {
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -503,10 +503,17 @@ public abstract class RocksDBStore extends AbstractBackendStore {
|
|||
}
|
||||
|
||||
@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 abstract class RocksDBStore extends AbstractBackendStore {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,38 +41,24 @@ public class RocksDBTables {
|
|||
|
||||
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 @@ public class RocksDBTables {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -256,6 +256,14 @@ public class RocksDBSstSessions extends RocksDBSessions {
|
|||
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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -79,5 +79,17 @@ public abstract class RocksDBSstStore extends RocksDBStore {
|
|||
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()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ import com.baidu.hugegraph.util.Log;
|
|||
VertexCoreTest.class,
|
||||
EdgeCoreTest.class,
|
||||
VertexPropertyCoreTest.class,
|
||||
EdgePropertyCoreTest.class
|
||||
EdgePropertyCoreTest.class,
|
||||
RestoreCoreTest.class
|
||||
})
|
||||
public class CoreTestSuite {
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ import org.junit.Test;
|
|||
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 class RocksDBCountersTest extends BaseRocksDBUnitTest {
|
|||
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 class RocksDBCountersTest extends BaseRocksDBUnitTest {
|
|||
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 class RocksDBCountersTest extends BaseRocksDBUnitTest {
|
|||
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 class RocksDBCountersTest extends BaseRocksDBUnitTest {
|
|||
});
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue