/* * (C) Copyright IBM Corp. 2009 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb.tools; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import com.ibm.gaiandb.apps.dashboard.TopologyGraph.Edge; public class NetworkLinksAnalyser { // Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2009"; // int INIT_NODES = 100; // int MAX_STEPS = 20; // Hashtable of node names private final Hashtable<String, Set<String>> links = new Hashtable<String, Set<String>>(); //NUM_NODES); private final Hashtable<String, Set<String>> furthestNodes = new Hashtable<String, Set<String>>(); //NUM_NODES); // Hashtables of ArrayLists private final Hashtable<String, ArrayList<Integer>> stepCardinalities = new Hashtable<String, ArrayList<Integer>>(); //NUM_NODES); //[MAX_STEPS+1]; private final Hashtable<String, ArrayList<Integer>> runningTotalCardinalities = new Hashtable<String, ArrayList<Integer>>(); //NUM_NODES); //[MAX_STEPS+1]; private int radius = -1, diameter = 0; private int[] nodesPerEccentricity = null, nodesPerConnectivity = null; private static final String delimiter = " "; public static void main( String[] args) throws Exception { // String filename = args.length > 0 ? args[0] : "C:\\temp\\GDB52-emj.txt"; // String filename = args.length > 0 ? args[0] : "C:\\temp\\GDB120-propnewalgo.txt"; //GDB120-propnolimit.txt"; //GDB120-prop.txt"; String filename = args.length > 0 ? args[0] : "C:\\temp\\gdb1250.txt"; // String filename = args.length > 0 ? args[0] : "C:\\temp\\gdb120fix.txt"; NetworkLinksAnalyser nla = new NetworkLinksAnalyser(); FileReader fr = new FileReader( filename ); BufferedReader br = new BufferedReader( fr ); String line; while( null != ( line = br.readLine() ) ) { int cidx = line.indexOf( delimiter ); if ( -1 == cidx ) continue; // connected nodes n1 and n2 String n1 = line.substring(0, cidx); String n2 = line.substring(cidx+delimiter.length()); nla.addLink(n1, n2); } nla.computeAnalysis(); } public void computeStats( Set<Edge> topologyGraphEdges ) { links.clear(); stepCardinalities.clear(); runningTotalCardinalities.clear(); furthestNodes.clear(); radius = -1; diameter = 0; for ( Edge edge : topologyGraphEdges ) addLink(edge.source.getName(), edge.target.getName()); long time = -System.currentTimeMillis(); computeAnalysis(); time += System.currentTimeMillis(); // System.out.println("Computed Analysis in millis: " + time); } private void computeAnalysis() { Set<String> visited = new HashSet<String>(); int maxNodeConnections = 0; Iterator<String> nodes = links.keySet().iterator(); while(nodes.hasNext()) { String node = nodes.next(); visited.clear(); Set<String> previouslyVisited = new HashSet<String>(); // for every step out for ( int s=0; /*s<MAX_STEPS*/; s++ ) { Set<String> newlyVisited = new HashSet<String>(); if ( visited.isEmpty() ) { // Just add ourself at depth step 0 newlyVisited.add( node ); } else { // Compute cardinality at next step by getting all links m of the newly visited nodes // Iterator<String> iter = previouslyVisited.iterator(); // while( iter.hasNext() ) { // String m = iter.next(); // newlyVisited.addAll( links.get(m) ); // } for( String m : previouslyVisited ) newlyVisited.addAll( links.get(m) ); newlyVisited.removeAll( visited ); } // Early end condition: No new nodes visited if ( 0 == newlyVisited.size() ) break; visited.addAll( newlyVisited ); previouslyVisited = newlyVisited; if ( 0 == s ) continue; int numNewlyVisited = newlyVisited.size(); if ( 1 == s ) maxNodeConnections = Math.max( maxNodeConnections, numNewlyVisited ); stepCardinalities.get(node).add( numNewlyVisited ); runningTotalCardinalities.get(node).add( visited.size() ); } if ( null != previouslyVisited ) furthestNodes.put(node, previouslyVisited); // if ( stepCardinalities[n].size()-1 > diameter ) diameter = stepCardinalities[n].size()-1; if ( stepCardinalities.get(node).size() > diameter ) diameter = stepCardinalities.get(node).size(); if ( -1 == radius || stepCardinalities.get(node).size() < radius ) radius = stepCardinalities.get(node).size(); } // print results // System.out.println("Network Radius: " + radius + ", Diameter: " + diameter); // System.out.println("\nStep Cardinalities Per Node, i.e. number of newly connected nodes at each step out, for every node:"); // System.out.println("Note: Nodes are sorted by the distance they are from their furtest nodes:\n"); // / Running Totals nodesPerEccentricity = new int[ diameter ]; for ( int s=1; s<diameter+1; s++ ) { for( String node : stepCardinalities.keySet() ) { ArrayList<Integer> nodeStepCardinalities = stepCardinalities.get( node ); if ( nodeStepCardinalities.size() == s) { nodesPerEccentricity[s-1]++; int total = 0; for ( int i=0; i<nodeStepCardinalities.size(); i++ ) { total += (Integer) nodeStepCardinalities.get(i); } // System.out.println("Node \t" + node + " (total: " + total + "):\t" + nodeStepCardinalities ); //+ " / " + runningTotalCardinalities[n] ); } } } nodesPerConnectivity = new int[maxNodeConnections]; if ( 0 < maxNodeConnections ) for( String node : stepCardinalities.keySet() ) { ArrayList<Integer> nodeStepCardinalities = stepCardinalities.get( node ); if ( 0 < nodeStepCardinalities.size() ) nodesPerConnectivity[nodeStepCardinalities.get(0)-1]++; } // System.out.println("\nDiameter cardinalities: Number of nodes reaching out to all other nodes for each diameter size up to max diameter:"); // System.out.println("This is a measure of the Centeredness of nodes / Compactness of the network"); // System.out.println("Number of nodes for each diameter size: " + intArrayAsString(diameterCardinalities)); } private void addLink( String node1, String node2 ) { // Populate links and cardinalities for node1 Set<String> s = links.get(node1); if ( null == s ) { s = new HashSet<String>(); links.put(node1, s); stepCardinalities.put(node1, new ArrayList<Integer>()); runningTotalCardinalities.put(node1, new ArrayList<Integer>()); } s.add(node2); // Populate links and cardinalities for node2 s = links.get(node2); if ( null == s ) { s = new HashSet<String>(); links.put(node2, s); stepCardinalities.put(node2, new ArrayList<Integer>()); runningTotalCardinalities.put(node2, new ArrayList<Integer>()); } s.add(node1); } public static String intArrayAsString(int[] a) { if ( null==a ) return null; int len = a.length; String pcs = new String( 0<len ? "[" + a[0] : "[" ); // for (int i=1; i<len; i++) pcs += ", " + a[i]; pcs += "]"; for (int i=1; i<len; i++) pcs += ", " + a[i]; pcs += "]"; return pcs; } public int getEccentricity( String node ) { ArrayList<Integer> steps = stepCardinalities.get(node); if ( null == steps ) return 0; return steps.size(); } public String getNodesPerEccentricity() { return intArrayAsString(nodesPerEccentricity); } public String getNodesPerConnectivity() { return intArrayAsString(nodesPerConnectivity); } public int getNumConnections( String node ) { ArrayList<Integer> steps = stepCardinalities.get(node); if ( null == steps || 1 > steps.size() ) return 0; return steps.get(0); } public ArrayList<Integer> getStepCardinalities( String node ) { return stepCardinalities.get(node); } public Set<String> getFurthestNodes(String node) { return furthestNodes.get(node); } public int getDiameter() { return diameter; } public int getRadius() { return radius; } }