Skip to content

Instantly share code, notes, and snippets.

@mneedham
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mneedham/33d42fa1edca604946ec to your computer and use it in GitHub Desktop.
Save mneedham/33d42fa1edca604946ec to your computer and use it in GitHub Desktop.
Find where I am in a linked list - Cypher / Transactional API
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