Skip to content

Commit

Permalink
feat(server): integrate server-hstore into hugegraph (#2534)
Browse files Browse the repository at this point in the history
subtask of #2265

When introducing hstore, server-core needs corresponding modifications. Except for BytesBuffer.java in hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/serializer/, other files should be consistent with the pd-store branch.

---------

Co-authored-by: imbajin <jin@apache.org>
  • Loading branch information
VGalaxies and imbajin committed May 6, 2024
1 parent 253b8d3 commit c1e8ea5
Show file tree
Hide file tree
Showing 32 changed files with 3,885 additions and 18 deletions.
26 changes: 26 additions & 0 deletions hugegraph-server/hugegraph-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,32 @@
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.apache.hugegraph</groupId>
<artifactId>hg-pd-client</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.apache.hugegraph</groupId>
<artifactId>hg-store-common</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<version>0.5.9</version>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ public String toString() {
/**
* This class is just used by backend store for wrapper object as Id
*/
private static final class ObjectId implements Id {
public static final class ObjectId implements Id {

private final Object object;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public enum ConditionType {
NONE,
RELATION,
AND,
OR
OR,
NOT
}

public enum RelationType implements BiPredicate<Object, Object> {
Expand Down Expand Up @@ -300,7 +301,8 @@ public boolean isRelation() {

public boolean isLogic() {
return this.type() == ConditionType.AND ||
this.type() == ConditionType.OR;
this.type() == ConditionType.OR ||
this.type() == ConditionType.NOT;
}

public boolean isFlattened() {
Expand All @@ -315,6 +317,10 @@ public static Condition or(Condition left, Condition right) {
return new Or(left, right);
}

public static Condition not(Condition condition) {
return new Not(condition);
}

public static Relation eq(HugeKeys key, Object value) {
return new SyspropRelation(key, RelationType.EQ, value);
}
Expand Down Expand Up @@ -536,6 +542,80 @@ public Condition copy() {
}
}

public static class Not extends Condition {

Condition condition;

public Not(Condition condition) {
super();
this.condition = condition;
}

public Condition condition() {
return condition;
}

@Override
public ConditionType type() {
return ConditionType.NOT;
}

@Override
public boolean test(Object value) {
return !this.condition.test(value);
}

@Override
public boolean test(HugeElement element) {
return !this.condition.test(element);
}

@Override
public Condition copy() {
return new Not(this.condition.copy());
}

@Override
public boolean isSysprop() {
return this.condition.isSysprop();
}

@Override
public List<? extends Relation> relations() {
return new ArrayList<Relation>(this.condition.relations());
}

@Override
public Condition replace(Relation from, Relation to) {
this.condition = this.condition.replace(from, to);
return this;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder(64);
sb.append(this.type().name()).append(' ');
sb.append(this.condition);
return sb.toString();
}

@Override
public boolean equals(Object object) {
if (!(object instanceof Not)) {
return false;
}
Not other = (Not) object;
return this.type().equals(other.type()) &&
this.condition.equals(other.condition());
}

@Override
public int hashCode() {
return this.type().hashCode() ^
this.condition.hashCode();
}
}

public abstract static class Relation extends Condition {

// Relational operator (like: =, >, <, in, ...)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.hugegraph.backend.query;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -34,6 +35,8 @@
import org.apache.hugegraph.backend.id.SplicingIdGenerator;
import org.apache.hugegraph.backend.query.Condition.Relation;
import org.apache.hugegraph.backend.query.Condition.RelationType;
import org.apache.hugegraph.backend.query.serializer.QueryAdapter;
import org.apache.hugegraph.backend.query.serializer.QueryIdAdapter;
import org.apache.hugegraph.perf.PerfUtil.Watched;
import org.apache.hugegraph.structure.HugeElement;
import org.apache.hugegraph.structure.HugeProperty;
Expand All @@ -48,6 +51,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ConditionQuery extends IdQuery {

Expand All @@ -73,6 +78,12 @@ public class ConditionQuery extends IdQuery {

private static final List<Condition> EMPTY_CONDITIONS = ImmutableList.of();

private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(Condition.class, new QueryAdapter())
.registerTypeAdapter(Id.class, new QueryIdAdapter())
.setDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.create();

// Conditions will be contacted with `and` by default
private List<Condition> conditions = EMPTY_CONDITIONS;

Expand Down Expand Up @@ -220,6 +231,31 @@ public Relation relation(Id key) {
return null;
}

public boolean containsLabelOrUserpropRelation() {
for (Condition c : this.conditions) {
while (c instanceof Condition.Not) {
c = ((Condition.Not) c).condition();
}
if (c.isLogic()) {
Condition.BinCondition binCondition =
(Condition.BinCondition) c;
ConditionQuery query = new ConditionQuery(HugeType.EDGE);
query.query(binCondition.left());
query.query(binCondition.right());
if (query.containsLabelOrUserpropRelation()) {
return true;
}
} else {
Condition.Relation r = (Condition.Relation) c;
if (r.key().equals(HugeKeys.LABEL) ||
c instanceof Condition.UserpropRelation) {
return true;
}
}
}
return false;
}

@Watched
public <T> T condition(Object key) {
List<Object> valuesEQ = InsertionOrderUtil.newList();
Expand Down Expand Up @@ -300,6 +336,19 @@ public boolean containsCondition(HugeKeys key) {
return false;
}

public boolean containsCondition(Condition.RelationType type) {
for (Relation r : this.relations()) {
if (r.relation().equals(type)) {
return true;
}
}
return false;
}

public boolean containsScanCondition() {
return this.containsCondition(Condition.RelationType.SCAN);
}

public boolean containsRelation(HugeKeys key, Condition.RelationType type) {
for (Relation r : this.relations()) {
if (r.key().equals(key) && r.relation().equals(type)) {
Expand Down Expand Up @@ -702,6 +751,18 @@ public static String concatValues(Object value) {
}
}

public static ConditionQuery fromBytes(byte[] bytes) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Condition.class, new QueryAdapter())
.registerTypeAdapter(Id.class, new QueryIdAdapter())
.setDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.create();
String cqs = new String(bytes, StandardCharsets.UTF_8);
ConditionQuery conditionQuery = gson.fromJson(cqs, ConditionQuery.class);

return conditionQuery;
}

private static boolean needConvertNumber(Object value) {
// Numeric or date values should be converted to number from string
return NumericUtil.isNumber(value) || value instanceof Date;
Expand Down Expand Up @@ -891,4 +952,9 @@ public interface ResultsFilter {

boolean test(HugeElement element);
}

public byte[] bytes() {
String cqs = gson.toJson(this);
return cqs.getBytes(StandardCharsets.UTF_8);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@ public class Query implements Cloneable {
private long actualOffset;
private long actualStoreOffset;
private long limit;
private long skipDegree;
private String page;
private long capacity;
private boolean showHidden;
private boolean showDeleting;
private boolean showExpired;
private boolean olap;
private boolean withProperties;
private OrderType orderType;
private Set<Id> olapPks;

private Aggregate aggregate;
Expand All @@ -88,13 +91,17 @@ public Query(HugeType resultType, Query originQuery) {
this.actualOffset = 0L;
this.actualStoreOffset = 0L;
this.limit = NO_LIMIT;
this.skipDegree = NO_LIMIT;
this.page = null;

this.capacity = defaultCapacity();

this.showHidden = false;
this.showDeleting = false;

this.withProperties = true;
this.orderType = OrderType.ORDER_STRICT;

this.aggregate = null;
this.showExpired = false;
this.olap = false;
Expand All @@ -105,10 +112,13 @@ public void copyBasic(Query query) {
E.checkNotNull(query, "query");
this.offset = query.offset();
this.limit = query.limit();
this.skipDegree = query.skipDegree();
this.page = query.page();
this.capacity = query.capacity();
this.showHidden = query.showHidden();
this.showDeleting = query.showDeleting();
this.withProperties = query.withProperties();
this.orderType = query.orderType();
this.aggregate = query.aggregate();
this.showExpired = query.showExpired();
this.olap = query.olap();
Expand Down Expand Up @@ -441,6 +451,30 @@ public void showDeleting(boolean showDeleting) {
this.showDeleting = showDeleting;
}

public long skipDegree() {
return this.skipDegree;
}

public void skipDegree(long skipDegree) {
this.skipDegree = skipDegree;
}

public boolean withProperties() {
return this.withProperties;
}

public void withProperties(boolean withProperties) {
this.withProperties = withProperties;
}

public OrderType orderType() {
return this.orderType;
}

public void orderType(OrderType orderType) {
this.orderType = orderType;
}

public boolean showExpired() {
return this.showExpired;
}
Expand Down Expand Up @@ -493,7 +527,8 @@ public boolean equals(Object object) {
this.limit == other.limit &&
Objects.equals(this.page, other.page) &&
this.ids().equals(other.ids()) &&
this.conditions().equals(other.conditions());
this.conditions().equals(other.conditions()) &&
this.withProperties == other.withProperties;
}

@Override
Expand All @@ -504,7 +539,8 @@ public int hashCode() {
Long.hashCode(this.limit) ^
Objects.hashCode(this.page) ^
this.ids().hashCode() ^
this.conditions().hashCode();
this.conditions().hashCode() ^
Boolean.hashCode(this.withProperties);
}

@Override
Expand Down Expand Up @@ -580,6 +616,13 @@ public static void checkForceCapacity(long count) throws LimitExceedException {
}
}

public enum OrderType {
// 批量接口下,返回顺序的要求
ORDER_NONE, // 允许无序
ORDER_WITHIN_VERTEX, // 一个点内的边不会被打断,单不同点之间为无序
ORDER_STRICT // 保证原始的输入点顺序
}

public enum Order {
ASC,
DESC
Expand Down
Loading

0 comments on commit c1e8ea5

Please sign in to comment.