Compare commits

...

4 Commits

Author SHA1 Message Date
zhoney f4031f1e05 fix bug: remove secondary index of cassandra backend exceeding 65535 limit (#387)
fixed: #384

Change-Id: I3b0db265b621c149404a97ab688af8bd2e4ca4bd
2019-03-08 19:57:12 +08:00
zhangyi51 6eaeee81d8 fix bug: index rebuild exceeds 80w limit and 65536 cassandra limit
fixed: #291

Change-Id: Iadf1b18c7a1be7a6343ae1fdeffbdb268ee1be90
2018-12-26 03:05:52 -06:00
zhangyi51 e8f81d47e3 fix bug: query vertices by ids with hasId() filter when using number id
Also improve exception message for query by labels
where one of labels is not exist

fixed: #302

Change-Id: I71f299061002b680a1b9d76f2bf4b34ed0f9f3cc
2018-12-26 14:39:31 +08:00
liningrui 5711f371e5 HugeGraph-1358: Release 0.8.0
Change-Id: I053af3e5fde3ce0ffec58e842e1c01e53b770cdd
2018-11-29 16:26:56 +08:00
9 changed files with 158 additions and 34 deletions

View File

@ -1,8 +1,8 @@
# HugeGraph
[![License](https://img.shields.io/badge/license-Apache%202-0E78BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Build Status](https://travis-ci.org/hugegraph/hugegraph.svg?branch=master)](https://travis-ci.org/hugegraph/hugegraph)
[![codecov](https://codecov.io/gh/hugegraph/hugegraph/branch/master/graph/badge.svg)](https://codecov.io/gh/hugegraph/hugegraph)
[![Build Status](https://travis-ci.org/hugegraph/hugegraph.svg?branch=release-0.8)](https://travis-ci.org/hugegraph/hugegraph)
[![codecov](https://codecov.io/gh/hugegraph/hugegraph/branch/release-0.8/graph/badge.svg)](https://codecov.io/gh/hugegraph/hugegraph)
HugeGraph is a fast-speed and highly-scalable [graph database](https://en.wikipedia.org/wiki/Graph_database). Billions of vertices and edges can be easily stored into and queried from HugeGraph due to its excellent OLTP ability. As compliance to [Apache TinkerPop 3](https://tinkerpop.apache.org/) framework, various complicated graph queries can be accomplished through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful graph traversal language).

View File

@ -558,12 +558,18 @@ public class CassandraTables {
}
final String FIELD_VALUES = formatKey(HugeKeys.FIELD_VALUES);
int count = 0;
for (Iterator<Row> it = rs.iterator(); it.hasNext();) {
fieldValues = it.next().get(FIELD_VALUES, String.class);
Delete delete = QueryBuilder.delete().from(this.table());
delete.where(formatEQ(HugeKeys.INDEX_LABEL_ID, indexLabel));
delete.where(formatEQ(HugeKeys.FIELD_VALUES, fieldValues));
session.add(delete);
if (++count >= COMMIT_DELETE_BATCH) {
session.commit();
count = 0;
}
}
}

View File

@ -184,10 +184,10 @@ public abstract class IdGenerator {
@Override
public boolean equals(Object other) {
if (!(other instanceof LongId)) {
if (!(other instanceof Number)) {
return false;
}
return this.id == ((LongId) other).id;
return this.id == ((Number) other).longValue();
}
@Override

View File

@ -1324,7 +1324,7 @@ public class GraphTransaction extends IndexableTransaction {
this.traverseVerticesByLabel(vertexLabel, vertex -> {
this.removeVertex((HugeVertex) vertex);
this.commitIfGtSize(COMMIT_BATCH);
});
}, true);
this.commit();
} catch (Exception e) {
LOG.error("Failed to remove vertices", e);
@ -1354,7 +1354,7 @@ public class GraphTransaction extends IndexableTransaction {
this.traverseEdgesByLabel(edgeLabel, edge -> {
this.removeEdge((HugeEdge) edge);
this.commitIfGtSize(COMMIT_BATCH);
});
}, true);
}
this.commit();
} catch (Exception e) {
@ -1366,18 +1366,19 @@ public class GraphTransaction extends IndexableTransaction {
}
public void traverseVerticesByLabel(VertexLabel label,
Consumer<Vertex> consumer) {
this.traverseByLabel(label, this::queryVertices, consumer);
Consumer<Vertex> consumer,
boolean remove) {
this.traverseByLabel(label, this::queryVertices, consumer, remove);
}
public void traverseEdgesByLabel(EdgeLabel label,
Consumer<Edge> consumer) {
this.traverseByLabel(label, this::queryEdges, consumer);
public void traverseEdgesByLabel(EdgeLabel label, Consumer<Edge> consumer,
boolean remove) {
this.traverseByLabel(label, this::queryEdges, consumer, remove);
}
private <T> void traverseByLabel(SchemaLabel label,
Function<Query, Iterator<T>> fetcher,
Consumer<T> consumer) {
Consumer<T> consumer, boolean remove) {
HugeType type = label.type() == HugeType.VERTEX_LABEL ?
HugeType.VERTEX : HugeType.EDGE;
ConditionQuery query = new ConditionQuery(type);
@ -1405,12 +1406,14 @@ public class GraphTransaction extends IndexableTransaction {
* Query.DEFAULT_CAPACITY to limit elements number per pass
*/
query.limit(Query.DEFAULT_CAPACITY);
query.capacity(Query.DEFAULT_CAPACITY);
query.capacity(Query.NO_CAPACITY);
query.eq(HugeKeys.LABEL, label.id());
int pass = 0;
int counter = 0;
int counter;
do {
query.offset(pass++ * Query.DEFAULT_CAPACITY);
if (!remove) {
query.offset(pass++ * Query.DEFAULT_CAPACITY);
}
// Process every element in current batch
Iterator<T> itor = fetcher.apply(query);
for (counter = 0; itor.hasNext(); ++counter) {

View File

@ -57,6 +57,15 @@ public abstract class IndexableTransaction extends AbstractTransaction {
this.commitMutation2Backend(mutation, txMutation);
}
@Override
public void commitIfGtSize(int size) throws BackendException {
int totalSize = this.mutationSize() +
this.indexTransaction().mutationSize();
if (totalSize >= size) {
this.commit();
}
}
@Override
public void rollback() throws BackendException {
try {

View File

@ -123,12 +123,14 @@ public class RebuildIndexCallable extends SchemaCallable {
if (label.type() == HugeType.VERTEX_LABEL) {
@SuppressWarnings("unchecked")
Consumer<Vertex> consumer = (Consumer<Vertex>) indexUpdater;
graphTx.traverseVerticesByLabel((VertexLabel) label, consumer);
graphTx.traverseVerticesByLabel((VertexLabel) label,
consumer, false);
} else {
assert label.type() == HugeType.EDGE_LABEL;
@SuppressWarnings("unchecked")
Consumer<Edge> consumer = (Consumer<Edge>) indexUpdater;
graphTx.traverseEdgesByLabel((EdgeLabel) label, consumer);
graphTx.traverseEdgesByLabel((EdgeLabel) label,
consumer, false);
}
graphTx.commit();

View File

@ -362,25 +362,31 @@ public final class TraversalUtil {
assert bp instanceof Contains;
List<?> values = (List<?>) has.getValue();
try {
String originKey = has.getKey();
if (values.size() > 1) {
E.checkArgument(!originKey.equals(T.key) &&
!originKey.equals(T.value),
"Not support hasKey() or hasValue() with " +
"multiple values");
}
HugeKeys key = string2HugeKey(originKey);
values = convSysListValueIfNeeded(graph, type, key, values);
String originKey = has.getKey();
if (values.size() > 1) {
E.checkArgument(!originKey.equals(T.key) &&
!originKey.equals(T.value),
"Not support hasKey() or hasValue() with " +
"multiple values");
}
HugeKeys hugeKey = null;
try {
hugeKey = string2HugeKey(originKey);
} catch (IllegalArgumentException ignored) {
// Ignore
}
if (hugeKey != null) {
values = convSysListValueIfNeeded(graph, type, hugeKey, values);
switch ((Contains) bp) {
case within:
return Condition.in(key, values);
return Condition.in(hugeKey, values);
case without:
return Condition.nin(key, values);
return Condition.nin(hugeKey, values);
}
} catch (IllegalArgumentException e) {
} else {
String key = has.getKey();
PropertyKey pkey = graph.propertyKey(key);

View File

@ -479,11 +479,14 @@ public class HbaseSessions extends BackendSessionPool {
public RowIterator(Result... results) {
this.resultScanner = null;
if (results.length == 1 && results[0].isEmpty()) {
this.results = Collections.emptyIterator();
} else {
this.results = Arrays.asList(results).iterator();
List<Result> rs = new ArrayList<>(results.length);
for (Result result : results) {
// Get by Ids may return empty result
if (!result.isEmpty()) {
rs.add(result);
}
}
this.results = rs.iterator();
}
@Override

View File

@ -3302,6 +3302,101 @@ public class VertexCoreTest extends BaseCoreTest {
});
}
@Test
public void testQueryVerticesByIdsWithHasIdFilterAndNumberId() {
HugeGraph graph = graph();
SchemaManager schema = graph.schema();
schema.vertexLabel("user").useCustomizeNumberId().create();
graph.addVertex(T.label, "user", T.id, 123);
graph.addVertex(T.label, "user", T.id, 456);
graph.addVertex(T.label, "user", T.id, 789);
graph.tx().commit();
GraphTraversalSource g = graph.traversal();
List<Vertex> vertices;
vertices = g.V().hasId(P.within(123)).toList();
Assert.assertEquals(1, vertices.size());
vertices = g.V(123, 456).hasId(P.within(123)).toList();
Assert.assertEquals(1, vertices.size());
vertices = g.V(123, 456).hasId(123).toList();
Assert.assertEquals(1, vertices.size());
vertices = g.V(123, 456, 789).hasId(P.within(123, 456)).toList();
Assert.assertEquals(2, vertices.size());
vertices = g.V(123, 456, 789).hasId(456, 789).toList();
Assert.assertEquals(2, vertices.size());
vertices = g.V(123, 456, 789).hasId(P.within(123, 456, 789)).toList();
Assert.assertEquals(3, vertices.size());
}
@Test
public void testQueryVerticesByLabelsWithOneLabelNotExist() {
HugeGraph graph = graph();
SchemaManager schema = graph.schema();
schema.vertexLabel("user1").useCustomizeNumberId().create();
schema.vertexLabel("user2").useCustomizeNumberId().create();
graph.addVertex(T.label, "user1", T.id, 123);
graph.addVertex(T.label, "user2", T.id, 456);
graph.addVertex(T.label, "user2", T.id, 789);
graph.tx().commit();
GraphTraversalSource g = graph.traversal();
List<Vertex> vertices;
vertices = g.V().hasLabel("user1").toList();
Assert.assertEquals(1, vertices.size());
vertices = g.V().hasLabel("user2").toList();
Assert.assertEquals(2, vertices.size());
vertices = g.V().hasLabel("user1", "user2").toList();
Assert.assertEquals(3, vertices.size());
Assert.assertThrows(IllegalArgumentException.class, () -> {
g.V().hasLabel("user3").toList();
}, e -> {
Assert.assertEquals("Undefined vertex label: 'user3'",
e.getMessage());
});
Assert.assertThrows(IllegalArgumentException.class, () -> {
g.V().hasLabel("user1", "user3").toList();
}, e -> {
Assert.assertEquals("Undefined vertex label: 'user3'",
e.getMessage());
});
Assert.assertThrows(IllegalArgumentException.class, () -> {
g.V().hasLabel("user3", "user1").toList();
}, e -> {
Assert.assertEquals("Undefined vertex label: 'user3'",
e.getMessage());
});
Assert.assertThrows(IllegalArgumentException.class, () -> {
g.V().hasLabel("user3", "user4").toList();
}, e -> {
Assert.assertEquals("Undefined vertex label: 'user3'",
e.getMessage());
});
Assert.assertThrows(IllegalArgumentException.class, () -> {
g.V().hasLabel("user4", "user3").toList();
}, e -> {
Assert.assertEquals("Undefined vertex label: 'user4'",
e.getMessage());
});
}
private void init10Vertices() {
HugeGraph graph = graph();