// Path: src/main/java/com/maxdemarzi/processing/unionfind/UnionFind.java
// public interface UnionFind extends Algorithm {
// 
//     void compute(String label, String type, int iterations);
//     double getResult(long node);
//     long numberOfNodes();
//     default String getPropertyName() {
//         return "unionfind";
//     }
// 
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/unionfind/UnionFindMapStorage.java
// public class UnionFindMapStorage implements UnionFind {
//     private final GraphDatabaseService db;
//     private final long nodes;
//     private Long2IntOpenHashMap rankMap;
//     private Long2LongMap rootMap;
// 
//     public UnionFindMapStorage(GraphDatabaseService db) {
//         this.db = db;
//         this.rootMap = new Long2LongOpenHashMap();
//         this.rankMap = new Long2IntOpenHashMap();
//         this.nodes = new NodeCounter().getNodeCount(db);
//     }
// 
//     @Override
//     public void compute(String label, String type, int iterations) {
//         RelationshipType relationshipType = RelationshipType.withName(type);
// 
//         try ( Transaction tx = db.beginTx()) {
//             ResourceIterator<Node> nodes = db.findNodes(DynamicLabel.label(label));
//             while (nodes.hasNext()) {
//                 long nodeId = nodes.next().getId();
//                 rootMap.put(nodeId, nodeId);
//                 rankMap.put(nodeId, 1);
//             }
// 
//             for( Relationship relationship : db.getAllRelationships()) {
//                 if (relationship.isType(relationshipType)) {
// 
//                     long x = relationship.getStartNode().getId();
//                     long y = relationship.getEndNode().getId();
//                     if (x == y) { continue; }
// 
//                     x = rootMap.get(relationship.getStartNode().getId());
//                     y = rootMap.get(relationship.getEndNode().getId());
// 
//                     while (x != rootMap.get(x)) {
//                         rootMap.put(x, rootMap.get(rootMap.get(x)));
//                         x = rootMap.get(x);
//                     }
//                     while (y != rootMap.get(y)) {
//                         rootMap.put(y, rootMap.get(rootMap.get(y)));
//                         y = rootMap.get(y);
//                     }
// 
//                     if (x != y) {
//                         if ( rankMap.get(x) > rankMap.get(y)) {
//                             rootMap.put(y, x);
//                         } else if (rankMap.get(x) < rankMap.get(y)) {
//                             rootMap.put(x, y);
//                         } else {
//                             rootMap.put(y, x);
//                             rankMap.put(x, rankMap.get(x) + 1);
//                         }
//                     }
//                 }
//             }
// 
//             // This part is technically not necessary since we can just follow the unionfind property
//             // of any node UP the tree to see if it's really connected or not.
// 
//             int iteration = 0;
//             boolean done = false;
// 
//             while (!done && iterations > 0) {
//                 done = true;
//                 iteration++;
//                 nodes = db.findNodes(DynamicLabel.label(label));
//                 while (nodes.hasNext()) {
//                     long x = nodes.next().getId();
//                     if (rootMap.get(x) != x) {
//                         done = false;
//                         // This can be changed to be the GrandParent instead of Parent for faster convergence.
//                         rootMap.put(x, rootMap.get(rootMap.get(x)));
//                     }
//                 }
// 
//                 if (iteration > iterations) {
//                     done = true;
//                 }
//             }
//         }
//     }
// 
//     @Override
//     public double getResult(long node) {
//         return rootMap != null ? rootMap.getOrDefault(node, -1L) : -1;
//     }
// 
//     @Override
//     public long numberOfNodes() {
//         return nodes;
//     };
// }


import com.maxdemarzi.processing.unionfind.UnionFind;
import com.maxdemarzi.processing.unionfind.UnionFindMapStorage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.test.TestGraphDatabaseFactory;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import static org.junit.Assert.assertEquals;
package com.maxdemarzi.processing;




