Last active
August 29, 2015 14:04
-
-
Save mneedham/33d42fa1edca604946ec to your computer and use it in GitHub Desktop.
Find where I am in a linked list - Cypher / Transactional API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.neo4j.chains; | |
import java.util.Collection; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Random; | |
import org.neo4j.cypher.javacompat.ExecutionEngine; | |
import org.neo4j.cypher.javacompat.ExecutionResult; | |
import org.neo4j.graphdb.Direction; | |
import org.neo4j.graphdb.DynamicRelationshipType; | |
import org.neo4j.graphdb.GraphDatabaseService; | |
import org.neo4j.graphdb.Node; | |
import org.neo4j.graphdb.Path; | |
import org.neo4j.graphdb.Transaction; | |
import org.neo4j.graphdb.factory.GraphDatabaseFactory; | |
import org.neo4j.graphdb.traversal.TraversalDescription; | |
import org.neo4j.graphdb.traversal.Traverser; | |
import org.neo4j.helpers.collection.IteratorUtil; | |
public class Chains | |
{ | |
private static final DynamicRelationshipType NEXT = DynamicRelationshipType.withName( "NEXT" ); | |
public static void main( String[] args ) | |
{ | |
String simpleChains = "/tmp/chains"; | |
// String simpleChains = "/tmp/longchains"; | |
// | |
// populate( simpleChains, 10000 ); | |
// System.out.println("populated"); | |
GraphDatabaseService simpleChainsDb = new GraphDatabaseFactory().newEmbeddedDatabase( simpleChains ); | |
ExecutionEngine simpleChainsEngine = new ExecutionEngine( simpleChainsDb ); | |
System.out.println("warm up"); | |
for ( int i = 0; i < 3; i++ ) | |
{ | |
warmup( 1, simpleChainsDb, simpleChainsEngine ); | |
warmup( 456, simpleChainsDb, simpleChainsEngine ); | |
warmup( 761, simpleChainsDb, simpleChainsEngine ); | |
} | |
System.out.println("*******"); | |
System.out.println("No Noise"); | |
System.out.println("*******"); | |
for ( int i = 0; i < 3; i++ ) | |
{ | |
query(1, simpleChainsDb, simpleChainsEngine); | |
query(456, simpleChainsDb, simpleChainsEngine ); | |
query(761, simpleChainsDb, simpleChainsEngine ); | |
System.out.println("--------"); | |
} | |
simpleChainsDb.shutdown(); | |
} | |
private static void warmup( int nodeId, GraphDatabaseService db, ExecutionEngine engine ) | |
{ | |
try(Transaction tx = db.beginTx()) { | |
Node startNode = db.getNodeById( nodeId ); | |
TraversalDescription traversal = db.traversalDescription(); | |
Traverser traverse = traversal | |
.depthFirst() | |
.relationships( NEXT, Direction.OUTGOING ) | |
.sort( new Comparator<Path>() | |
{ | |
@Override | |
public int compare( Path o1, Path o2 ) | |
{ | |
return Integer.valueOf( o2.length() ).compareTo( o1 .length() ); | |
} | |
} ) | |
.traverse( startNode ); | |
for ( Path p : IteratorUtil.asCollection( traverse ) ) | |
{ | |
} | |
tx.failure(); | |
} | |
Map<String, Object> params = new HashMap<>(); | |
params.put( "nodeId", nodeId ); | |
long cypherStart = System.currentTimeMillis(); | |
ExecutionResult result = engine.execute( "match n where id(n) = {nodeId} with n match path = (n)-[:NEXT*]->() RETURN id(n) AS nodeId, length(path) AS length ORDER BY length DESC LIMIT 1;", params ); | |
Collection<Map<String, Object>> rows = IteratorUtil.asCollection( result ); | |
Map<String, Object> firstRow = rows.iterator().next(); | |
} | |
private static void query( int nodeId, GraphDatabaseService db, ExecutionEngine engine ) | |
{ | |
long start = System.currentTimeMillis(); | |
try(Transaction tx = db.beginTx()) { | |
Node startNode = db.getNodeById( nodeId ); | |
TraversalDescription traversal = db.traversalDescription(); | |
Traverser traverse = traversal | |
.depthFirst() | |
.relationships( NEXT, Direction.OUTGOING ) | |
.sort( new Comparator<Path>() | |
{ | |
@Override | |
public int compare( Path o1, Path o2 ) | |
{ | |
return Integer.valueOf( o2.length() ).compareTo( o1 .length() ); | |
} | |
} ) | |
.traverse( startNode ); | |
int maxLength = traverse.iterator().next().length(); | |
System.out.printf( "%15s Node: %4d, Length: %3d, Time (ms): %3d%n", "(Traversal API)", nodeId, maxLength, System.currentTimeMillis() - start ); | |
tx.failure(); | |
} | |
Map<String, Object> params = new HashMap<>(); | |
params.put( "nodeId", nodeId ); | |
long cypherStart = System.currentTimeMillis(); | |
ExecutionResult result = engine.execute( "match n where id(n) = {nodeId} with n match path = (n)-[:NEXT*]->() RETURN id(n) AS nodeId, length(path) AS length ORDER BY length DESC LIMIT 1;", params ); | |
Collection<Map<String, Object>> rows = IteratorUtil.asCollection( result ); | |
Map<String, Object> firstRow = rows.iterator().next(); | |
System.out.printf( "%15s Node: %4d, Length: %3s, Time (ms): %3d%n", "(Cypher)", nodeId, firstRow.get("length"), (System.currentTimeMillis() - cypherStart) ); | |
} | |
private static void populate( String path, int chainSize ) | |
{ | |
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( path ); | |
try(Transaction tx = db.beginTx()) { | |
Node currentNode = null; | |
for ( int i = 0; i < chainSize; i++ ) | |
{ | |
Node node = db.createNode(); | |
if(currentNode != null) { | |
currentNode.createRelationshipTo( node, NEXT ); | |
} | |
currentNode = node; | |
} | |
tx.success(); | |
} | |
db.shutdown(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment