// // The graph holding the simulation network topology // Takes care of routing, position randomization, also some node configuration // package sim; import java.util.Random; import java.util.Vector; import java.util.LinkedList; class SimpleGraph { // SimpleNode[] nodes; Vector nodes; // Growable, but array should be more efficient private static Random rand = new Random(System.currentTimeMillis() % 10000); private boolean delays = false; // If to vary delays by default /* * @n: number of nodes * @estsize: size of estimation table * @delays: if to sample delays between nodes, or to use unity */ public SimpleGraph(int n, int estsize, boolean delays) { this.delays = delays; // nodes = new SimpleNode[n]; nodes = new Vector(); for (int i=0; i route = src.route(new SimpleQuery(src,null,dst,null,SimpleQuery.FORWARD,htl,false)); unlock(route); } /* * Unlock simple trackkeeping of route participation * * @route: The route with all parcitipants */ public void unlock(LinkedList route) { for (SimpleQuery rq: route) { rq.source.busy = false; } } /* * Randomly assign new locations in [0,1) to nodes */ public void randLocations() { for (SimpleNode n: nodes) { n.setLocation(rand.nextDouble()); } } /* * Randomly shuffle the existing positions */ public void shuffleLocations() { for(int j=0; j=nodes.size()) { destpos = destpos - nodes.size(); } else if (destpos<0) { destpos = destpos + nodes.size(); } SimpleNode dst = nodes.get(destpos); if(delays) delay = sampleDelay(); else delay = 1; if (directed) { if (inconst) { if (!dst.hasNeighbor(src)) { found = true; SimpleLink sl = new SimpleLink(src,dst,delay); dst.connect(src,sl,SimplePeer.t_DARKNET); } } else { if (!src.hasNeighbor(dst)) { found = true; SimpleLink sl = new SimpleLink(dst,src,delay); src.connect(dst,sl,SimplePeer.t_DARKNET); } } } else { if (!src.hasNeighbor(dst) && !dst.hasNeighbor(src)) { found = true; SimpleLink sl = new SimpleLink(src,dst,delay); src.connect(dst,sl,SimplePeer.t_DARKNET); dst.connect(src,sl,SimplePeer.t_DARKNET); } } } } return newnode; } /* * Remove a node from the graph * * fixme: also remove load stats/counters * @n: node to remove */ public void removeNode (SimpleNode n) { Vector toDisconnect = new Vector(); for (SimplePeer peer: n.neighbors) { peer.n.disconnect(n); toDisconnect.add(peer.n); } for (SimpleNode disconnecter: toDisconnect) { n.disconnect(disconnecter); } nodes.removeElement(n); } /* * Generating a Kleinberg small-world graph with shortcuts proportional to 1/d * * @avgdeg: average degree of nodes * @directed: if to have directed edges * @local: if to have local edges (to nearest-neighbors in the lattice) * @inconst: if to have a constant number of indegree edges (when using directed edges), * otherwise use constant outdegree (default) */ public void CreateKleinbergGraph(double avgdeg, boolean directed, boolean local, boolean inconst) { double degree,delay; if(directed) { degree = avgdeg; } else { degree = avgdeg/2; } if(local) { for(int i=0; i=nodes.size()) { destpos = destpos - nodes.size(); } else if (destpos<0) { destpos = destpos + nodes.size(); } SimpleNode dst = nodes.get(destpos); if(delays) delay = sampleDelay(); else delay = 1; if (directed) { if (inconst) { if (!dst.hasNeighbor(src)) { found = true; SimpleLink sl = new SimpleLink(src,dst,delay); dst.connect(src,sl,SimplePeer.t_DARKNET); } } else { if (!src.hasNeighbor(dst)) { found = true; SimpleLink sl = new SimpleLink(dst,src,delay); src.connect(dst,sl,SimplePeer.t_DARKNET); } } } else { if (!src.hasNeighbor(dst) && !dst.hasNeighbor(src)) { found = true; SimpleLink sl = new SimpleLink(src,dst,delay); src.connect(dst,sl,SimplePeer.t_DARKNET); dst.connect(src,sl,SimplePeer.t_DARKNET); } } } } } } /* * Evaluate swap directly without no delay * * @randsteps: steps for random walk from source to dest (0=uniform selection) * @randomize_interval: if to enable position randomization with a period of swaps */ public void tryswap(int randsteps, int randomize_interval) { int i,j; SimpleNode na=null,nb=null; if (randsteps==0) { do { i = rand.nextInt(nodes.size()); j = rand.nextInt(nodes.size()); } while (i==j); na = nodes.get(i); nb = nodes.get(j); } else { // Fixme: let the node initialize the request itself do { i = rand.nextInt(nodes.size()); na = nodes.get(i); int s = randsteps; nb = na; while (s > 0) { nb = nb.neighbors.get(rand.nextInt(nb.neighbors.size())).n; s--; } } while (na==nb); } if (randomize_interval > 0) { if (na.rand_interval > 0) { na.rand_interval--; } else { na.setLocation(rand.nextDouble()); na.rand_interval = na.rand_interval + randomize_interval; } } double p = Math.exp(na.logDists(na.getLocation())+nb.logDists(nb.getLocation())-na.logDists(nb.getLocation())-nb.logDists(na.getLocation())); // Evaluate step if (rand.nextDouble() neighbors = nodes.get(i).neighbors; for (SimplePeer peer: nodes.get(i).neighbors) { int stop = (int) Math.round(nodes.size()*peer.n.getLocation()); if(stdout==1) { System.out.println(start + "\t" + stop); } else { System.err.println(start + "\t" + stop); } } } } /* * Print only locations for nodes (in topology order) * * @stdout: if stdout!= 0 we print to stdout, if stdout==0 print to stderr */ public void printLocations(int stdout) { for(SimpleNode n: nodes) { ((stdout==0) ? System.err : System.out).println(n.getLocation()); } } /* * Enable all nodes for learning route delays */ public void learning() { for (SimpleNode n: nodes) { n.learning = true; } } /* * Disable learning of route delays */ public void unlearning() { for (SimpleNode n: nodes) { n.learning = false; } } /* * Use delays for generating edges */ public void edgedelays() { this.delays = true; } /* * Enable delay usage for nodes in routing */ public void usedelays() { for (SimpleNode n: nodes) { n.delays = true; } } /* * Disable delays usage for nodes in routing */ public void nodelays() { for (SimpleNode n: nodes) { n.delays = false; } } }