Skip to content

Commit

Permalink
all tets are passing again, bit faster but Schema.getEdgeLabels need …
Browse files Browse the repository at this point in the history
…optimizing or caching
  • Loading branch information
pieter committed Nov 18, 2016
1 parent 4edc3d7 commit 555bc6e
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 17 deletions.
3 changes: 2 additions & 1 deletion TinkerPopTODO
Expand Up @@ -2,4 +2,5 @@
Why? Optional paths may or may not contain the label. Return an Optional instead?
* .select(...) returns an empty list is a labels in the var args is not found.
Why n ot just return what is found as opposed to nothing is a particular label is not found.
Also because of Optional
Also because of Optional

3 changes: 2 additions & 1 deletion sqlg-core/src/main/java/org/umlg/sqlg/structure/Schema.java
Expand Up @@ -412,7 +412,7 @@ Map<String, Map<String, PropertyType>> getUncommittedLabels() {
}
for (EdgeLabel edgeLabel : this.getUncommittedEdgeLabels()) {
String edgeQualifiedName = this.name + "." + EDGE_PREFIX + edgeLabel.getLabel();
result.put(edgeQualifiedName, edgeLabel.getPropertyTypeMap());
result.put(edgeQualifiedName, edgeLabel.getUncommittedPropertyTypeMap());
}
return result;
}
Expand Down Expand Up @@ -815,6 +815,7 @@ void fromNotifyJsonOutEdges(JsonNode jsonSchema) {
this.vertexLabels.put(vertexLabelName, vertexLabel);
}
vertexLabel.fromNotifyJsonOutEdge(vertexLabelJson);
this.getTopology().addToAllTables(this.getName() + "." + VERTEX_PREFIX + vertexLabelName, vertexLabel.getPropertyTypeMap());
}
}
}
Expand Down
Expand Up @@ -56,6 +56,11 @@
method = "shouldRollbackElementAutoTransactionByDefault",
reason = "Fails for HSQLDB as HSQLDB commits the transaction on schema creation and buggers the rollback test logic.")

@Graph.OptOut(
test = "org.apache.tinkerpop.gremlin.structure.TransactionTest",
method = "shouldSupportTransactionIsolationCommitCheck",
reason = "Fails for as the schema creation deadlock because of unnatural locking in the test.")

@Graph.OptOut(
test = "org.apache.tinkerpop.gremlin.structure.TransactionTest",
method = "shouldRollbackElementAutoTransactionByDefault",
Expand Down
17 changes: 16 additions & 1 deletion sqlg-core/src/main/java/org/umlg/sqlg/structure/Topology.java
Expand Up @@ -849,6 +849,10 @@ public Optional<EdgeLabel> getEdgeLabel(String schemaName, String edgeLabelName)
}
}

