|
Alan Kaminsky
|
|
•
|
|
Department of Computer Science
|
|
•
|
|
Rochester Institute of Technology
|
|
•
|
|
4486 +
2220 =
6706
|
|
Home Page
|
Simulation Simplified
19. A Distributed Encyclopedia, Part 2
Class P2Pedia07
import edu.rit.numeric.DoublePrng;
import edu.rit.numeric.ExponentialPrng;
import edu.rit.numeric.ListSeries;
import edu.rit.numeric.Series;
import edu.rit.numeric.UniformPrng;
import edu.rit.sim.Event;
import edu.rit.sim.Simulation;
import edu.rit.util.Random;
import edu.rit.util.RandomSubset;
import java.util.HashSet;
import java.util.LinkedList;
public class P2Pedia07
{
// Knobs
private static int N; // Number of nodes
private static int K; // Number of extra connections per node
private static double lambda; // Mean query arrival rate
private static double tx_L; // Query transmit time lower bound
private static double tx_U; // Query transmit time upper bound
private static int Q; // Maximum queries in query queue
private static int R; // Number of queries to simulate
private static long seed; // PRNG seed
// Global variables
private static Random prng;
private static DoublePrng queryPrng;
private static DoublePrng txPrng;
private static int queryCount;
private static ListSeries elapsedTimes;
private static int successCount;
private static Simulation sim;
private static Network network;
private static class Query
{
private int id;
private Node matchingNode;
private double startTime;
public Query
(int id,
Node matchingNode)
{
this.id = id;
this.matchingNode = matchingNode;
this.startTime = sim.time();
}
public boolean matches
(Node node)
{
return node == matchingNode;
}
public double elapsedTime()
{
return sim.time() - startTime;
}
public boolean equals
(Object obj)
{
return
obj instanceof Query &&
((Query) obj).id == this.id;
}
public int hashCode()
{
return id;
}
public String toString()
{
return "Query " + id;
}
}
private static class Node
{
private int id;
private LinkedList<Node> connectedNodes =
new LinkedList<Node>();
private LinkedList<Query> queryQueue =
new LinkedList<Query>();
private HashSet<Query> priorQueries =
new HashSet<Query>();
public Node
(int id)
{
this.id = id;
}
public void connectTo
(Node node)
{
connectedNodes.add (node);
}
public void addToQueue
(Query query)
{
if (queryQueue.size() < Q)
{
System.out.printf ("%.3f %s received by %s%n",
sim.time(), query, this);
queryQueue.add (query);
if (queryQueue.size() == 1) startServing();
}
else
{
System.out.printf ("%.3f %s dropped by %s%n",
sim.time(), query, this);
}
}
private void startServing()
{
final Query query = queryQueue.getFirst();
if (priorQueries.contains (query))
{
System.out.printf ("%.3f %s previously seen by %s%n",
sim.time(), query, this);
removeFromQueue();
}
else if (query.matches (this))
{
System.out.printf ("%.3f %s matches at %s%n",
sim.time(), query, this);
elapsedTimes.add (query.elapsedTime());
++ successCount;
removeFromQueue();
}
else
{
System.out.printf ("%.3f %s sent from %s to",
sim.time(), query, this);
double txTime = 0.0;
for (Node nextNode : connectedNodes)
{
System.out.printf (" %s", nextNode);
final Node nn = nextNode;
txTime += txPrng.next();
sim.doAfter (txTime, new Event()
{
public void perform()
{
nn.addToQueue (query);
}
});
}
System.out.println();
sim.doAfter (txTime, new Event()
{
public void perform()
{
removeFromQueue();
}
});
}
}
private void removeFromQueue()
{
Query query = queryQueue.removeFirst();
System.out.printf ("%.3f %s removed from %s%n",
sim.time(), query, this);
priorQueries.add (query);
if (queryQueue.size() > 0) startServing();
}
public String toString()
{
return "Node " + id;
}
}
private static class Network
{
private Node[] node;
public Network()
{
node = new Node[N];
for (int i = 0; i < N; ++ i) node[i] = new Node (i);
for (int i = 0; i < N; ++ i)
{
node[i].connectTo (node[(i + 1)%N]);
RandomSubset rs = new RandomSubset (prng, N)
.remove (i) .remove ((i + 1)%N);
for (int j = 0; j < K; ++ j)
{
node[i].connectTo (node[rs.next()]);
}
}
}
public void generateQuery()
{
Node origNode = randomNode();
Node matchNode = randomNode();
Query query = new Query (++ queryCount, matchNode);
System.out.printf
("%.3f %s generated, originating %s, matching %s%n",
sim.time(), query, origNode, matchNode);
origNode.addToQueue (query);
if (queryCount < R)
{
sim.doAfter (queryPrng.next(), new Event()
{
public void perform()
{
generateQuery();
}
});
}
}
private Node randomNode()
{
return node[prng.nextInt (node.length)];
}
}
public static void main
(String[] args)
{
// Knobs
if (args.length != 8) usage();
N = Integer.parseInt (args[0]);
K = Integer.parseInt (args[1]);
lambda = Double.parseDouble (args[2]);
tx_L = Double.parseDouble (args[3]);
tx_U = Double.parseDouble (args[4]);
Q = Integer.parseInt (args[5]);
R = Integer.parseInt (args[6]);
seed = Long.parseLong (args[7]);
// Global variables
prng = Random.getInstance (seed);
queryPrng = new ExponentialPrng (prng, lambda);
txPrng = new UniformPrng (prng, tx_L, tx_U);
queryCount = 0;
elapsedTimes = new ListSeries();
successCount = 0;
sim = new Simulation();
network = new Network();
// Run simulation
network.generateQuery();
sim.run();
Series.Stats etStats = elapsedTimes.stats();
double ff = 1.0 - (double)successCount/(double)R;
System.out.printf ("Elapsed time mean = %.3f%n",
etStats.mean);
System.out.printf ("Elapsed time stddev = %.3f%n",
etStats.stddev);
System.out.printf ("Failure fraction = %.3f%n", ff);
}
private static void usage()
{
System.err.println
("Usage: java P2Pedia07 <N> <K> <lambda> <tx_L> "+
"<tx_U> <Q> <R> <seed>");
System.exit (1);
}
}
|
Alan Kaminsky
|
|
•
|
|
Department of Computer Science
|
|
•
|
|
Rochester Institute of Technology
|
|
•
|
|
4486 +
2220 =
6706
|
|
Home Page
|
Copyright © 2011 Alan Kaminsky.
All rights reserved.
Last updated 31-Aug-2011.
Please send comments to ark@cs.rit.edu.