// Path: src/main/java/com/maxdemarzi/processing/NodeCounter.java
// public class NodeCounter {
//     public int getNodeCount(GraphDatabaseService db) {
//         Result result = db.execute( "MATCH (n) RETURN max(id(n)) AS maxId" );
//         return ((Number) result.next().get( "maxId" )).intValue() + 1;
// 
//     }
//     public int getRelationshipCount(GraphDatabaseService db) {
//         Result result = db.execute( "MATCH ()-[r]->() RETURN max(id(r)) AS maxId" );
//         return ((Number) result.next().get( "maxId" )).intValue() + 1;
//     }
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/OpsRunner.java
// public interface OpsRunner {
//     void run(int node) throws EntityNotFoundException;
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/Utils.java
// public class Utils {
//     static final int BATCH_SIZE  = 100_000;
// 
//     public static int toInt(double value) {
//         return (int) (100_000*value);
//     }
//     public static double toFloat(int value) {
//         return value / 100_000.0;
//     }
// 
//     public static SingleSourceShortestPath<Double> getSingleSourceShortestPath(RelationshipType relationshipType)
//     {
//         return new SingleSourceShortestPathDijkstra<Double>( 0.0, null,
//                 new CostEvaluator<Double>()
//                 {
//                     public Double getCost( Relationship relationship,
//                                            Direction direction )
//                     {
//                         return 1.0;
//                     }
//                 }, new org.neo4j.graphalgo.impl.util.DoubleAdder(),
//                 new org.neo4j.graphalgo.impl.util.DoubleComparator(),
//                 Direction.BOTH, relationshipType );
//     }
// 
// 
//     static ExecutorService createPool(int threads, int queueSize) {
//         return new ThreadPoolExecutor(1, threads, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>(queueSize),
//                 new ThreadPoolExecutor.CallerRunsPolicy());
//     }
// 
//     public static int waitForTasks(List<Future> futures) {
//         int total = 0;
//         for (Future future : futures) {
//             try {
//                 future.get();
//                 total ++;
//             } catch (InterruptedException | ExecutionException e) {
//                 e.printStackTrace();
//             }
//         }
//         futures.clear();
//         return total;
//     }
// 
//     public static void runOperations(ExecutorService pool, final PrimitiveLongIterator it, int totalCount, ReadOperations ops, OpsRunner runner) {
//         List<Future> futures = new ArrayList<>((int)(totalCount / BATCH_SIZE));
//         while (it.hasNext()) {
//             futures.add(pool.submit(new BatchRunnable(ops, it, BATCH_SIZE,runner)));
//         }
//         Utils.waitForTasks(futures);
//     }
// }


import com.maxdemarzi.processing.NodeCounter;
import com.maxdemarzi.processing.OpsRunner;
import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.kernel.impl.api.RelationshipVisitor;
import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicIntegerArray;
import static com.maxdemarzi.processing.Utils.*;
package com.maxdemarzi.processing.pagerank;




/**
 * @author mh
 * @since 28.03.15
 */
public class PageRankArrayStorageParallelSPI implements PageRank {
    public static final int ONE_MINUS_ALPHA_INT = toInt(ONE_MINUS_ALPHA);
    private final GraphDatabaseAPI db;
    private final int nodeCount;
    private final ExecutorService pool;
    private final int relCount;
    private AtomicIntegerArray dst;

    public PageRankArrayStorageParallelSPI(GraphDatabaseService db, ExecutorService pool) {
        this.pool = pool;
        this.db = (GraphDatabaseAPI) db;
// Path: src/main/java/com/maxdemarzi/processing/NodeCounter.java
// public class NodeCounter {
//     public int getNodeCount(GraphDatabaseService db) {
//         Result result = db.execute( "MATCH (n) RETURN max(id(n)) AS maxId" );
//         return ((Number) result.next().get( "maxId" )).intValue() + 1;
// 
//     }
//     public int getRelationshipCount(GraphDatabaseService db) {
//         Result result = db.execute( "MATCH ()-[r]->() RETURN max(id(r)) AS maxId" );
//         return ((Number) result.next().get( "maxId" )).intValue() + 1;
//     }
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/OpsRunner.java
// public interface OpsRunner {
//     void run(int node) throws EntityNotFoundException;
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/Utils.java
// public class Utils {
//     static final int BATCH_SIZE  = 100_000;
// 
//     public static int toInt(double value) {
//         return (int) (100_000*value);
//     }
//     public static double toFloat(int value) {
//         return value / 100_000.0;
//     }
// 
//     public static SingleSourceShortestPath<Double> getSingleSourceShortestPath(RelationshipType relationshipType)
//     {
//         return new SingleSourceShortestPathDijkstra<Double>( 0.0, null,
//                 new CostEvaluator<Double>()
//                 {
//                     public Double getCost( Relationship relationship,
//                                            Direction direction )
//                     {
//                         return 1.0;
//                     }
//                 }, new org.neo4j.graphalgo.impl.util.DoubleAdder(),
//                 new org.neo4j.graphalgo.impl.util.DoubleComparator(),
//                 Direction.BOTH, relationshipType );
//     }
// 
// 
//     static ExecutorService createPool(int threads, int queueSize) {
//         return new ThreadPoolExecutor(1, threads, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>(queueSize),
//                 new ThreadPoolExecutor.CallerRunsPolicy());
//     }
// 
//     public static int waitForTasks(List<Future> futures) {
//         int total = 0;
//         for (Future future : futures) {
//             try {
//                 future.get();
//                 total ++;
//             } catch (InterruptedException | ExecutionException e) {
//                 e.printStackTrace();
//             }
//         }
//         futures.clear();
//         return total;
//     }
// 
//     public static void runOperations(ExecutorService pool, final PrimitiveLongIterator it, int totalCount, ReadOperations ops, OpsRunner runner) {
//         List<Future> futures = new ArrayList<>((int)(totalCount / BATCH_SIZE));
//         while (it.hasNext()) {
//             futures.add(pool.submit(new BatchRunnable(ops, it, BATCH_SIZE,runner)));
//         }
//         Utils.waitForTasks(futures);
//     }
// }


// Path: src/main/java/com/maxdemarzi/processing/pagerank/PageRankArrayStorageParallelSPI.java
import com.maxdemarzi.processing.NodeCounter;
import com.maxdemarzi.processing.OpsRunner;
import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.kernel.impl.api.RelationshipVisitor;
import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicIntegerArray;
import static com.maxdemarzi.processing.Utils.*;

package com.maxdemarzi.processing.pagerank;




/**
 * @author mh
 * @since 28.03.15
 */
public class PageRankArrayStorageParallelSPI implements PageRank {
    public static final int ONE_MINUS_ALPHA_INT = toInt(ONE_MINUS_ALPHA);
    private final GraphDatabaseAPI db;
    private final int nodeCount;
    private final ExecutorService pool;
    private final int relCount;
    private AtomicIntegerArray dst;

    public PageRankArrayStorageParallelSPI(GraphDatabaseService db, ExecutorService pool) {
        this.pool = pool;
        this.db = (GraphDatabaseAPI) db;
        this.nodeCount = new NodeCounter().getNodeCount(db);