/**
* This only returns uncommitted values. So committed properties will not be in the map.
* @return A map or uncommitted properties for all Vertex and Edge labels.
*/
private Map<String, Map<String, PropertyType>> getUncommittedAllTables() {
Preconditions.checkState(isWriteLockHeldByCurrentThread());
Map<String, Map<String, PropertyType>> result = new HashMap<>();
Expand All @@ -868,7 +872,14 @@ public Map<String, Map<String, PropertyType>> getAllTables() {
try {
Map<String, Map<String, PropertyType>> result = new HashMap<>(this.allTableCache);
if (this.isWriteLockHeldByCurrentThread()) {
result.putAll(this.getUncommittedAllTables());
Map<String, Map<String, PropertyType>> uncommittedTables = this.getUncommittedAllTables();
for (String table : uncommittedTables.keySet()) {
if (result.containsKey(table)) {
result.get(table).putAll(uncommittedTables.get(table));
} else {
result.put(table, uncommittedTables.get(table));
}
}
}
for (String sqlgSchemaSchemaTable : SQLG_SCHEMA_SCHEMA_TABLES) {
result.remove(sqlgSchemaSchemaTable);
Expand Down Expand Up @@ -991,4 +1002,8 @@ public Map<String, Set<String>> getAllEdgeForeignKeys() {
z_internalReadUnLock();
}
}

void addToAllTables(String tableName, Map<String, PropertyType> propertyTypeMap) {
this.allTableCache.put(tableName, propertyTypeMap);
}
}
Expand Up @@ -105,6 +105,12 @@ Set<EdgeLabel> getUncommittedOutEdgeLabels() {
Set<EdgeLabel> result = new HashSet<>();
if (this.schema.getTopology().isWriteLockHeldByCurrentThread()) {
result.addAll(this.uncommittedOutEdgeLabels);
for (EdgeLabel outEdgeLabel : this.outEdgeLabels) {
Map<String, PropertyType> propertyMap = outEdgeLabel.getUncommittedPropertyTypeMap();
if (!propertyMap.isEmpty()) {
result.add(outEdgeLabel);
}
}
}
return result;
}
Expand Down Expand Up @@ -400,6 +406,9 @@ void fromNotifyJsonOutEdge(JsonNode vertexLabelJson) {
edgeLabel.addToOutVertexLabel(this);
this.outEdgeLabels.add(edgeLabel);
edgeLabel.fromPropertyNotifyJson(uncommittedOutEdgeLabel);
//Babysit the cache
this.getSchema().getTopology().addToAllTables(getSchema().getName() + "." + EDGE_PREFIX + edgeLabel.getLabel(), edgeLabel.getPropertyTypeMap());
this.getSchema().addToAllEdgeCache(edgeLabel);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion sqlg-test/src/main/java/org/umlg/sqlg/AllTest.java
Expand Up @@ -150,7 +150,8 @@
TestLabelsSchema.class,
//TODO fails, issue #65
// TestEdgeFromDifferentSchema.class
TestBatchModeMultipleGraphs.class
TestBatchModeMultipleGraphs.class,
TestDetachedEdge.class
})
public class AllTest {
}
6 changes: 1 addition & 5 deletions sqlg-test/src/main/java/org/umlg/sqlg/AnyTest.java
Expand Up @@ -10,11 +10,7 @@
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestTraversalPerformance.class
// TestAddVertexViaMap.class
// LocalDateTest.class
// TestLoadSchema.class
// TestSchema.class
TestTraversalPerformance.class,
})
public class AnyTest {
}
@@ -0,0 +1,53 @@
package org.umlg.sqlg.test.edges;

import org.apache.tinkerpop.gremlin.structure.*;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import org.junit.Test;
import org.umlg.sqlg.test.BaseTest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
* Date: 2016/11/17
* Time: 10:15 PM
*/
public class TestDetachedEdge extends BaseTest {


@Test
public void shouldConstructDetachedEdge() {
loadModern();
Object edgeId = convertToEdgeId("marko", "knows", "vadas");
this.sqlgGraph.traversal().E(edgeId).next().property("year", 2002);
Edge next = this.sqlgGraph.traversal().E(edgeId).next();

assertTrue(this.sqlgGraph.traversal().E(edgeId).next().property("year").isPresent());

final DetachedEdge detachedEdge = DetachedFactory.detach(next, true);
assertEquals(convertToEdgeId("marko", "knows", "vadas"), detachedEdge.id());
assertEquals("knows", detachedEdge.label());
assertEquals(DetachedVertex.class, detachedEdge.vertices(Direction.OUT).next().getClass());
assertEquals(convertToVertexId("marko"), detachedEdge.vertices(Direction.OUT).next().id());
assertEquals("person", detachedEdge.vertices(Direction.IN).next().label());
assertEquals(DetachedVertex.class, detachedEdge.vertices(Direction.IN).next().getClass());
assertEquals(convertToVertexId("vadas"), detachedEdge.vertices(Direction.IN).next().id());
assertEquals("person", detachedEdge.vertices(Direction.IN).next().label());

assertEquals(2, IteratorUtils.count(detachedEdge.properties()));
assertEquals(1, IteratorUtils.count(detachedEdge.properties("year")));
assertEquals(0.5d, detachedEdge.properties("weight").next().value());
}

public Object convertToEdgeId(final String outVertexName, String edgeLabel, final String inVertexName) {
return convertToEdgeId(this.sqlgGraph, outVertexName, edgeLabel, inVertexName);
}

public Object convertToEdgeId(final Graph graph, final String outVertexName, String edgeLabel, final String inVertexName) {
return graph.traversal().V().has("name", outVertexName).outE(edgeLabel).as("e").inV().has("name", inVertexName).<Edge>select("e").next().id();
}

}
@@ -1,24 +1,42 @@
package org.umlg.sqlg.test.edges;