public class UnionFindTest {
    public static final double EXPECTED = 2.0;
    private GraphDatabaseService db;
// Path: src/main/java/com/maxdemarzi/processing/unionfind/UnionFind.java
// public interface UnionFind extends Algorithm {
// 
//     void compute(String label, String type, int iterations);
//     double getResult(long node);
//     long numberOfNodes();
//     default String getPropertyName() {
//         return "unionfind";
//     }
// 
// }
// 
// Path: src/main/java/com/maxdemarzi/processing/unionfind/UnionFindMapStorage.java
// public class UnionFindMapStorage implements UnionFind {
//     private final GraphDatabaseService db;
//     private final long nodes;
//     private Long2IntOpenHashMap rankMap;
//     private Long2LongMap rootMap;
// 
//     public UnionFindMapStorage(GraphDatabaseService db) {
//         this.db = db;
//         this.rootMap = new Long2LongOpenHashMap();
//         this.rankMap = new Long2IntOpenHashMap();
//         this.nodes = new NodeCounter().getNodeCount(db);
//     }
// 
//     @Override
//     public void compute(String label, String type, int iterations) {
//         RelationshipType relationshipType = RelationshipType.withName(type);
// 
//         try ( Transaction tx = db.beginTx()) {
//             ResourceIterator<Node> nodes = db.findNodes(DynamicLabel.label(label));
//             while (nodes.hasNext()) {
//                 long nodeId = nodes.next().getId();
//                 rootMap.put(nodeId, nodeId);
//                 rankMap.put(nodeId, 1);
//             }
// 
//             for( Relationship relationship : db.getAllRelationships()) {
//                 if (relationship.isType(relationshipType)) {
// 
//                     long x = relationship.getStartNode().getId();
//                     long y = relationship.getEndNode().getId();
//                     if (x == y) { continue; }
// 
//                     x = rootMap.get(relationship.getStartNode().getId());
//                     y = rootMap.get(relationship.getEndNode().getId());
// 
//                     while (x != rootMap.get(x)) {
//                         rootMap.put(x, rootMap.get(rootMap.get(x)));
//                         x = rootMap.get(x);
//                     }
//                     while (y != rootMap.get(y)) {
//                         rootMap.put(y, rootMap.get(rootMap.get(y)));
//                         y = rootMap.get(y);
//                     }
// 
//                     if (x != y) {
//                         if ( rankMap.get(x) > rankMap.get(y)) {
//                             rootMap.put(y, x);
//                         } else if (rankMap.get(x) < rankMap.get(y)) {
//                             rootMap.put(x, y);
//                         } else {
//                             rootMap.put(y, x);
//                             rankMap.put(x, rankMap.get(x) + 1);
//                         }
//                     }
//                 }
//             }
// 
//             // This part is technically not necessary since we can just follow the unionfind property
//             // of any node UP the tree to see if it's really connected or not.
// 
//             int iteration = 0;
//             boolean done = false;
// 
//             while (!done && iterations > 0) {
//                 done = true;
//                 iteration++;
//                 nodes = db.findNodes(DynamicLabel.label(label));
//                 while (nodes.hasNext()) {
//                     long x = nodes.next().getId();
//                     if (rootMap.get(x) != x) {
//                         done = false;
//                         // This can be changed to be the GrandParent instead of Parent for faster convergence.
//                         rootMap.put(x, rootMap.get(rootMap.get(x)));
//                     }
//                 }
// 
//                 if (iteration > iterations) {
//                     done = true;
//                 }
//             }
//         }
//     }
// 
//     @Override
//     public double getResult(long node) {
//         return rootMap != null ? rootMap.getOrDefault(node, -1L) : -1;
//     }
// 
//     @Override
//     public long numberOfNodes() {
//         return nodes;
//     };
// }


// Path: src/test/java/com/maxdemarzi/processing/UnionFindTest.java
import com.maxdemarzi.processing.unionfind.UnionFind;
import com.maxdemarzi.processing.unionfind.UnionFindMapStorage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.test.TestGraphDatabaseFactory;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import static org.junit.Assert.assertEquals;

package com.maxdemarzi.processing;




public class UnionFindTest {
    public static final double EXPECTED = 2.0;
    private GraphDatabaseService db;
    private static Service service;