blob: 87a81be5741d9ad8686fad36b15121d9372f5a04 [file] [log] [blame]
/*
* 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 org.apache.hugegraph.unit.cache;
import java.util.Iterator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.apache.hugegraph.HugeException;
import org.apache.hugegraph.HugeFactory;
import org.apache.hugegraph.HugeGraph;
import org.apache.hugegraph.backend.id.IdGenerator;
import org.apache.hugegraph.backend.store.ram.RamTable;
import org.apache.hugegraph.schema.EdgeLabel;
import org.apache.hugegraph.schema.SchemaManager;
import org.apache.hugegraph.schema.VertexLabel;
import org.apache.hugegraph.structure.HugeEdge;
import org.apache.hugegraph.structure.HugeVertex;
import org.apache.hugegraph.testutil.Assert;
import org.apache.hugegraph.type.define.Directions;
import org.apache.hugegraph.unit.FakeObjects;
public class RamTableTest {
// max value is 4 billion
private static final int VERTEX_SIZE = 10000000;
private static final int EDGE_SIZE = 20000000;
private HugeGraph graph;
@Before
public void setup() {
this.graph = HugeFactory.open(FakeObjects.newConfig());
SchemaManager schema = this.graph.schema();
schema.propertyKey("p3").asText().create();
schema.vertexLabel("vl1").useCustomizeNumberId().create();
schema.vertexLabel("vl2").useCustomizeNumberId().create();
schema.vertexLabel("vl3").useCustomizeStringId().create();
schema.edgeLabel("el1")
.sourceLabel("vl1")
.targetLabel("vl1")
.create();
schema.edgeLabel("el2")
.sourceLabel("vl2")
.targetLabel("vl2")
.create();
schema.edgeLabel("el3")
.sourceLabel("vl3")
.targetLabel("vl3")
.properties("p3")
.multiTimes()
.sortKeys("p3")
.create();
}
@After
public void teardown() throws Exception {
this.graph.close();
}
private HugeGraph graph() {
return this.graph;
}
@Test
public void testAddAndQuery() throws Exception {
HugeGraph graph = this.graph();
int el1 = (int) graph.edgeLabel("el1").id().asLong();
int el2 = (int) graph.edgeLabel("el2").id().asLong();
RamTable table = new RamTable(graph, VERTEX_SIZE, EDGE_SIZE);
long oldSize = table.edgesSize();
// insert edges
for (int i = 0; i < VERTEX_SIZE; i++) {
table.addEdge(true, i, i, Directions.OUT, el1);
Assert.assertEquals(oldSize + 2 * i + 1, table.edgesSize());
table.addEdge(false, i, i + 1, Directions.IN, el2);
Assert.assertEquals(oldSize + 2 * i + 2, table.edgesSize());
}
// query by BOTH
for (int i = 0; i < VERTEX_SIZE; i++) {
Iterator<HugeEdge> edges = table.query(i, Directions.BOTH, 0);
Assert.assertTrue(edges.hasNext());
HugeEdge edge1 = edges.next();
Assert.assertEquals(i, edge1.id().ownerVertexId().asLong());
Assert.assertEquals(i, edge1.id().otherVertexId().asLong());
Assert.assertEquals(Directions.OUT, edge1.direction());
Assert.assertEquals("el1", edge1.label());
Assert.assertTrue(edges.hasNext());
HugeEdge edge2 = edges.next();
Assert.assertEquals(i, edge2.id().ownerVertexId().asLong());
Assert.assertEquals(i + 1L, edge2.id().otherVertexId().asLong());
Assert.assertEquals(Directions.IN, edge2.direction());
Assert.assertEquals("el2", edge2.label());
Assert.assertFalse(edges.hasNext());
}
// query by OUT
for (int i = 0; i < VERTEX_SIZE; i++) {
Iterator<HugeEdge> edges = table.query(i, Directions.OUT, el1);
Assert.assertTrue(edges.hasNext());
HugeEdge edge1 = edges.next();
Assert.assertEquals(i, edge1.id().ownerVertexId().asLong());
Assert.assertEquals(i, edge1.id().otherVertexId().asLong());
Assert.assertEquals(Directions.OUT, edge1.direction());
Assert.assertEquals("el1", edge1.label());
Assert.assertFalse(edges.hasNext());
}
// query by IN
for (int i = 0; i < VERTEX_SIZE; i++) {
Iterator<HugeEdge> edges = table.query(i, Directions.IN, el2);
Assert.assertTrue(edges.hasNext());
HugeEdge edge1 = edges.next();
Assert.assertEquals(i, edge1.id().ownerVertexId().asLong());
Assert.assertEquals(i + 1L, edge1.id().otherVertexId().asLong());
Assert.assertEquals(Directions.IN, edge1.direction());
Assert.assertEquals("el2", edge1.label());
Assert.assertFalse(edges.hasNext());
}
// query by BOTH & label 1
for (int i = 0; i < VERTEX_SIZE; i++) {
Iterator<HugeEdge> edges = table.query(i, Directions.BOTH, el1);
Assert.assertTrue(edges.hasNext());
HugeEdge edge1 = edges.next();
Assert.assertEquals(i, edge1.id().ownerVertexId().asLong());
Assert.assertEquals(i, edge1.id().otherVertexId().asLong());
Assert.assertEquals(Directions.OUT, edge1.direction());
Assert.assertEquals("el1", edge1.label());
Assert.assertFalse(edges.hasNext());
}
// query by BOTH & label 2
for (int i = 0; i < VERTEX_SIZE; i++) {
Iterator<HugeEdge> edges = table.query(i, Directions.BOTH, el2);
Assert.assertTrue(edges.hasNext());
HugeEdge edge1 = edges.next();
Assert.assertEquals(i, edge1.id().ownerVertexId().asLong());
Assert.assertEquals(i + 1L, edge1.id().otherVertexId().asLong());
Assert.assertEquals(Directions.IN, edge1.direction());
Assert.assertEquals("el2", edge1.label());
Assert.assertFalse(edges.hasNext());
}
// query non-exist vertex
Iterator<HugeEdge> edges = table.query(VERTEX_SIZE, Directions.BOTH, 0);
Assert.assertFalse(edges.hasNext());
}
@Test
public void testAddAndQueryWithoutAdjEdges() throws Exception {
HugeGraph graph = this.graph();
int el1 = (int) graph.edgeLabel("el1").id().asLong();
int el2 = (int) graph.edgeLabel("el2").id().asLong();
RamTable table = new RamTable(graph, VERTEX_SIZE, EDGE_SIZE);
long oldSize = table.edgesSize();
// insert edges
for (int i = 0; i < VERTEX_SIZE; i++) {
if (i % 3 != 0) {
// don't insert edges for 2/3 vertices
continue;
}
table.addEdge(true, i, i, Directions.OUT, el1);
Assert.assertEquals(oldSize + i + 1, table.edgesSize());
table.addEdge(false, i, i, Directions.OUT, el2);
Assert.assertEquals(oldSize + i + 2, table.edgesSize());
table.addEdge(false, i, i + 1, Directions.IN, el2);
Assert.assertEquals(oldSize + i + 3, table.edgesSize());
}
// query by BOTH
for (int i = 0; i < VERTEX_SIZE; i++) {
Iterator<HugeEdge> edges = table.query(i, Directions.BOTH, 0);
if (i % 3 != 0) {
Assert.assertFalse(edges.hasNext());
continue;
}
Assert.assertTrue(edges.hasNext());
HugeEdge edge1 = edges.next();
Assert.assertEquals(i, edge1.id().ownerVertexId().asLong());
Assert.assertEquals(i, edge1.id().otherVertexId().asLong());
Assert.assertEquals(Directions.OUT, edge1.direction());
Assert.assertEquals("el1", edge1.label());
Assert.assertTrue(edges.hasNext());
HugeEdge edge2 = edges.next();
Assert.assertEquals(i, edge2.id().ownerVertexId().asLong());
Assert.assertEquals(i, edge2.id().otherVertexId().asLong());
Assert.assertEquals(Directions.OUT, edge2.direction());
Assert.assertEquals("el2", edge2.label());
Assert.assertTrue(edges.hasNext());
HugeEdge edge3 = edges.next();
Assert.assertEquals(i, edge3.id().ownerVertexId().asLong());
Assert.assertEquals(i + 1L, edge3.id().otherVertexId().asLong());
Assert.assertEquals(Directions.IN, edge3.direction());
Assert.assertEquals("el2", edge3.label());
Assert.assertFalse(edges.hasNext());
}
}
@Test
public void testAddInvalidVertexOrEdge() {
HugeGraph graph = this.graph();
VertexLabel vl3 = graph.vertexLabel("vl3");
EdgeLabel el3 = graph.edgeLabel("el3");
VertexLabel vl2 = graph.vertexLabel("vl2");
EdgeLabel el2 = graph.edgeLabel("el2");
RamTable table = new RamTable(graph, VERTEX_SIZE, EDGE_SIZE);
HugeVertex ownerVertex = new HugeVertex(graph, IdGenerator.of(1), vl3);
HugeEdge edge1 = HugeEdge.constructEdge(ownerVertex, true, el3, "marko",
IdGenerator.of(2));
Assert.assertThrows(HugeException.class, () -> {
table.addEdge(true, edge1);
}, e -> {
Assert.assertContains("Only edge label without sortkey is " +
"supported by ramtable, but got 'el3(id=3)'",
e.getMessage());
});
HugeVertex v1 = new HugeVertex(graph, IdGenerator.of("s1"), vl2);
HugeEdge edge2 = HugeEdge.constructEdge(v1, true, el2, "marko",
IdGenerator.of("s2"));
Assert.assertThrows(HugeException.class, () -> {
table.addEdge(true, edge2);
}, e -> {
Assert.assertContains("Only number id is supported by ramtable, " +
"but got string id 's1'", e.getMessage());
});
HugeVertex v2 = new HugeVertex(graph, IdGenerator.of(2), vl2);
HugeEdge edge3 = HugeEdge.constructEdge(v2, true, el2, "marko",
IdGenerator.of("s2"));
Assert.assertThrows(HugeException.class, () -> {
table.addEdge(true, edge3);
}, e -> {
Assert.assertContains("Only number id is supported by ramtable, " +
"but got string id 's2'", e.getMessage());
});
}
}