import java.util.concurrent.atomic.AtomicReference; import static edu.rice.hj.Module1.async; import edu.rice.hj.api.HjFinishAccumulator; import edu.rice.hj.api.HjOperator; import static edu.rice.hj.Module1.finish; import static edu.rice.hj.Module1.newFinishAccumulator; /** * */ public class spanning_tree_atomic_hj { public static void main(String[] args) { int global_num_neighbors = 100; int num_nodes = 1000; if(args.length > 0) num_nodes = Integer.parseInt(args[0]); if(args.length > 1) global_num_neighbors = Integer.parseInt(args[1]); if(num_nodes < 2) { System.out.println("Error: number of nodes must be > 1"); return; } if(global_num_neighbors < -1) { System.out.println("Error: negative number of neighbors entered\n"); return; } java.util.Random rand = new java.util.Random(12399); // Initialize the graph by randomly generating neighbour connections Node[] nodes = new Node[num_nodes]; for(int i = 0; i < nodes.length; i++) { nodes[i] = new Node(Integer.toString(i)); } for(int i = 0; i < nodes.length; i++) { int num_neighbors = ( (global_num_neighbors == -1) ? rand.nextInt(10) : global_num_neighbors); Node[] neighbors = new Node[num_neighbors]; for(int j = 0; j < neighbors.length; j++) { int neighbor_index = rand.nextInt(nodes.length); if(neighbor_index == i) neighbor_index = (neighbor_index + 1) % num_nodes; neighbors[j] = nodes[neighbor_index]; } nodes[i].SetNeighbors(neighbors); } // Run the spanning tree algorithm for several iterations for(int run_no = 0; run_no < 5; run_no++) { for(int i = 0; i < nodes.length; i++) nodes[i].parent.set(null); Node root = nodes[0]; root.parent.set(root); long start = System.currentTimeMillis(); finish(()-> root.compute()); long stop = System.currentTimeMillis(); System.out.println("Time: "+(stop-start)+" ms"); } } } /* Node class used in the graph/tree */ class Node { Node[] neighbors; public AtomicReference parent; String name; /* constructor */ public Node(String set_name) { neighbors = new Node[0]; name = set_name; parent = new AtomicReference(null); } public void SetNeighbors(Node[] n) { neighbors = n; } /* try setting the parent */ boolean tryLabeling(Node n) { return parent.compareAndSet(null, n); } /* label*/ void compute() { // Recursively compute for each neighbour for(int i = 0; i < neighbors.length; i++) { Node child = neighbors[i]; if(child.tryLabeling(this)) { async(()->child.compute()); } } } }