Вы находитесь на странице: 1из 21

public class NextCycle extends FullNextCycle {

// ============== fields ===============================================

/**

* Gives the list of protocols (whitespace separated) that need to be

* iterated over.

* @config

*/

private static final String PAR_PROTS = "protocol";

private final int[] pids;

// =============== initialization ======================================

/**

* reads configuration parameters and the {@link Scheduler}s.

*/

public NextCycle(String prefix) {

super(prefix);

String prots = Configuration.getString(prefix+"."+PAR_PROTS);

String[] protnames = prots.split("\\s");

pids = new int[protnames.length];

for(int i=0; i<protnames.length; ++i)

pids[i] = Configuration.lookupPid(protnames[i]);

}
// =============== methods =============================================

/**

* Execute the configured protocols on all nodes.

* It works exactly as {@link FullNextCycle#execute}, only just the configured

* protocols are iterated over.

*/

public boolean execute() {

final int cycle=CDState.getCycle();

if( shuffle ) rperm.reset( Network.size() );

for(int j=0; j<Network.size(); ++j)

Node node = null;

if( getpair_rand )

node = Network.get(CDState.r.nextInt(Network.size()));

else if( shuffle )

node = Network.get(rperm.next());

else

node = Network.get(j);

if( !node.isUp() ) continue;

CDState.setNode(node);

CDState.setCycleT(j);

for(int pid: pids)

// Check if the protocol should be executed, given the

// associated scheduler.
if (!protSchedules[pid].active(cycle))

continue;

CDState.setPid(pid);

Protocol protocol = node.getProtocol(pid);

if( protocol instanceof CDProtocol )

((CDProtocol)protocol).nextCycle(node, pid);

if( !node.isUp() ) break;

return false;

public ConfigProperties( String[] pars, String resource ) {

try

if( resource != null )

loadSystemResource(resource);

System.err.println("ConfigProperties: System resource "

+resource+" loaded.");

catch( Exception e )
{

System.err.println("ConfigProperties: " + e );

if( pars == null || pars.length == 0 ) return;

for (int i=0; i < pars.length; i++)

try

load( pars[i] );

System.err.println(

"ConfigProperties: File "+pars[i]+" loaded.");

pars[i] = "";

catch( IOException e )

try

loadPropertyString( pars[i] );

System.err.println("ConfigProperties: Property '" +

pars[i] + "' set.");

catch( Exception e2 )

System.err.println("ConfigProperties: " + e2 );

}
}

catch( Exception e )

System.err.println("ConfigProperties: " + e );

/**

* Constructs a ConfigProperty object by loading a file by calling

* {@link #load}.

* @param fileName The name of the configuration file.

*/

public ConfigProperties( String fileName ) throws IOException {

load( fileName );

/**

* Calls super constructor.

*/

public ConfigProperties( Properties props ) {

super( props );

/**

* Calls {@link #ConfigProperties(String[],String)} with resource set to null.

*/

public ConfigProperties( String[] pars ) {


this( pars, null );

// =========== Public methods ========================================

/**

* Loads given file. Calls <code>Properties.load</code> with a file

* input stream to the given file.

*/

public void load( String fileName ) throws IOException {

FileInputStream fis = new FileInputStream( fileName );

load( fis );

fis.close();

/**

* Adds the properties from the given property file. Searches in the class path

* for the file with the given name.

*/

public void loadSystemResource( String n ) throws IOException {

ClassLoader cl = getClass().getClassLoader();

load( cl.getResourceAsStream( n ) );

/**

* Appends a property defined in the given string.

* The string is considered as a property file line.

* It is converted to a byte array according to the

* default character encoding and then loaded by the


* <code>Properties.load</code> method. This means that the ISO-8859-1

* (or compatible) encoding is assumed.

*/

public void loadPropertyString( String prop ) throws IOException {

StringBuffer sb = new StringBuffer();

sb.append( prop ).append( "\n" );

load( new ByteArrayInputStream(sb.toString().getBytes()) );

public interface Node extends Fallible, Cloneable

/**

* Prefix of the parameters that defines protocols.

* @config

*/

public static final String PAR_PROT = "protocol";

/**

* Returns the <code>i</code>-th protocol in this node. If <code>i</code>

* is not a valid protocol id

* (negative or larger than or equal to the number of protocols), then it throws

* IndexOutOfBoundsException.

*/

public Protocol getProtocol(int i);

/**

* Returns the number of protocols included in this node.


*/

public int protocolSize();

/**

* Sets the index of this node in the internal representation of the node list.

* Applications should not use this method. It is defined as public simply

* because it is not possible to define it otherwise.

* Using this method will result in

* undefined behavior. It is provided for the core system.

*/

public void setIndex(int index);

/**

* Returns the index of this node. It is such that

* <code>Network.get(n.getIndex())</code> returns n. This index can

* change during a simulation, it is not a fixed id. If you need that, use

* {@link #getID}.

* @see Network#get

*/

public int getIndex();

/**

* Returns the unique ID of the node. It is guaranteed that the ID is unique

* during the entire simulation, that is, there will be no different Node

* objects with the same ID in the system during one invocation of the JVM.

* Preferably nodes

* should implement <code>hashCode()</code> based on this ID.

*/
public long getID();

/**

* Clones the node. It is defined as part of the interface

* to change the access right to public and to get rid of the

* <code>throws</code> clause.

*/

public Object clone();

public DynamicNetwork(String prefix)

add = Configuration.getDouble(prefix + "." + PAR_ADD);

substitute = Configuration.contains(prefix + "." + PAR_SUBST);

Object[] tmp = Configuration.getInstanceArray(prefix + "." + PAR_INIT);

inits = new NodeInitializer[tmp.length];

for (int i = 0; i < tmp.length; ++i) {

//System.out.println("Inits " + tmp[i]);

inits[i] = (NodeInitializer) tmp[i];

maxsize=Configuration.getInt(prefix+"."+PAR_MAX,Integer.MAX_VALUE);

minsize = Configuration.getInt(prefix + "." + PAR_MIN, 0);

public SearchDataInitializer(String prefix) {


keywords = Configuration.getLong(prefix + "." + PAR_KEYWORDS);
protocolID = Configuration.getPid(prefix + "." + PAR_PROT);
query_nodes = Configuration.getInt(prefix + "." + PAR_QUERY_NODES,
Network.size());
max_queries = Configuration.getInt(prefix + "." + PAR_MAX_QUERIES, 0);
query_interval = Configuration.getInt(
prefix + "." + PAR_QUERY_INTERVAL, 10);
maxCycles = Configuration.getInt(prefix + "." + PAR_MAX_CYLES, 100);

}
// Methods
// ---------------------------------------------------------------------
/**
* Fills a {@link SearchProtocol} with the keywords representing the

* documents it holds. It is called for each node.


* @param proto
* the protocol instance to initialize
*/
private void initializeData(SearchProtocol proto) {
// create the stored keywords
// number of keywords held by the node (poisson)
int storageSize = CommonState.r.nextPoisson(1 + keywords / 1000);

/* generates a distribution of keyIDs along with their frequencies */

Map<Integer, Integer> keyStorage = makeKeyMap(storageSize);


proto.addKeyStorage(keyStorage);

/**
* Fills a {@link SearchProtocol} with the queries it will initiate.
* @param proto
* the protocol to initialize
*/

private void initializeQueries(SearchProtocol proto) {

int cycle = -1;


int nqueries = 0;
while (true) {
cycle += (1 + CommonState.r.nextPoisson(query_interval));

System.err.println("cycle: " + cycle);


if (cycle > (maxCycles - proto.ttl)) {

System.err
.println("Warn: the TTL probably too large for maxCycles...");

break;
}

if (max_queries > 0 && ++nqueries > max_queries) {


// System.err.println("Warn: ");

break;
}

// number of keywords in the query (exponential)


int querySize = (int) Math.ceil(nextExponential(1.5));

System.err.println("query size: " + querySize);


int[] query = makeKeyArray(querySize);

proto.addQueryData(cycle, query);
}

}
/**

* Generate a set of (keyID, frequency) pairs of the specified size.


* @param size
* The size of the desired set
* @return
*/
private Map<Integer, Integer> makeKeyMap(int size) {
HashMap<Integer, Integer> keys = new HashMap<Integer, Integer>();

while (keys.size() < size) {


int key = (int) Math.ceil(nextPower(keywords / (double) 100, 1.0));

if (key > keywords) /*


* keyIDs grater than the max key number are
* trashed
*/

continue;

Integer ikey = Integer.valueOf(key);


Integer oldValue = (Integer) keys.get(ikey);

int newval = (oldValue == null ? 1 : oldValue.intValue() + 1);


keys.put(ikey, Integer.valueOf(newval));

}
return keys;
}

private int[] makeKeyArray(int size) {

HashSet<Integer> keys = new HashSet<Integer>();


while (keys.size() < size) {
int key = (int) Math.ceil(nextPower(keywords / (double) 100, 1.0));

if (key > keywords)

continue;
keys.add(Integer.valueOf(key));
}

int[] result = new int[size];


Object[] ikeys = keys.toArray();

for (int i = 0; i < size; ++i) {


result[i] = ((Integer) ikeys[i]).intValue();

}
return result;
}

public boolean execute() {

for (int i = 0; i < Network.size(); ++i) {


SearchProtocol proto = ((SearchProtocol) Network.get(i)
.getProtocol(protocolID));

initializeData(proto);
if (i < query_nodes)

initializeQueries(proto);
}
return false;

/**
* Extracts random values according to a power distribution.
*
* @param base
* base
* @param a
* scaling exponent
* @return
*/

private static double nextPower(double base, double a) {


return base / Math.pow(CommonState.r.nextDouble(), a) - base;

public double nextExponential(double b) {

return -1 * b * Math.log(CommonState.r.nextDouble());

}
public SearchObserver(String name) {

this.name = name;

// Other parameters from config file:

pid = Configuration.getPid(name + "." + PAR_PROT);

verbosity = Configuration.getInt(name + "." + PAR_VERBOSITY, 0);

cleanCache = Configuration.contains(name + "." + PAR_CLEAN_CACHE);

public void printItemsStatistics(HashMap messageStats) {

Iterator iterStats = messageStats.values().iterator();


while (iterStats.hasNext()) {

SearchStats stats = (SearchStats) iterStats.next();

if (verbosity == 0 && stats.getAge() < stats.getTtl())

continue;

System.out.println(name + ": " + CommonState.getIntTime() + " "

+ stats.toString());

// System.out.println(stats);
}
}

public SearchStats(int seq, int age, int ttl) {


this.nbSeen = 0;

this.nbHits = 0;

this.nbMessages = 0;

// this.nbExtraProbes = 0;

this.seq = seq;

this.age = age;

this.ttl = ttl;
}
// Methods
public void update(int msgs, int hits) {

++nbSeen;
nbHits += hits;

nbMessages += msgs;
}

public String toString() {


return ("" + seq + "\t" + age + "\t" + nbSeen + "\t" + nbHits + "\t" + nbMessages);

}
public int getAge() {

return age;
}

public void setAge(int age) {

this.age = age;
}

public int getTtl() {


return ttl;

}
public void setTtl(int ttl) {

this.ttl = ttl;
}
public int getNbSeen() {
return nbSeen;

}
}

public SMessage(Node originator, int type, int hops, int[] payload) {


this.originator = originator;

this.type = type;

this.hops = hops;
this.payload = payload;

this.seq = ++seq_generator;
this.start = CDState.getCycle();

}
public Object clone() throws CloneNotSupportedException {

SMessage m = (SMessage) super.clone();


return m;

}
// Methods
public int hashCode() {

return seq;
}

public boolean equals(Object obj) {


return (obj instanceof SMessage) && (((SMessage) obj).seq == this.seq);
}
public String toString() {

return "SMessage[" + seq + "] hops=" + hops;


}

}
/** Creates a new instance of RWProtocol */
public RWProtocol(String prefix) {
super(prefix);

walkers = Configuration.getInt(prefix + "." + PAR_WALKERS, 1);


}

// "Passive" behaviour implementation: process key similarity and notifies


// any match and forwards messages.

public void process(SMessage mes) {

// checks for hits and notifies originator if any:

boolean match = this.match(mes.payload);

if (match)
this.notifyOriginator(mes);

// forwards the message to a random neighbor:

Node neighbor = this.getRNDNeighbor();

this.forward(neighbor, mes);

// "active" behaviour implementation: makes query

public void nextCycle(peersim.core.Node node, int protocolID) {


super.nextCycle(node, protocolID);

// this will handle incoming messages

int[] data = this.pickQueryData(); // if we have to produce a query...

if (data != null) {

System.err.println("DATA");

SMessage m = new SMessage(node, SMessage.QRY, 0, data);

// System.err.println("sending to " + view.size() + " neighbours: "


// + m);

// For ttl <=3 we use flooding and for ttl >3 we use K-Walker Random Walk where K is
prespecified walker number.

if (ttl <=3)
{
for (int i = 0; i <= this.degree(); i++)
{
this.send((Node) this.getNeighbor(i), m);
}
}
else
{
for (int i = 0; i < this.walkers; i++)
{
this.send((Node) this.getNeighbor(i), m);
}

}
}

}
# PEERSIM EXAMPLE iSEARCH

random.seed 1234567890

simulation.cycles 100

control.0 peersim.cdsim.Shuffle

network.size 10000

#network.maxsize 1000

include.protocol Hybrid_Search

protocol.topo peersim.core.IdleProtocol

protocol.topo.capacity 10

protocol.Hybrid_Search peersim.extras.gj.isearch.RWProtocol

#protocol.Hybrid_Search.linkable topo

protocol.Hybrid_Search.ttl 20

init.0 peersim.dynamics.WireKOut

#init.0.protocol topo

init.0.protocol Hybrid_Search

init.0.k 20
init.1 peersim.extras.gj.isearch.SearchDataInitializer

init.1.protocol Hybrid_Search

init.1.keywords 1000

init.1.query_nodes 1

init.1.query_interval 1

init.1.max_queries 1

control.0 peersim.extras.gj.isearch.SearchObserver

control.0.protocol Hybrid_Search

control.0.verbosity 1

control.1 peersim.reports.DegreeStats

control.1.protocol Hybrid_Search

control.1.method list

Вам также может понравиться