/** * Jeff Rupp * Master's Thesis * 2005 * * container for all the nodes in the network * * Singleton class */ package jdr.mobisim; import java.util.*; import org.apache.log4j.*; public class AllNodes { private static Logger m_logger = Logger.getLogger(AllNodes.class); private static AllNodes s_instance = null; // map from FloatPoint to NodeIF objects. The map allows quick lookup of what nodes // can 'hear' another node transmitting private HashMap m_locationToNodeMap = new HashMap(); // map used to print out the nodes in order, for debug prints private TreeMap m_nodeNumberToNodeMap = new TreeMap(); java.util.Random m_rand = new java.util.Random(12344123); private EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock m_mapLock = new EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock(); private double m_width = 100.0; private double m_height = 100.0; /** * singleton class, use Instance to get the single instance */ protected AllNodes() { } // singleton getter public static AllNodes Instance() { if(s_instance == null) { s_instance = new AllNodes(); } return s_instance; } /** * add a node at a random location * @param node the node to add */ public void AddNode(NodeIF node) { AddNode(1.0, node); } /** * add a node, creating a new location that roughly obeys the requested density * @param avgNumNodesPer1000SquareUnits desired average node density * @param node the node to add */ public jdr.utils.FloatPoint AddNode(double avgNumNodesPer1000SquareUnits, NodeIF node) { float x = (float)(m_rand.nextFloat() * m_width); float y = (float)(m_rand.nextFloat() * m_height); jdr.utils.FloatPoint location = new jdr.utils.FloatPoint(x, y); int attempts = 0; while(GetNodesNear(location, Math.sqrt(avgNumNodesPer1000SquareUnits)/2).size() > avgNumNodesPer1000SquareUnits) { // try a new location, only try 10 times, then let excess density happen x = (float)(m_rand.nextFloat() * m_width); y = (float)(m_rand.nextFloat() * m_height); location = new jdr.utils.FloatPoint(x, y); if(attempts++ > 10) { break; } } AddNode(location, node); return location; } /** * add a node to the specified location * @param location the location to place the node in * @param node the node to add */ public void AddNode(jdr.utils.FloatPoint location, NodeIF node) { node.setLocation(location); try { m_mapLock.writeLock().acquire(); { m_locationToNodeMap.put(location, node); m_nodeNumberToNodeMap.put(new Integer(node.getNodeNumber()), node); } m_mapLock.writeLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } } public void ClearNodes() { try { m_mapLock.writeLock().acquire(); { m_locationToNodeMap.clear(); } m_mapLock.writeLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } // reset the seed so we get the same locations each run m_rand = new java.util.Random(12344123); } public void setWidthHeight(double width, double height) { m_width = width; m_height = height; } public double getWidth() { return m_width; } public double getHeight() { return m_height; } public HashMap GetNodesNear(jdr.utils.FloatPoint location, double distance) { return GetNodesNear(location, distance, false); } /** * returns a hashmap of the nodes within the given distance of a point * ??? This needs to be very fast, as it will be called a lot */ public HashMap GetNodesNear(jdr.utils.FloatPoint location, double distance, boolean doLog) { HashMap near = new HashMap(); try { m_mapLock.readLock().acquire(); { double thisDist = 0.0; Iterator iter = m_locationToNodeMap.keySet().iterator(); while(iter.hasNext()) { jdr.utils.FloatPoint testNodeLoc = (jdr.utils.FloatPoint)(iter.next()); thisDist = Math.sqrt(Math.pow((location.getX() - testNodeLoc.getX()), 2) + Math.pow((location.getY() - testNodeLoc.getY()), 2)); if(thisDist <= distance) { if(doLog) { //??? this will need to be commented out for speed m_logger.info("source node: "+location.toString()+ " test node: "+testNodeLoc.toString()+ "\n test distance: "+ distance+ " this distance: "+thisDist); } NodeIF node = (NodeIF)(m_locationToNodeMap.get(testNodeLoc)); near.put(testNodeLoc, node); } } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } return near; } public NodeIF GetNodeByNumber(int nodeNum) { NodeIF node = null; try { m_mapLock.readLock().acquire(); { node = (NodeIF)m_nodeNumberToNodeMap.get(new Integer(nodeNum)); } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } return node; } public int GetNumNodes() { return m_locationToNodeMap.size(); } public Vector GetAllNodeLocations() { Vector retVect = new Vector(); try { m_mapLock.readLock().acquire(); { Iterator iter = m_locationToNodeMap.keySet().iterator(); while(iter.hasNext()) { retVect.addElement(iter.next()); } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } return retVect; } public void DrawNodes(java.awt.Graphics2D graphics, java.awt.Rectangle bounds, double xScale, double yScale) { try { m_mapLock.readLock().acquire(); { Iterator iter = m_nodeNumberToNodeMap.keySet().iterator(); while(iter.hasNext()) { java.lang.Object node = m_nodeNumberToNodeMap.get(iter.next()); if(node instanceof NodeIF) { ((NodeIF)node).Draw(graphics, bounds, xScale, yScale); } } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } } public double GetAverageNodeWattsRemaining() { double avgPwr = 0.0; int numNodes = 0; try { m_mapLock.readLock().acquire(); { Iterator iter = m_locationToNodeMap.keySet().iterator(); while(iter.hasNext()) { jdr.utils.FloatPoint testNodeLoc = (jdr.utils.FloatPoint)(iter.next()); NodeIF node = (NodeIF)(m_locationToNodeMap.get(testNodeLoc)); avgPwr += node.GetRemainingPower(); ++numNodes; } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } if(numNodes > 0) { avgPwr /= numNodes; } else { avgPwr = Float.MIN_VALUE; } return avgPwr; } public double GetPercentageOfNodesBelowPercentPower(double percent) { double percentAt = 0.0; int numNodesAt = 0; int totalNumNodes = 0; try { m_mapLock.readLock().acquire(); { totalNumNodes = m_locationToNodeMap.size(); double percentPwr = 0.0; Iterator iter = m_locationToNodeMap.keySet().iterator(); while(iter.hasNext()) { jdr.utils.FloatPoint testNodeLoc = (jdr.utils.FloatPoint)(iter.next()); NodeIF node = (NodeIF)(m_locationToNodeMap.get(testNodeLoc)); percentPwr = node.GetRemainingPower() / node.GetMaxPower(); if((percentPwr*100) <= percent) { ++numNodesAt; } } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } percentAt = 100 * ((double)numNodesAt / (double)totalNumNodes); return percentAt; } /** * Method to pass the highlight flag to all nodes, to show clusters */ public void HighlightCluster(int clusterHead, boolean highlight) { try { m_mapLock.readLock().acquire(); { Iterator iter = m_locationToNodeMap.keySet().iterator(); while(iter.hasNext()) { jdr.utils.FloatPoint testNodeLoc = (jdr.utils.FloatPoint)(iter.next()); NodeIF node = (NodeIF)(m_locationToNodeMap.get(testNodeLoc)); node.SetHighliteCluster(false, false); node.SetHighliteClusterMembers(highlight, clusterHead); } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } } // debug print routines public void DumpAllNodesHeard() { try { m_mapLock.readLock().acquire(); { Iterator iter = m_nodeNumberToNodeMap.keySet().iterator(); while(iter.hasNext()) { java.lang.Object node = m_nodeNumberToNodeMap.get(iter.next()); if(node instanceof NodeIF) { ((NodeIF)node).DumpNodesHeard(); } } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } } public void DumpAllNodesQueue() { try { m_mapLock.readLock().acquire(); { Iterator iter = m_nodeNumberToNodeMap.keySet().iterator(); while(iter.hasNext()) { java.lang.Object node = m_nodeNumberToNodeMap.get(iter.next()); if(node instanceof NodeIF) { ((NodeIF)node).DumpNodePacketQueue(); } } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } } public void DumpAllNodesClusterInfo() { try { m_mapLock.readLock().acquire(); { Iterator iter = m_nodeNumberToNodeMap.keySet().iterator(); while(iter.hasNext()) { java.lang.Object node = m_nodeNumberToNodeMap.get(iter.next()); if(node instanceof NodeIF) { m_logger.debug("node at location: "+((NodeIF)node).getLocation().toString()); ((NodeIF)node).DumpClusterInfo(); } } } m_mapLock.readLock().release(); } catch(InterruptedException iex) { m_logger.error("exception getting lock", iex); } } } // end class definition