import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.junit.Assert;
import org.junit.Test;
import org.umlg.sqlg.structure.SqlgGraph;
import org.umlg.sqlg.test.BaseTest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
* Date: 2014/10/04
* Time: 12:33 PM
*/
public class TestEdgeCache extends BaseTest {

@Test
public void testEdgeUncommittedProperties() {
Vertex a1 = this.sqlgGraph.addVertex(T.label, "A");
Vertex b1 = this.sqlgGraph.addVertex(T.label, "B");
Edge e = a1.addEdge("ab", b1, "name", "test");
this.sqlgGraph.tx().commit();
e.property("test", "this");
assertTrue(this.sqlgGraph.traversal().E(e.id()).next().property("name").isPresent());
assertTrue(this.sqlgGraph.traversal().E(e.id()).next().property("test").isPresent());
this.sqlgGraph.traversal().E(e.id()).next().property("name1", "test");
this.sqlgGraph.traversal().E(e.id()).next().property("test1", "test2");
assertTrue(this.sqlgGraph.traversal().E(e.id()).next().property("name1").isPresent());
assertTrue(this.sqlgGraph.traversal().E(e.id()).next().property("test1").isPresent());
}

@Test
public void testEdgeCreateEndsUpInVertexEdgeCache() {
Vertex v1 = this.sqlgGraph.addVertex(T.label, "Person");
Vertex v2 = this.sqlgGraph.addVertex(T.label, "Person");
v1.addEdge("friend", v2);
Assert.assertEquals(1, vertexTraversal(v1).out("friend").count().next().intValue());
assertEquals(1, vertexTraversal(v1).out("friend").count().next().intValue());
this.sqlgGraph.tx().commit();
}

Expand All @@ -35,8 +53,8 @@ public void testMultipleEdgesFromSameVertex() throws Exception {
this.sqlgGraph.close();
try (SqlgGraph sqlgGraph = SqlgGraph.open(configuration)) {
v1 = sqlgGraph.v(v1.id());
Assert.assertEquals(1, sqlgGraph.traversal().V(v1.id()).out("bts_btsalm").count().next().intValue());
Assert.assertEquals(1, sqlgGraph.traversal().V(v1.id()).out("bts_btsalmtos").count().next().intValue());
assertEquals(1, sqlgGraph.traversal().V(v1.id()).out("bts_btsalm").count().next().intValue());
assertEquals(1, sqlgGraph.traversal().V(v1.id()).out("bts_btsalmtos").count().next().intValue());
}
}
}
Expand Up @@ -33,7 +33,7 @@ public void testSpeed() throws InterruptedException {
}
//Create a large schema, it slows the maps down
// this.sqlgGraph.tx().normalBatchModeOn();
for (int i = 0; i < 100; i++) {
for (int i = 0; i < 10; i++) {
if (i % 100 == 0) {
stopWatch.stop();
System.out.println("got " + i + " time taken " + stopWatch.toString());
Expand Down
Expand Up @@ -5,7 +5,10 @@
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.junit.*;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
import org.umlg.sqlg.structure.SqlgGraph;
import org.umlg.sqlg.test.BaseTest;

Expand Down Expand Up @@ -45,6 +48,7 @@ public void testLazyLoadTableViaVertexHas() throws Exception {
Thread.sleep(1000);
Assert.assertEquals(1, sqlgGraph1.traversal().V().count().next().intValue());
Assert.assertEquals(1, sqlgGraph1.traversal().V().has(T.label, "Person").count().next().intValue());
Assert.assertEquals("a", sqlgGraph1.traversal().V().has(T.label, "Person").next().value("name"));
sqlgGraph1.tx().rollback();
}
}
Expand Down Expand Up @@ -171,14 +175,15 @@ public void testLoadSchemaEdge() throws Exception {
try (SqlgGraph sqlgGraph1 = SqlgGraph.open(configuration)) {
Vertex personVertex = this.sqlgGraph.addVertex(T.label, "Person", "name", "a");
Vertex dogVertex = this.sqlgGraph.addVertex(T.label, "Dog", "name", "b");
Edge petEdge = personVertex.addEdge("pet", dogVertex);
Edge petEdge = personVertex.addEdge("pet", dogVertex, "test", "this");
this.sqlgGraph.tx().commit();

//allow time for notification to happen
Thread.sleep(1_000);

Assert.assertEquals(1, sqlgGraph1.traversal().E().count().next().intValue());
Assert.assertEquals(1, sqlgGraph1.traversal().E().has(T.label, "pet").count().next().intValue());
Assert.assertEquals("this", sqlgGraph1.traversal().E().has(T.label, "pet").next().value("test"));
Assert.assertEquals(1, sqlgGraph1.traversal().V().has(T.label, "Person").count().next().intValue());
Assert.assertEquals(1, sqlgGraph1.traversal().V().has(T.label, "Dog").count().next().intValue());

Expand Down
Expand Up @@ -13,6 +13,7 @@
import java.util.Random;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

Expand All @@ -28,6 +29,70 @@ public class TestMultiThread extends BaseTest {

private Logger logger = LoggerFactory.getLogger(TestMultiThread.class.getName());

/**
* This test is a duplicate of TransactionTest.shouldSupportTransactionIsolationCommitCheck but with the schema created upfront else it deadlocks.
* @throws Exception
*/
@Test
public void shouldSupportTransactionIsolationCommitCheck() throws Exception {
Vertex v1 = this.sqlgGraph.addVertex();
this.sqlgGraph.tx().commit();
v1.remove();
this.sqlgGraph.tx().commit();
// the purpose of this test is to simulate gremlin server access to a graph instance, where one thread modifies
// the graph and a separate thread cannot affect the transaction of the first
final CountDownLatch latchCommittedInOtherThread = new CountDownLatch(1);
final CountDownLatch latchCommitInOtherThread = new CountDownLatch(1);

final AtomicBoolean noVerticesInFirstThread = new AtomicBoolean(false);

// this thread starts a transaction then waits while the second thread tries to commit it.
final Thread threadTxStarter = new Thread("thread1") {
@Override
public void run() {
TestMultiThread.this.sqlgGraph.addVertex();
latchCommitInOtherThread.countDown();

try {
latchCommittedInOtherThread.await();
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}

TestMultiThread.this.sqlgGraph.tx().rollback();

// there should be no vertices here
noVerticesInFirstThread.set(!TestMultiThread.this.sqlgGraph.vertices().hasNext());
}
};

threadTxStarter.start();

// this thread tries to commit the transaction started in the first thread above.
final Thread threadTryCommitTx = new Thread("thread2") {
@Override
public void run() {
try {
latchCommitInOtherThread.await();
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}

// try to commit the other transaction
TestMultiThread.this.sqlgGraph.tx().commit();

latchCommittedInOtherThread.countDown();
}
};

threadTryCommitTx.start();

threadTxStarter.join();
threadTryCommitTx.join();

assertTrue(noVerticesInFirstThread.get());
assertVertexEdgeCounts(0, 0);
}
@Test
public void shouldExecuteWithCompetingThreads() throws InterruptedException {
final Graph graph = this.sqlgGraph;
Expand Down
Expand Up @@ -12,8 +12,8 @@
import org.umlg.sqlg.sql.dialect.SqlSchemaChangeDialect;
import org.umlg.sqlg.structure.PropertyType;
import org.umlg.sqlg.structure.SqlgGraph;
import org.umlg.sqlg.test.BaseTest;
import org.umlg.sqlg.structure.VertexLabel;
import org.umlg.sqlg.test.BaseTest;

import java.beans.PropertyVetoException;
import java.io.IOException;
Expand Down Expand Up @@ -48,6 +48,7 @@ public static void beforeClass() throws ClassNotFoundException, IOException, Pro
}
}


@Test
public void testMultiThreadedLocking() throws Exception {
//number graphs, pretending its a separate jvm
Expand Down

0 comments on commit 555bc6e

Please sign in to comment.