diff --git a/hugegraph-api/pom.xml b/hugegraph-api/pom.xml index 3043f8bccb..b963c6bfca 100644 --- a/hugegraph-api/pom.xml +++ b/hugegraph-api/pom.xml @@ -125,7 +125,7 @@ - 0.58.0.0 + 0.59.0.0 diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/profile/GraphsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/profile/GraphsAPI.java index a6bc40ac48..b095291280 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/profile/GraphsAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/profile/GraphsAPI.java @@ -49,6 +49,7 @@ import com.baidu.hugegraph.core.GraphManager; import com.baidu.hugegraph.server.RestServer; import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.type.define.GraphReadMode; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.codahale.metrics.annotation.Timed; @@ -167,4 +168,39 @@ public Map mode(@Context GraphManager manager, HugeGraph g = graph(manager, name); return ImmutableMap.of("mode", g.mode()); } + + @PUT + @Timed + @Path("{name}/graph_read_mode") + @Consumes(APPLICATION_JSON) + @Produces(APPLICATION_JSON_WITH_CHARSET) + @RolesAllowed("admin") + public Map graphReadMode( + @Context GraphManager manager, + @PathParam("name") String name, + GraphReadMode readMode) { + LOG.debug("Set graph read mode to: '{}' of graph '{}'", + readMode, name); + + E.checkArgument(readMode != null, + "Graph read mode can't be null"); + HugeGraph g = graph(manager, name); + g.readMode(readMode); + return ImmutableMap.of("graph_read_mode", readMode); + } + + @GET + @Timed + @Path("{name}/graph_read_mode") + @Consumes(APPLICATION_JSON) + @Produces(APPLICATION_JSON_WITH_CHARSET) + @RolesAllowed({"admin", "$owner=$name"}) + public Map graphReadMode( + @Context GraphManager manager, + @PathParam("name") String name) { + LOG.debug("Get graph read mode of graph '{}'", name); + + HugeGraph g = graph(manager, name); + return ImmutableMap.of("graph_read_mode", g.readMode()); + } } 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 e139acc84a..a4a91524d9 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 @@ -49,6 +49,7 @@ 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.type.define.ReadFrequency; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.codahale.metrics.annotation.Timed; @@ -182,6 +183,8 @@ private static class JsonPropertyKey implements Checkable { public DataType dataType; @JsonProperty("aggregate_type") public AggregateType aggregateType; + @JsonProperty("read_frequency") + public ReadFrequency readFrequency; @JsonProperty("properties") public String[] properties; @JsonProperty("user_data") @@ -221,6 +224,9 @@ private PropertyKey.Builder convert2Builder(HugeGraph g) { if (this.aggregateType != null) { builder.aggregateType(this.aggregateType); } + if (this.readFrequency != null) { + builder.readFrequency(this.readFrequency); + } if (this.userdata != null) { builder.userdata(this.userdata); } @@ -234,10 +240,10 @@ private PropertyKey.Builder convert2Builder(HugeGraph g) { public String toString() { return String.format("JsonPropertyKey{name=%s, cardinality=%s, " + "dataType=%s, aggregateType=%s, " + - "properties=%s}", + "readFrequency=%s, properties=%s}", this.name, this.cardinality, this.dataType, this.aggregateType, - this.properties); + this.readFrequency, this.properties); } } } 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 a6ef14795d..f58cc35f44 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 @@ -86,6 +86,7 @@ import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.type.Namifiable; import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.type.define.GraphReadMode; import com.baidu.hugegraph.type.define.NodeRole; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; @@ -596,6 +597,18 @@ public void mode(GraphMode mode) { this.hugegraph.mode(mode); } + @Override + public GraphReadMode readMode() { + this.verifyPermission(HugePermission.READ, ResourceType.STATUS); + return this.hugegraph.readMode(); + } + + @Override + public void readMode(GraphReadMode readMode) { + this.verifyPermission(HugePermission.WRITE, ResourceType.STATUS); + this.hugegraph.readMode(readMode); + } + @Override public void waitStarted() { this.verifyPermission(HugePermission.READ, ResourceType.STATUS); 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 1df5905f29..4062ef3534 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 @@ -108,10 +108,11 @@ public final class ApiVersion { * [0.57] Issue-1105: Allow not rebuild index when create index label * [0.58] Issue-1173: Supports customized kout/kneighbor, * multi-node-shortest-path, jaccard-similar and template-paths + * [0.59] Issue-1333: Support graph read mode for olap property */ // The second parameter of Version.of() is for IDE running without JAR - public static final Version VERSION = Version.of(ApiVersion.class, "0.58"); + public static final Version VERSION = Version.of(ApiVersion.class, "0.59"); 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/CassandraFeatures.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraFeatures.java index 80fc3bd677..f6a24ba3f6 100644 --- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraFeatures.java +++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraFeatures.java @@ -121,4 +121,9 @@ public boolean supportsAggregateProperty() { public boolean supportsTtl() { return true; } + + @Override + public boolean supportsOlapProperties() { + return false; + } } 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 65f566dcd4..fea2b988d2 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 @@ -206,6 +206,7 @@ public void init(CassandraSessionPool.Session session) { .put(HugeKeys.DATA_TYPE, DataType.tinyint()) .put(HugeKeys.CARDINALITY, DataType.tinyint()) .put(HugeKeys.AGGREGATE_TYPE, DataType.tinyint()) + .put(HugeKeys.READ_FREQUENCY, DataType.tinyint()) .put(HugeKeys.PROPERTIES, DataType.set(TYPE_PK)) .put(HugeKeys.USER_DATA, TYPE_UD) .put(HugeKeys.STATUS, DataType.tinyint()) 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 12b72f3352..e3d8f44be2 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java @@ -52,6 +52,7 @@ import com.baidu.hugegraph.traversal.optimize.HugeVertexStepStrategy; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.type.define.GraphReadMode; import com.baidu.hugegraph.type.define.NodeRole; /** @@ -136,6 +137,9 @@ public interface HugeGraph extends Graph { public GraphMode mode(); public void mode(GraphMode mode); + public GraphReadMode readMode(); + public void readMode(GraphReadMode readMode); + public void waitStarted(); public void serverStarted(Id serverId, NodeRole serverRole); public boolean started(); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraphParams.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraphParams.java index 8d51af883a..e307415635 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraphParams.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraphParams.java @@ -30,6 +30,7 @@ import com.baidu.hugegraph.event.EventHub; import com.baidu.hugegraph.task.ServerInfoManager; import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.type.define.GraphReadMode; import com.google.common.util.concurrent.RateLimiter; /** @@ -40,6 +41,7 @@ public interface HugeGraphParams { public HugeGraph graph(); public String name(); public GraphMode mode(); + public GraphReadMode readMode(); public SchemaTransaction schemaTransaction(); public GraphTransaction systemTransaction(); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/StandardHugeGraph.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/StandardHugeGraph.java index 91e6e89455..d2de38457c 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/StandardHugeGraph.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/StandardHugeGraph.java @@ -83,6 +83,7 @@ import com.baidu.hugegraph.task.TaskScheduler; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.type.define.GraphMode; +import com.baidu.hugegraph.type.define.GraphReadMode; import com.baidu.hugegraph.type.define.NodeRole; import com.baidu.hugegraph.util.DateUtil; import com.baidu.hugegraph.util.E; @@ -123,6 +124,7 @@ public class StandardHugeGraph implements HugeGraph { private volatile boolean started; private volatile boolean closed; private volatile GraphMode mode; + private volatile GraphReadMode readMode; private volatile HugeVariables variables; private final String name; @@ -179,6 +181,7 @@ public StandardHugeGraph(HugeConfig config) { this.started = false; this.closed = false; this.mode = GraphMode.NONE; + this.readMode = GraphReadMode.OLTP_ONLY; LockUtil.init(this.name); @@ -265,6 +268,16 @@ public void mode(GraphMode mode) { this.mode = mode; } + @Override + public GraphReadMode readMode() { + return this.readMode; + } + + @Override + public void readMode(GraphReadMode readMode) { + this.readMode = readMode; + } + @Override public void waitStarted() { // Just for trigger Tx.getOrNewTransaction, then load 3 stores @@ -957,6 +970,11 @@ public GraphMode mode() { return StandardHugeGraph.this.mode(); } + @Override + public GraphReadMode readMode() { + return StandardHugeGraph.this.readMode(); + } + @Override public SchemaTransaction schemaTransaction() { return StandardHugeGraph.this.schemaTransaction(); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/BinarySerializer.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/BinarySerializer.java index 9d95d5e37f..3620d72efc 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/BinarySerializer.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/BinarySerializer.java @@ -62,6 +62,7 @@ import com.baidu.hugegraph.type.define.HugeKeys; import com.baidu.hugegraph.type.define.IdStrategy; import com.baidu.hugegraph.type.define.IndexType; +import com.baidu.hugegraph.type.define.ReadFrequency; import com.baidu.hugegraph.type.define.SchemaStatus; import com.baidu.hugegraph.type.define.SerialEnum; import com.baidu.hugegraph.util.Bytes; @@ -997,6 +998,7 @@ public BinaryBackendEntry writePropertyKey(PropertyKey schema) { writeEnum(HugeKeys.DATA_TYPE, schema.dataType()); writeEnum(HugeKeys.CARDINALITY, schema.cardinality()); writeEnum(HugeKeys.AGGREGATE_TYPE, schema.aggregateType()); + writeEnum(HugeKeys.READ_FREQUENCY, schema.readFrequency()); writeIds(HugeKeys.PROPERTIES, schema.properties()); writeEnum(HugeKeys.STATUS, schema.status()); writeUserdata(schema); @@ -1016,6 +1018,8 @@ public PropertyKey readPropertyKey(HugeGraph graph, Cardinality.class)); propertyKey.aggregateType(readEnum(HugeKeys.AGGREGATE_TYPE, AggregateType.class)); + propertyKey.readFrequency(readEnum(HugeKeys.READ_FREQUENCY, + ReadFrequency.class)); propertyKey.properties(readIds(HugeKeys.PROPERTIES)); propertyKey.status(readEnum(HugeKeys.STATUS, SchemaStatus.class)); readUserdata(propertyKey); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/TableSerializer.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/TableSerializer.java index 168cc9c320..732d504db0 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/TableSerializer.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/serializer/TableSerializer.java @@ -56,6 +56,7 @@ import com.baidu.hugegraph.type.define.HugeKeys; import com.baidu.hugegraph.type.define.IdStrategy; import com.baidu.hugegraph.type.define.IndexType; +import com.baidu.hugegraph.type.define.ReadFrequency; import com.baidu.hugegraph.type.define.SchemaStatus; import com.baidu.hugegraph.type.define.SerialEnum; import com.baidu.hugegraph.util.E; @@ -464,6 +465,8 @@ public BackendEntry writePropertyKey(PropertyKey propertyKey) { entry.column(HugeKeys.CARDINALITY, propertyKey.cardinality().code()); entry.column(HugeKeys.AGGREGATE_TYPE, propertyKey.aggregateType().code()); + entry.column(HugeKeys.READ_FREQUENCY, + propertyKey.readFrequency().code()); entry.column(HugeKeys.PROPERTIES, this.toLongSet(propertyKey.properties())); this.writeUserdata(propertyKey, entry); @@ -560,6 +563,7 @@ public PropertyKey readPropertyKey(HugeGraph graph, Number dataType = entry.column(HugeKeys.DATA_TYPE); Number cardinality = entry.column(HugeKeys.CARDINALITY); Number aggregateType = entry.column(HugeKeys.AGGREGATE_TYPE); + Number readFrequency = entry.column(HugeKeys.READ_FREQUENCY); Object properties = entry.column(HugeKeys.PROPERTIES); Number status = entry.column(HugeKeys.STATUS); @@ -571,6 +575,9 @@ public PropertyKey readPropertyKey(HugeGraph graph, propertyKey.aggregateType(SerialEnum.fromCode( AggregateType.class, aggregateType.byteValue())); + propertyKey.readFrequency(SerialEnum.fromCode( + ReadFrequency.class, + readFrequency.byteValue())); propertyKey.properties(this.toIdArray(properties)); this.readUserdata(propertyKey, entry); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendFeatures.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendFeatures.java index e7c0c5ec45..8330147d0e 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendFeatures.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendFeatures.java @@ -62,4 +62,6 @@ public default boolean supportsPersistence() { public boolean supportsAggregateProperty(); public boolean supportsTtl(); + + public boolean supportsOlapProperties(); } 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 78bd7759a6..c7d9db8e1b 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 @@ -461,5 +461,10 @@ public boolean supportsAggregateProperty() { public boolean supportsTtl() { return false; } + + @Override + public boolean supportsOlapProperties() { + return false; + } }; } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/io/GraphSONSchemaSerializer.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/io/GraphSONSchemaSerializer.java index f26de5f153..25c9e53518 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/io/GraphSONSchemaSerializer.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/io/GraphSONSchemaSerializer.java @@ -98,6 +98,7 @@ public Map writePropertyKey(PropertyKey propertyKey) { map.put(HugeKeys.DATA_TYPE, propertyKey.dataType()); map.put(HugeKeys.CARDINALITY, propertyKey.cardinality()); map.put(HugeKeys.AGGREGATE_TYPE, propertyKey.aggregateType()); + map.put(HugeKeys.READ_FREQUENCY, propertyKey.readFrequency()); map.put(HugeKeys.PROPERTIES, graph.mapPkId2Name(propertyKey.properties())); map.put(HugeKeys.STATUS, propertyKey.status()); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/schema/RebuildIndexCallable.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/schema/RebuildIndexCallable.java index da6477170f..ac951dcb2b 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/schema/RebuildIndexCallable.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/schema/RebuildIndexCallable.java @@ -190,4 +190,4 @@ private SchemaElement schemaElement() { "Invalid HugeType '%s' for rebuild", type)); } } -} \ No newline at end of file +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/PropertyKey.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/PropertyKey.java index d0ee1f6ccd..5129d7d184 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/PropertyKey.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/schema/PropertyKey.java @@ -37,6 +37,7 @@ import com.baidu.hugegraph.type.define.AggregateType; import com.baidu.hugegraph.type.define.Cardinality; import com.baidu.hugegraph.type.define.DataType; +import com.baidu.hugegraph.type.define.ReadFrequency; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.LongEncoding; @@ -45,12 +46,14 @@ public class PropertyKey extends SchemaElement implements Propfiable { private DataType dataType; private Cardinality cardinality; private AggregateType aggregateType; + private ReadFrequency readFrequency; public PropertyKey(final HugeGraph graph, Id id, String name) { super(graph, id, name); this.dataType = DataType.TEXT; this.cardinality = Cardinality.SINGLE; this.aggregateType = AggregateType.NONE; + this.readFrequency = ReadFrequency.OLTP; } @Override @@ -82,6 +85,14 @@ public void aggregateType(AggregateType aggregateType) { this.aggregateType = aggregateType; } + public void readFrequency(ReadFrequency readFrequency) { + this.readFrequency = readFrequency; + } + + public ReadFrequency readFrequency() { + return this.readFrequency; + } + @Override public Set properties() { return Collections.emptySet(); @@ -108,7 +119,8 @@ public boolean hasSameContent(PropertyKey other) { return super.hasSameContent(other) && this.dataType == other.dataType() && this.cardinality == other.cardinality() && - this.aggregateType == other.aggregateType(); + this.aggregateType == other.aggregateType() && + this.readFrequency == other.readFrequency(); } public String clazz() { @@ -370,6 +382,12 @@ public interface Builder extends SchemaBuilder { Builder calcOld(); + Builder calcSet(); + + Builder calcList(); + + Builder readFrequency(ReadFrequency readFrequency); + Builder cardinality(Cardinality cardinality); Builder dataType(DataType dataType); 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 47c4cb0949..9f3266a1f5 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 @@ -28,6 +28,7 @@ import com.baidu.hugegraph.exception.ExistedException; import com.baidu.hugegraph.exception.NotAllowException; import com.baidu.hugegraph.exception.NotFoundException; +import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.schema.PropertyKey; import com.baidu.hugegraph.schema.Userdata; import com.baidu.hugegraph.type.HugeType; @@ -35,6 +36,7 @@ import com.baidu.hugegraph.type.define.AggregateType; import com.baidu.hugegraph.type.define.Cardinality; import com.baidu.hugegraph.type.define.DataType; +import com.baidu.hugegraph.type.define.ReadFrequency; import com.baidu.hugegraph.util.E; public class PropertyKeyBuilder extends AbstractBuilder @@ -45,6 +47,7 @@ public class PropertyKeyBuilder extends AbstractBuilder private DataType dataType; private Cardinality cardinality; private AggregateType aggregateType; + private ReadFrequency readFrequency; private boolean checkExist; private Userdata userdata; @@ -57,6 +60,7 @@ public PropertyKeyBuilder(SchemaTransaction transaction, this.dataType = DataType.TEXT; this.cardinality = Cardinality.SINGLE; this.aggregateType = AggregateType.NONE; + this.readFrequency = ReadFrequency.OLTP; this.userdata = new Userdata(); this.checkExist = true; } @@ -70,6 +74,7 @@ public PropertyKeyBuilder(SchemaTransaction transaction, this.dataType = copy.dataType(); this.cardinality = copy.cardinality(); this.aggregateType = copy.aggregateType(); + this.readFrequency = copy.readFrequency(); this.userdata = new Userdata(copy.userdata()); this.checkExist = false; } @@ -82,6 +87,7 @@ public PropertyKey build() { propertyKey.dataType(this.dataType); propertyKey.cardinality(this.cardinality); propertyKey.aggregateType(this.aggregateType); + propertyKey.readFrequency(this.readFrequency); propertyKey.userdata(this.userdata); return propertyKey; } @@ -103,6 +109,7 @@ public PropertyKey create() { Userdata.check(this.userdata, Action.INSERT); this.checkAggregateType(); + this.checkOlap(); propertyKey = this.build(); assert propertyKey.name().equals(name); @@ -135,6 +142,10 @@ private boolean hasSameProperties(PropertyKey propertyKey) { return false; } + if (this.readFrequency != propertyKey.readFrequency()) { + return false; + } + // all properties are same, return true. return true; } @@ -289,6 +300,24 @@ public PropertyKeyBuilder calcOld() { return this; } + @Override + public PropertyKey.Builder calcSet() { + this.aggregateType = AggregateType.SET; + return this; + } + + @Override + public PropertyKey.Builder calcList() { + this.aggregateType = AggregateType.LIST; + return this; + } + + @Override + public PropertyKey.Builder readFrequency(ReadFrequency readFrequency) { + this.readFrequency = readFrequency; + return this; + } + @Override public PropertyKeyBuilder userdata(String key, Object value) { this.userdata.put(key, value); @@ -347,7 +376,15 @@ private void checkAggregateType() { return; } - if (this.cardinality != Cardinality.SINGLE) { + if (this.aggregateType.isSet() && + this.cardinality == Cardinality.SET || + this.aggregateType.isList() && + this.cardinality == Cardinality.LIST) { + return; + } + + if (this.cardinality != Cardinality.SINGLE || + this.aggregateType.isUnion()) { throw new NotAllowException("Not allowed to set aggregate type " + "'%s' for property key '%s' with " + "cardinality '%s'", @@ -355,6 +392,14 @@ private void checkAggregateType() { this.cardinality); } + if (this.aggregateType.isSum() && this.dataType.isDate()) { + throw new NotAllowException( + "Not allowed to set aggregate type '%s' for " + + "property key '%s' with data type '%s'", + this.aggregateType, this.name, this.dataType); + } + + if (this.aggregateType.isNumber() && !this.dataType.isNumber() && !this.dataType.isDate()) { throw new NotAllowException( @@ -363,4 +408,22 @@ private void checkAggregateType() { this.aggregateType, this.name, this.dataType); } } + + private void checkOlap() { + if (this.readFrequency == ReadFrequency.OLTP) { + return; + } + + if (!this.graph().backendStoreFeatures().supportsOlapProperties()) { + throw new NotSupportException( + "olap property key '%s' for backend '%s'", + this.name, this.graph().backend()); + } + + if (!this.aggregateType.isNone()) { + throw new NotAllowException( + "Not allow to set aggregate type '%s' for olap " + + "property key '%s'", this.aggregateType, this.name); + } + } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/AggregateType.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/AggregateType.java index bb1edb4f21..cf7f8f63e2 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/AggregateType.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/AggregateType.java @@ -25,7 +25,9 @@ public enum AggregateType implements SerialEnum { MAX(1, "max"), MIN(2, "min"), SUM(3, "sum"), - OLD(4, "old"); + OLD(4, "old"), + SET(5, "set"), + LIST(6, "list"); private final byte code; private final String name; @@ -73,6 +75,18 @@ public boolean isOld() { return this == OLD; } + public boolean isSet() { + return this == SET; + } + + public boolean isList() { + return this == LIST; + } + + public boolean isUnion() { + return this == SET || this == LIST; + } + public boolean isIndexable() { return this == NONE || this == MAX || this == MIN || this == OLD; } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphReadMode.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphReadMode.java new file mode 100644 index 0000000000..5fe85368eb --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/GraphReadMode.java @@ -0,0 +1,50 @@ +/* + * 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 GraphReadMode { + + ALL(1, "all"), + + OLTP_ONLY(2, "oltp_only"), + + OLAP_ONLY(3, "olap_only"); + + private final byte code; + private final String name; + + private GraphReadMode(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 showOlap() { + return this == ALL || this == OLAP_ONLY; + } +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/HugeKeys.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/HugeKeys.java index 3d119c8408..488312a69b 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/HugeKeys.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/HugeKeys.java @@ -53,6 +53,7 @@ public enum HugeKeys { DATA_TYPE(120, "data_type"), CARDINALITY(121, "cardinality"), AGGREGATE_TYPE(122, "aggregate_type"), + READ_FREQUENCY(123, "read_frequency"), /* Column names of schema type (IndexLabel) */ BASE_TYPE(150, "base_type"), @@ -75,7 +76,12 @@ public enum HugeKeys { DIRECTION(205, "direction"), SORT_VALUES(206, "sort_values"), PRIMARY_VALUES(207, "primary_values"), - EXPIRED_TIME(208, "expired_time"); + EXPIRED_TIME(208, "expired_time"), + + PROPERTY_TYPE(249, "property_type"), + AGGREGATE_PROPERTIES(250, "aggregate_properties"); + + public static final long NORMAL_PROPERTY_ID = 0L; /* HugeKeys define */ private byte code = 0; diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/ReadFrequency.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/ReadFrequency.java new file mode 100644 index 0000000000..16555ec07a --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/type/define/ReadFrequency.java @@ -0,0 +1,49 @@ +/* + * 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 ReadFrequency implements SerialEnum { + + OLTP(1, "oltp"), + + OLAP(2, "olap"); + + private byte code = 0; + private String name = null; + + static { + SerialEnum.register(ReadFrequency.class); + } + + ReadFrequency(int code, String name) { + assert code < 256; + this.code = (byte) code; + this.name = name; + } + + @Override + public byte code() { + return this.code; + } + + public String string() { + return this.name; + } +} diff --git a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseFeatures.java b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseFeatures.java index 952990c126..d9e4ef3b5c 100644 --- a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseFeatures.java +++ b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseFeatures.java @@ -125,4 +125,9 @@ public boolean supportsAggregateProperty() { public boolean supportsTtl() { return true; } + + @Override + public boolean supportsOlapProperties() { + return false; + } } diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlFeatures.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlFeatures.java index 34ed0de8fd..a6c989ef1f 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlFeatures.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlFeatures.java @@ -120,4 +120,9 @@ public boolean supportsAggregateProperty() { public boolean supportsTtl() { return false; } + + @Override + public boolean supportsOlapProperties() { + return false; + } } 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 0887726fe7..e9e5fa969f 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 @@ -212,6 +212,7 @@ public PropertyKey(Map typesMapping) { this.define.column(HugeKeys.DATA_TYPE, TINYINT); this.define.column(HugeKeys.CARDINALITY, TINYINT); this.define.column(HugeKeys.AGGREGATE_TYPE, TINYINT); + this.define.column(HugeKeys.READ_FREQUENCY, TINYINT); this.define.column(HugeKeys.PROPERTIES, SMALL_JSON); this.define.column(HugeKeys.USER_DATA, LARGE_JSON); this.define.column(HugeKeys.STATUS, TINYINT); diff --git a/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloFeatures.java b/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloFeatures.java index 7423e1e262..1ae2613851 100644 --- a/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloFeatures.java +++ b/hugegraph-palo/src/main/java/com/baidu/hugegraph/backend/store/palo/PaloFeatures.java @@ -123,4 +123,9 @@ public boolean supportsAggregateProperty() { public boolean supportsTtl() { return false; } + + @Override + public boolean supportsOlapProperties() { + return false; + } } diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBFeatures.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBFeatures.java index 5ac0a500ee..0820b639eb 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBFeatures.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBFeatures.java @@ -125,4 +125,9 @@ public boolean supportsAggregateProperty() { public boolean supportsTtl() { return false; } + + @Override + public boolean supportsOlapProperties() { + return false; + } } diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java index 52736a2ef4..d1741dc870 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java @@ -5920,11 +5920,17 @@ public void testUpdateEdgePropertyOfAggregateType() { schema.propertyKey("times") .asLong().valueSingle().calcSum() .ifNotExist().create(); + schema.propertyKey("port") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("type") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("ip").useCustomizeStringId().ifNotExist().create(); schema.edgeLabel("attack").sourceLabel("ip").targetLabel("ip") - .properties("startTime", "endTime", "times") + .properties("startTime", "endTime", "times", "port", "type") .ifNotExist().create(); Vertex ip1 = graph.addVertex(T.label, "ip", T.id, "10.0.0.1"); @@ -5933,7 +5939,7 @@ public void testUpdateEdgePropertyOfAggregateType() { ip1.addEdge("attack", ip2, "startTime", "2019-1-1 00:00:30", "endTime", "2019-1-1 00:01:00", - "times", 3); + "times", 3, "port", 21, "type", 21); graph.tx().commit(); Edge edge = graph.traversal().V("10.0.0.1").outE().next(); @@ -5942,10 +5948,23 @@ public void testUpdateEdgePropertyOfAggregateType() { Assert.assertEquals(Utils.date("2019-1-1 00:01:00"), edge.value("endTime")); Assert.assertEquals(3L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21), edge.value("port")); + Assert.assertEquals(ImmutableList.of(21), edge.value("type")); + + edge = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:00:30"), + edge.value("startTime")); + Assert.assertEquals(Utils.date("2019-1-1 00:01:00"), + edge.value("endTime")); + Assert.assertEquals(3L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21), edge.value("port")); + Assert.assertEquals(ImmutableList.of(21), edge.value("type")); edge.property("startTime", "2019-1-1 00:04:00"); edge.property("endTime", "2019-1-1 00:08:00"); edge.property("times", 10); + edge.property("port", 22); + edge.property("type", 22); graph.tx().commit(); edge = graph.traversal().V("10.0.0.1").outE().next(); @@ -5954,10 +5973,23 @@ public void testUpdateEdgePropertyOfAggregateType() { Assert.assertEquals(Utils.date("2019-1-1 00:08:00"), edge.value("endTime")); Assert.assertEquals(13L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21, 22), edge.value("port")); + Assert.assertEquals(ImmutableList.of(21, 22), edge.value("type")); + + edge = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:00:30"), + edge.value("startTime")); + Assert.assertEquals(Utils.date("2019-1-1 00:08:00"), + edge.value("endTime")); + Assert.assertEquals(13L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21, 22), edge.value("port")); + Assert.assertEquals(ImmutableList.of(21, 22), edge.value("type")); edge.property("startTime", "2019-1-2 00:04:00"); edge.property("endTime", "2019-1-2 00:08:00"); edge.property("times", 7); + edge.property("port", 23); + edge.property("type", 23); graph.tx().commit(); edge = graph.traversal().V("10.0.0.1").outE().next(); @@ -5966,17 +5998,50 @@ public void testUpdateEdgePropertyOfAggregateType() { Assert.assertEquals(Utils.date("2019-1-2 00:08:00"), edge.value("endTime")); Assert.assertEquals(20L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21, 22, 23), + edge.value("port")); + Assert.assertEquals(ImmutableList.of(21, 22, 23), + edge.value("type")); + + edge = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:00:30"), + edge.value("startTime")); + Assert.assertEquals(Utils.date("2019-1-2 00:08:00"), + edge.value("endTime")); + Assert.assertEquals(20L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21, 22, 23), + edge.value("port")); + Assert.assertEquals(ImmutableList.of(21, 22, 23), + edge.value("type")); edge.property("startTime", "2019-1-1 00:00:00"); edge.property("endTime", "2019-2-1 00:20:00"); edge.property("times", 100); + edge.property("port", 23); + edge.property("type", 23); graph.tx().commit(); + edge = graph.traversal().V("10.0.0.1").outE().next(); Assert.assertEquals(Utils.date("2019-1-1 00:00:00"), edge.value("startTime")); Assert.assertEquals(Utils.date("2019-2-1 00:20:00"), edge.value("endTime")); Assert.assertEquals(120L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21, 22, 23), + edge.value("port")); + Assert.assertEquals(ImmutableList.of(21, 22, 23, 23), + edge.value("type")); + + edge = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:00:00"), + edge.value("startTime")); + Assert.assertEquals(Utils.date("2019-2-1 00:20:00"), + edge.value("endTime")); + Assert.assertEquals(120L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(21, 22, 23), + edge.value("port")); + Assert.assertEquals(ImmutableList.of(21, 22, 23, 23), + edge.value("type")); } @Test @@ -5996,11 +6061,17 @@ public void testAddAndUpdateEdgePropertyOfAggregateType() { schema.propertyKey("times") .asLong().valueSingle().calcSum() .ifNotExist().create(); + schema.propertyKey("port") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("type") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("ip").useCustomizeStringId().ifNotExist().create(); schema.edgeLabel("attack").sourceLabel("ip").targetLabel("ip") - .properties("startTime", "endTime", "times") + .properties("startTime", "endTime", "times", "port", "type") .ifNotExist().create(); Vertex ip1 = graph.addVertex(T.label, "ip", T.id, "10.0.0.1"); @@ -6009,10 +6080,12 @@ public void testAddAndUpdateEdgePropertyOfAggregateType() { Edge edge = ip1.addEdge("attack", ip2, "startTime", "2019-1-1 00:00:30", "endTime", "2019-1-1 00:01:00", - "times", 3); + "times", 3, "port", 21, "type", 21); edge.property("startTime", "2019-1-1 00:04:00"); edge.property("endTime", "2019-1-1 00:08:00"); - edge.property("times", 10); + edge.property("times", 10L); + edge.property("port", 21); + edge.property("type", 21); Edge result = graph.traversal().V("10.0.0.1").outE().next(); Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), @@ -6020,6 +6093,17 @@ public void testAddAndUpdateEdgePropertyOfAggregateType() { Assert.assertEquals(Utils.date("2019-1-1 00:08:00"), result.value("endTime")); Assert.assertEquals(10L, result.value("times")); + Assert.assertEquals(ImmutableSet.of(21), result.value("port")); + Assert.assertEquals(ImmutableList.of(21, 21), result.value("type")); + + result = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), + result.value("startTime")); + Assert.assertEquals(Utils.date("2019-1-1 00:08:00"), + result.value("endTime")); + Assert.assertEquals(10L, result.value("times")); + Assert.assertEquals(ImmutableSet.of(21), result.value("port")); + Assert.assertEquals(ImmutableList.of(21, 21), result.value("type")); graph.tx().commit(); @@ -6029,34 +6113,71 @@ public void testAddAndUpdateEdgePropertyOfAggregateType() { Assert.assertEquals(Utils.date("2019-1-1 00:08:00"), result.value("endTime")); Assert.assertEquals(10L, result.value("times")); + Assert.assertEquals(ImmutableSet.of(21), result.value("port")); + Assert.assertEquals(ImmutableList.of(21, 21), result.value("type")); + + result = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), + result.value("startTime")); + Assert.assertEquals(Utils.date("2019-1-1 00:08:00"), + result.value("endTime")); + Assert.assertEquals(10L, result.value("times")); + Assert.assertEquals(ImmutableSet.of(21), result.value("port")); + Assert.assertEquals(ImmutableList.of(21, 21), result.value("type")); edge = ip1.addEdge("attack", ip2, "startTime", "2019-1-1 00:00:30", "endTime", "2019-1-1 00:01:00", - "times", 3); + "times", 3, "port", 22, "type", 22); edge.property("startTime", "2019-1-2 00:00:30"); edge.property("endTime", "2019-1-2 00:01:00"); edge.property("times", 2); + edge.property("port", 23); + edge.property("type", 23); - Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), + Assert.assertEquals(Utils.date("2019-1-2 00:00:30"), edge.value("startTime")); Assert.assertEquals(Utils.date("2019-1-2 00:01:00"), edge.value("endTime")); - Assert.assertEquals(12L, edge.value("times")); + Assert.assertEquals(2L, edge.value("times")); + Assert.assertEquals(ImmutableSet.of(22, 23), + edge.value("port")); + Assert.assertEquals(ImmutableList.of(22, 23), + edge.value("type")); - Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), + Assert.assertEquals(Utils.date("2019-1-2 00:00:30"), edge.property("startTime").value()); Assert.assertEquals(Utils.date("2019-1-2 00:01:00"), edge.property("endTime").value()); - Assert.assertEquals(12L, edge.property("times").value()); + Assert.assertEquals(2L, edge.property("times").value()); + Assert.assertEquals(ImmutableSet.of(22, 23), + edge.property("port").value()); + Assert.assertEquals(ImmutableList.of(22, 23), + edge.property("type").value()); + graph.tx().commit(); result = graph.traversal().V("10.0.0.1").outE().next(); Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), result.property("startTime").value()); Assert.assertEquals(Utils.date("2019-1-2 00:01:00"), result.property("endTime").value()); Assert.assertEquals(12L, result.property("times").value()); + Assert.assertEquals(ImmutableSet.of(21, 22, 23), + result.property("port").value()); + Assert.assertEquals(ImmutableList.of(21, 21, 22, 23), + result.property("type").value()); + + result = graph.traversal().V("10.0.0.2").inE().next(); + Assert.assertEquals(Utils.date("2019-1-1 00:04:00"), + result.property("startTime").value()); + Assert.assertEquals(Utils.date("2019-1-2 00:01:00"), + result.property("endTime").value()); + Assert.assertEquals(12L, result.property("times").value()); + Assert.assertEquals(ImmutableSet.of(21, 22, 23), + result.property("port").value()); + Assert.assertEquals(ImmutableList.of(21, 21, 22, 23), + result.property("type").value()); } @Test @@ -6079,11 +6200,19 @@ public void testQueryEdgeByAggregateProperty() { schema.propertyKey("firstTime") .asDate().valueSingle().calcOld() .ifNotExist().create(); + schema.propertyKey("port") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("type") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("ip").useCustomizeStringId().ifNotExist().create(); schema.edgeLabel("attack").sourceLabel("ip").targetLabel("ip") - .properties("startTime", "endTime", "times", "firstTime") + .properties("startTime", "endTime", "times", + "firstTime", "port", "type") + .nullableKeys("port", "type") .ifNotExist().create(); schema.indexLabel("attackByStartTime") @@ -6099,6 +6228,20 @@ public void testQueryEdgeByAggregateProperty() { }); schema.indexLabel("attackByFirstTime") .onE("attack").by("firstTime").range().ifNotExist().create(); + Assert.assertThrows(IllegalArgumentException.class, () -> { + schema.indexLabel("attackByPort") + .onE("attack").by("port").secondary().ifNotExist().create(); + }, e -> { + Assert.assertTrue(e.getMessage(), e.getMessage().contains( + "The aggregate type SET is not indexable")); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + schema.indexLabel("attackByType") + .onE("attack").by("type").secondary().ifNotExist().create(); + }, e -> { + Assert.assertTrue(e.getMessage(), e.getMessage().contains( + "The aggregate type LIST is not indexable")); + }); Vertex ip1 = graph.addVertex(T.label, "ip", T.id, "10.0.0.1"); Vertex ip2 = graph.addVertex(T.label, "ip", T.id, "10.0.0.2"); diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/PropertyKeyCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/PropertyKeyCoreTest.java index 454d488e4f..ca0dd4f79e 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/PropertyKeyCoreTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/PropertyKeyCoreTest.java @@ -190,6 +190,28 @@ public void testAddPropertyKeyWithAggregateType() { Assert.assertEquals(Cardinality.SINGLE, oldProp.cardinality()); Assert.assertEquals(AggregateType.OLD, oldProp.aggregateType()); + PropertyKey setProp = schema.propertyKey("setProp") + .asLong().valueSet().calcSet() + .ifNotExist().create(); + Assert.assertEquals(DataType.LONG, setProp.dataType()); + Assert.assertEquals(Cardinality.SET, setProp.cardinality()); + Assert.assertEquals(AggregateType.SET, setProp.aggregateType()); + setProp = schema.getPropertyKey("setProp"); + Assert.assertEquals(DataType.LONG, setProp.dataType()); + Assert.assertEquals(Cardinality.SET, setProp.cardinality()); + Assert.assertEquals(AggregateType.SET, setProp.aggregateType()); + + PropertyKey listProp = schema.propertyKey("listProp") + .asLong().valueList().calcList() + .ifNotExist().create(); + Assert.assertEquals(DataType.LONG, listProp.dataType()); + Assert.assertEquals(Cardinality.LIST, listProp.cardinality()); + Assert.assertEquals(AggregateType.LIST, listProp.aggregateType()); + listProp = schema.getPropertyKey("listProp"); + Assert.assertEquals(DataType.LONG, listProp.dataType()); + Assert.assertEquals(Cardinality.LIST, listProp.cardinality()); + Assert.assertEquals(AggregateType.LIST, listProp.aggregateType()); + PropertyKey regular = schema.propertyKey("regular").create(); Assert.assertEquals(DataType.TEXT, regular.dataType()); Assert.assertEquals(Cardinality.SINGLE, regular.cardinality()); @@ -245,6 +267,26 @@ public void testAddPropertyKeyWithAggregateTypeInvalid() { .asDate().valueSet().calcOld().create(); }); + Assert.assertThrows(NotAllowException.class, () -> { + schema.propertyKey("aggregateProperty") + .asDate().valueSingle().calcSet().create(); + }); + + Assert.assertThrows(NotAllowException.class, () -> { + schema.propertyKey("aggregateProperty") + .asDate().valueSingle().calcList().create(); + }); + + Assert.assertThrows(NotAllowException.class, () -> { + schema.propertyKey("aggregateProperty") + .asDate().valueSet().calcList().create(); + }); + + Assert.assertThrows(NotAllowException.class, () -> { + schema.propertyKey("aggregateProperty") + .asDate().valueList().calcSet().create(); + }); + // Invalid data type Assert.assertThrows(NotAllowException.class, () -> { schema.propertyKey("aggregateProperty") @@ -305,6 +347,11 @@ public void testAddPropertyKeyWithAggregateTypeInvalid() { schema.propertyKey("aggregateProperty") .asUUID().valueSingle().calcSum().create(); }); + + Assert.assertThrows(NotAllowException.class, () -> { + schema.propertyKey("aggregateProperty") + .asDate().valueSingle().calcSum().create(); + }); } @Test diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java index a18300d4ba..196589f361 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java @@ -20,6 +20,7 @@ package com.baidu.hugegraph.core; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashSet; @@ -27,6 +28,7 @@ import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; +import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -5426,16 +5428,24 @@ public void testUpdateVertexPropertyOfAggregateType() { schema.propertyKey("testNum") .asInt().valueSingle().calcSum() .ifNotExist().create(); + schema.propertyKey("rank") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("reword") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("student") - .properties("name", "worstScore", "bestScore", "testNum") + .properties("name", "worstScore", "bestScore", + "testNum", "rank", "reword") .primaryKeys("name") - .nullableKeys("worstScore", "bestScore", "testNum") + .nullableKeys("worstScore", "bestScore", + "testNum", "rank", "reword") .ifNotExist() .create(); graph.addVertex(T.label, "student", "name", "Tom", "worstScore", 55, - "bestScore", 96, "testNum", 1); + "bestScore", 96, "testNum", 1, "rank", 8, "reword", 8); graph.tx().commit(); Vertex tom = graph.traversal().V().hasLabel("student") @@ -5443,10 +5453,14 @@ public void testUpdateVertexPropertyOfAggregateType() { Assert.assertEquals(55, tom.value("worstScore")); Assert.assertEquals(96, tom.value("bestScore")); Assert.assertEquals(1, tom.value("testNum")); + Assert.assertEquals(ImmutableSet.of(8), tom.value("rank")); + Assert.assertEquals(ImmutableList.of(8), tom.value("reword")); tom.property("worstScore", 45); tom.property("bestScore", 98); tom.property("testNum", 1); + tom.property("rank", 12); + tom.property("reword", 12); graph.tx().commit(); tom = graph.traversal().V().hasLabel("student") @@ -5454,10 +5468,14 @@ public void testUpdateVertexPropertyOfAggregateType() { Assert.assertEquals(45, tom.value("worstScore")); Assert.assertEquals(98, tom.value("bestScore")); Assert.assertEquals(2, tom.value("testNum")); + Assert.assertEquals(ImmutableSet.of(8, 12), tom.value("rank")); + Assert.assertEquals(ImmutableList.of(8, 12), tom.value("reword")); tom.property("worstScore", 65); tom.property("bestScore", 99); tom.property("testNum", 1); + tom.property("rank", 8); + tom.property("reword", 8); graph.tx().commit(); tom = graph.traversal().V().hasLabel("student") @@ -5465,10 +5483,15 @@ public void testUpdateVertexPropertyOfAggregateType() { Assert.assertEquals(45, tom.value("worstScore")); Assert.assertEquals(99, tom.value("bestScore")); Assert.assertEquals(3, tom.value("testNum")); + Assert.assertEquals(ImmutableSet.of(8, 12), tom.value("rank")); + Assert.assertEquals(ImmutableList.of(8, 12, 8), + tom.value("reword")); tom.property("worstScore", 75); tom.property("bestScore", 100); tom.property("testNum", 1); + tom.property("rank", 1); + tom.property("reword", 1); graph.tx().commit(); tom = graph.traversal().V().hasLabel("student") @@ -5476,6 +5499,10 @@ public void testUpdateVertexPropertyOfAggregateType() { Assert.assertEquals(45, tom.value("worstScore")); Assert.assertEquals(100, tom.value("bestScore")); Assert.assertEquals(4, tom.value("testNum")); + Assert.assertEquals(ImmutableSet.of(1, 8, 12), + tom.value("rank")); + Assert.assertEquals(ImmutableList.of(8, 12, 8, 1), + tom.value("reword")); } @Test @@ -5495,26 +5522,38 @@ public void testAddAndUpdateVertexPropertyOfAggregateType() { schema.propertyKey("testNum") .asInt().valueSingle().calcSum() .ifNotExist().create(); + schema.propertyKey("rank") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("reword") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("student") - .properties("name", "worstScore", "bestScore", "testNum") + .properties("name", "worstScore", "bestScore", + "testNum", "rank", "reword") .primaryKeys("name") - .nullableKeys("worstScore", "bestScore", "testNum") + .nullableKeys("worstScore", "bestScore", + "testNum", "rank", "reword") .ifNotExist() .create(); Vertex tom = graph.addVertex(T.label, "student", "name", "Tom", "worstScore", 55, "bestScore", 96, - "testNum", 1); + "testNum", 1, "rank", 8, "reword", 8); tom.property("worstScore", 65); tom.property("bestScore", 94); tom.property("testNum", 2); + tom.property("rank", 12); + tom.property("reword", 12); Vertex result = graph.traversal().V().hasLabel("student") .has("name", "Tom").next(); Assert.assertEquals(65, result.value("worstScore")); Assert.assertEquals(94, result.value("bestScore")); Assert.assertEquals(2, result.value("testNum")); + Assert.assertEquals(ImmutableSet.of(8, 12), result.value("rank")); + Assert.assertEquals(ImmutableList.of(8, 12), result.value("reword")); graph.tx().commit(); @@ -5523,27 +5562,44 @@ public void testAddAndUpdateVertexPropertyOfAggregateType() { Assert.assertEquals(65, result.value("worstScore")); Assert.assertEquals(94, result.value("bestScore")); Assert.assertEquals(2, result.value("testNum")); + Assert.assertEquals(ImmutableSet.of(8, 12), result.value("rank")); + Assert.assertEquals(ImmutableList.of(8, 12), result.value("reword")); tom = graph.addVertex(T.label, "student", "name", "Tom", "worstScore", 55, "bestScore", 96, - "testNum", 1); + "testNum", 1, "rank", 2, "reword", 2); tom.property("worstScore", 75); tom.property("bestScore", 92); tom.property("testNum", 2); + tom.property("rank", 1); + tom.property("reword", 1); - Assert.assertEquals(65, tom.value("worstScore")); - Assert.assertEquals(94, tom.value("bestScore")); - Assert.assertEquals(4, tom.value("testNum")); - - Assert.assertEquals(65, tom.property("worstScore").value()); - Assert.assertEquals(94, tom.property("bestScore").value()); - Assert.assertEquals(4, tom.property("testNum").value()); + Assert.assertEquals(75, tom.value("worstScore")); + Assert.assertEquals(92, tom.value("bestScore")); + Assert.assertEquals(2, tom.value("testNum")); + Assert.assertEquals(ImmutableSet.of(1, 2), + tom.value("rank")); + Assert.assertEquals(ImmutableList.of(2, 1), + tom.value("reword")); + + Assert.assertEquals(75, tom.property("worstScore").value()); + Assert.assertEquals(92, tom.property("bestScore").value()); + Assert.assertEquals(2, tom.property("testNum").value()); + Assert.assertEquals(ImmutableSet.of(1, 2), + tom.property("rank").value()); + Assert.assertEquals(ImmutableList.of(2, 1), + tom.value("reword")); + graph.tx().commit(); result = graph.traversal().V().hasLabel("student") .has("name", "Tom").next(); Assert.assertEquals(65, result.value("worstScore")); Assert.assertEquals(94, result.value("bestScore")); Assert.assertEquals(4, result.value("testNum")); + Assert.assertEquals(ImmutableSet.of(1, 2, 8, 12), + result.value("rank")); + Assert.assertEquals(ImmutableList.of(8, 12, 2, 1), + result.value("reword")); } @Test @@ -5566,11 +5622,19 @@ public void testQueryVertexByAggregateProperty() { schema.propertyKey("no") .asText().valueSingle().calcOld() .ifNotExist().create(); + schema.propertyKey("rank") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("reword") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("student") - .properties("name", "worstScore", "bestScore", "testNum", "no") + .properties("name", "worstScore", "bestScore", + "testNum", "no", "rank", "reword") .primaryKeys("name") - .nullableKeys("worstScore", "bestScore", "testNum", "no") + .nullableKeys("worstScore", "bestScore", + "testNum", "no", "rank", "reword") .ifNotExist() .create(); @@ -5587,6 +5651,21 @@ public void testQueryVertexByAggregateProperty() { }); schema.indexLabel("studentByNo") .onV("student").by("no").secondary().ifNotExist().create(); + Assert.assertThrows(IllegalArgumentException.class, () -> { + schema.indexLabel("studentByRank") + .onV("student").by("rank").secondary().ifNotExist().create(); + }, e -> { + Assert.assertTrue(e.getMessage(), e.getMessage().contains( + "The aggregate type SET is not indexable")); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + schema.indexLabel("studentByReword") + .onV("student").by("reword").secondary().ifNotExist() + .create(); + }, e -> { + Assert.assertTrue(e.getMessage(), e.getMessage().contains( + "The aggregate type LIST is not indexable")); + }); graph.addVertex(T.label, "student", "name", "Tom", "worstScore", 55, "bestScore", 96, "testNum", 1, "no", "001"); @@ -5806,11 +5885,19 @@ public void testUpdateVertexWithAggregatePropertyMultiTimes() { schema.propertyKey("no") .asText().valueSingle().calcOld() .ifNotExist().create(); + schema.propertyKey("rank") + .asInt().valueSet().calcSet() + .ifNotExist().create(); + schema.propertyKey("reword") + .asInt().valueList().calcList() + .ifNotExist().create(); schema.vertexLabel("student") - .properties("name", "worstScore", "bestScore", "testNum", "no") + .properties("name", "worstScore", "bestScore", + "testNum", "no", "rank", "reword") .primaryKeys("name") - .nullableKeys("worstScore", "bestScore", "testNum", "no") + .nullableKeys("worstScore", "bestScore", + "testNum", "no", "rank", "reword") .ifNotExist() .create(); @@ -5829,7 +5916,8 @@ public void testUpdateVertexWithAggregatePropertyMultiTimes() { .onV("student").by("no").secondary().ifNotExist().create(); graph.addVertex(T.label, "student", "name", "Tom", "worstScore", 55, - "bestScore", 96, "testNum", 1, "no", "001"); + "bestScore", 96, "testNum", 1, "no", "001", + "rank", 1, "reword", 1); graph.tx().commit(); List vertices = graph.traversal().V().hasLabel("student") @@ -5840,12 +5928,27 @@ public void testUpdateVertexWithAggregatePropertyMultiTimes() { Assert.assertEquals(96, tom.value("bestScore")); Assert.assertEquals(1, tom.value("testNum")); Assert.assertEquals("001", tom.value("no")); - + Assert.assertEquals(ImmutableSet.of(1), tom.value("rank")); + Assert.assertEquals(ImmutableList.of(1), tom.value("reword")); + + Set ranks = new HashSet<>(); + List rewords = new ArrayList<>(); + int rank; + int reword; + ranks.add(1); + rewords.add(1); + Random random = new Random(); for (int i = 0; i < 100; i++) { tom.property("worstScore", 65); tom.property("bestScore", 94); tom.property("testNum", 1); tom.property("no", "002"); + rank = random.nextInt(); + ranks.add(rank); + tom.property("rank", rank); + reword = random.nextInt(); + rewords.add(reword); + tom.property("reword", reword); graph.tx().commit(); tom = graph.traversal().V().hasLabel("student") @@ -5855,6 +5958,8 @@ public void testUpdateVertexWithAggregatePropertyMultiTimes() { Assert.assertEquals(96, tom.value("bestScore")); Assert.assertEquals(i + 2, tom.value("testNum")); Assert.assertEquals("001", tom.value("no")); + Assert.assertEquals(ranks, tom.value("rank")); + Assert.assertEquals(rewords, tom.value("reword")); } } diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/util/JsonUtilTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/util/JsonUtilTest.java index aa8b4a8826..eb2521e072 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/util/JsonUtilTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/util/JsonUtilTest.java @@ -98,6 +98,7 @@ public void testSerializePropertyKey() { "\"data_type\":\"TEXT\"," + "\"cardinality\":\"SINGLE\"," + "\"aggregate_type\":\"NONE\"," + + "\"read_frequency\":\"OLTP\"," + "\"properties\":[],\"status\":\"CREATED\"," + "\"user_data\":{}}", json); @@ -107,8 +108,10 @@ public void testSerializePropertyKey() { json = JsonUtil.toJson(rate); Assert.assertEquals("{\"id\":2,\"name\":\"rate\"," + "\"data_type\":\"INT\",\"cardinality\":\"LIST\"," + - "\"aggregate_type\":\"NONE\",\"properties\":[]," + - "\"status\":\"CREATED\",\"user_data\":{}}", json); + "\"aggregate_type\":\"NONE\"," + + "\"read_frequency\":\"OLTP\"," + + "\"properties\":[],\"status\":\"CREATED\"," + + "\"user_data\":{}}", json); } @Test