diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java index 7462ead734..eb064f14d0 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java @@ -394,8 +394,13 @@ protected final void commitMutation2Backend(BackendMutation... mutations) { } } - // Update edge cache if any edges change - if (edgesInTxSize > 0 && this.enableCacheEdge()) { + /* + * Update edge cache if any vertex or edge changed + * For vertex change, the edges linked with should also be updated + * Before we find a more precise strategy, just clear all the edge cache now + */ + boolean invalidEdgesCache = (edgesInTxSize + updates.size() + deletions.size()) > 0; + if (invalidEdgesCache && this.enableCacheEdge()) { // TODO: Use a more precise strategy to update the edge cache this.edgesCache.clear(); this.notifyChanges(Cache.ACTION_CLEARED, HugeType.EDGE, null); diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/cache/CachedGraphTransactionTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/cache/CachedGraphTransactionTest.java index 6583a0730c..20fee3d735 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/cache/CachedGraphTransactionTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/cache/CachedGraphTransactionTest.java @@ -30,7 +30,9 @@ import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.backend.id.IdGenerator; import com.baidu.hugegraph.schema.VertexLabel; +import com.baidu.hugegraph.structure.HugeEdge; import com.baidu.hugegraph.structure.HugeVertex; +import com.baidu.hugegraph.structure.HugeVertexProperty; import com.baidu.hugegraph.testutil.Assert; import com.baidu.hugegraph.testutil.Whitebox; import com.baidu.hugegraph.type.HugeType; @@ -65,14 +67,27 @@ private CachedGraphTransaction cache() { private HugeVertex newVertex(Id id) { HugeGraph graph = this.cache().graph(); + graph.schema().propertyKey("name").asText() + .checkExist(false).create(); graph.schema().vertexLabel("person") - .idStrategy(IdStrategy.CUSTOMIZE_NUMBER) - .checkExist(false) - .create(); + .idStrategy(IdStrategy.CUSTOMIZE_NUMBER) + .properties("name").nullableKeys("name") + .checkExist(false) + .create(); VertexLabel vl = graph.vertexLabel("person"); return new HugeVertex(graph, id, vl); } + private HugeEdge newEdge(HugeVertex out, HugeVertex in) { + HugeGraph graph = this.cache().graph(); + graph.schema().edgeLabel("person_know_person") + .sourceLabel("person") + .targetLabel("person") + .checkExist(false) + .create(); + return out.addEdge("person_know_person", in); + } + @Test public void testEventClear() throws Exception { CachedGraphTransaction cache = this.cache(); @@ -125,4 +140,83 @@ public void testEventInvalid() throws Exception { Assert.assertEquals(2L, Whitebox.invoke(cache, "verticesCache", "size")); } + + @Test + public void testEdgeCacheClearWhenDeleteVertex() { + CachedGraphTransaction cache = this.cache(); + HugeVertex v1 = this.newVertex(IdGenerator.of(1)); + HugeVertex v2 = this.newVertex(IdGenerator.of(2)); + HugeVertex v3 = this.newVertex(IdGenerator.of(3)); + + cache.addVertex(v1); + cache.addVertex(v2); + cache.commit(); + HugeEdge edge = this.newEdge(v1, v2); + cache.addEdge(edge); + cache.commit(); + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(1)).hasNext()); + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(2)).hasNext()); + + Assert.assertEquals(2L, + Whitebox.invoke(cache, "edgesCache", "size")); + cache.removeVertex(v3); + cache.commit(); + Assert.assertEquals(0L, + Whitebox.invoke(cache, "edgesCache", "size")); + + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(1)).hasNext()); + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(2)).hasNext()); + Assert.assertEquals(2L, + Whitebox.invoke(cache, "edgesCache", "size")); + + cache.removeVertex(v1); + cache.commit(); + + Assert.assertEquals(0L, + Whitebox.invoke(cache, "edgesCache", "size")); + Assert.assertFalse(cache.queryEdgesByVertex(IdGenerator.of(2)).hasNext()); + } + + @Test + public void testEdgeCacheClearWhenUpdateVertex() { + CachedGraphTransaction cache = this.cache(); + HugeVertex v1 = this.newVertex(IdGenerator.of(1)); + HugeVertex v2 = this.newVertex(IdGenerator.of(2)); + HugeVertex v3 = this.newVertex(IdGenerator.of(3)); + + cache.addVertex(v1); + cache.addVertex(v2); + cache.commit(); + HugeEdge edge = this.newEdge(v1, v2); + cache.addEdge(edge); + cache.commit(); + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(1)).hasNext()); + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(2)).hasNext()); + + Assert.assertEquals(2L, + Whitebox.invoke(cache, "edgesCache", "size")); + + cache.addVertexProperty(new HugeVertexProperty<>(v3, + cache.graph().schema().getPropertyKey("name"), + "test-name")); + cache.commit(); + Assert.assertEquals(0L, + Whitebox.invoke(cache, "edgesCache", "size")); + + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(1)).hasNext()); + Assert.assertTrue(cache.queryEdgesByVertex(IdGenerator.of(2)).hasNext()); + Assert.assertEquals(2L, + Whitebox.invoke(cache, "edgesCache", "size")); + + cache.addVertexProperty(new HugeVertexProperty<>(v1, + cache.graph().schema().getPropertyKey("name"), + "test-name")); + cache.commit(); + + Assert.assertEquals(0L, + Whitebox.invoke(cache, "edgesCache", "size")); + String name = cache.queryEdgesByVertex(IdGenerator.of(1)).next().outVertex() + .value("name"); + Assert.assertEquals("test-name", name); + } }