/* * @(#)DistributedBubbleRap.java * * Copyright 2010 by University of Pittsburgh, released under GPLv3. * */ package routing.community; import java.util.*; import core.*; import routing.DecisionEngineRouter; import routing.MessageRouter; import routing.RoutingDecisionEngine; /** *

Implements the Distributed BubbleRap Routing Algorithm from Hui et al. * 2008 (Bibtex record included for convenience). The paper is a bit fuzzy on * thevactual implementation details. Choices exist for methods of community * detection (SIMPLE, K-CLIQUE, MODULARITY) and local centrality approximation * (DEGREE, S-WINDOW, C-WINDOW).

* *

In general, each node maintains an idea of it's local community, a group * of nodes it meets with frequently. It also approximates its centrality within * the social network defined by this local community and within the global * social network defined by all nodes.

* *

When a node has a message for a destination, D, and D is not part of its * local community, it forwards the message to "more globally central" nodes, * those that estimate a higher global centrality value. The intuition here is * that nodes in the center of the social network are more likely to contact the * destination. In this fashion the message bubbles up social network to more * central nodes until a node is found that reports D in its local community. * At this point, the message is only routed with in the nodes of the local * community and propagated towards more locally central nodes or the * destination until delivered.

* *

 * \@inproceedings{1374652,
 *	Address = {New York, NY, USA},
 *	Author = {Hui, Pan and Crowcroft, Jon and Yoneki, Eiko},
 *	Booktitle = {MobiHoc '08: Proceedings of the 9th ACM international symposium 
 *		on Mobile ad hoc networking and computing},
 *	Doi = {http://doi.acm.org/10.1145/1374618.1374652},
 *	Isbn = {978-1-60558-073-9},
 *	Location = {Hong Kong, Hong Kong, China},
 *	Pages = {241--250},
 *	Publisher = {ACM},
 *	Title = {BUBBLE Rap: Social-based Forwarding in Delay Tolerant Networks},
 *	Url = {http://portal.acm.org/ft_gateway.cfm?id=1374652&type=pdf&coll=GUIDE&dl=GUIDE&CFID=55195392&CFTOKEN=93998863},
 *	Year = {2008}
 * }
 * 
* * @author PJ Dillon, University of Pittsburgh * */ public class DistributedBubbleRap implements RoutingDecisionEngine, CommunityDetectionEngine { /** Community Detection Algorithm to employ -setting id {@value} */ public static final String COMMUNITY_ALG_SETTING = "communityDetectAlg"; /** Centrality Computation Algorithm to employ -setting id {@value} */ public static final String CENTRALITY_ALG_SETTING = "centralityAlg"; protected Map startTimestamps; protected Map> connHistory; protected CommunityDetection community; protected Centrality centrality; /** * Constructs a DistributedBubbleRap Decision Engine based upon the settings * defined in the Settings object parameter. The class looks for the class * names of the community detection and centrality algorithms that should be * employed used to perform the routing. * * @param s Settings to configure the object */ public DistributedBubbleRap(Settings s) { if(s.contains(COMMUNITY_ALG_SETTING)) this.community = (CommunityDetection) s.createIntializedObject(s.getSetting(COMMUNITY_ALG_SETTING)); else this.community = new SimpleCommunityDetection(s); if(s.contains(CENTRALITY_ALG_SETTING)) this.centrality = (Centrality) s.createIntializedObject(s.getSetting(CENTRALITY_ALG_SETTING)); else this.centrality = new SWindowCentrality(s); } /** * Constructs a DistributedBubbleRap Decision Engine from the argument * prototype. * * @param proto Prototype DistributedBubbleRap upon which to base this object */ public DistributedBubbleRap(DistributedBubbleRap proto) { this.community = proto.community.replicate(); this.centrality = proto.centrality.replicate(); startTimestamps = new HashMap(); connHistory = new HashMap>(); } public void connectionUp(DTNHost thisHost, DTNHost peer){} /** * Starts timing the duration of this new connection and informs the community * detection object that a new connection was formed. * * @see routing.RoutingDecisionEngine#doExchangeForNewConnection(core.Connection, core.DTNHost) */ public void doExchangeForNewConnection(Connection con, DTNHost peer) { DTNHost myHost = con.getOtherNode(peer); DistributedBubbleRap de = this.getOtherDecisionEngine(peer); this.startTimestamps.put(peer, SimClock.getTime()); de.startTimestamps.put(myHost, SimClock.getTime()); this.community.newConnection(myHost, peer, de.community); } public void connectionDown(DTNHost thisHost, DTNHost peer) { double time = startTimestamps.get(peer); double etime = SimClock.getTime(); // Find or create the connection history list List history; if(!connHistory.containsKey(peer)) { history = new LinkedList(); connHistory.put(peer, history); } else history = connHistory.get(peer); // add this connection to the list if(etime - time > 0) history.add(new Duration(time, etime)); CommunityDetection peerCD = this.getOtherDecisionEngine(peer).community; // inform the community detection object that a connection was lost. // The object might need the whole connection history at this point. community.connectionLost(thisHost, peer, peerCD, history); startTimestamps.remove(peer); } public boolean newMessage(Message m) { return true; // Always keep and attempt to forward a created message } public boolean isFinalDest(Message m, DTNHost aHost) { return m.getTo() == aHost; // Unicast Routing } public boolean shouldSaveReceivedMessage(Message m, DTNHost thisHost) { return m.getTo() != thisHost; } public boolean shouldSendMessageToHost(Message m, DTNHost otherHost) { if(m.getTo() == otherHost) return true; // trivial to deliver to final dest /* * Here is where we decide when to forward along a message. * * DiBuBB works such that it first forwards to the most globally central * nodes in the network until it finds a node that has the message's * destination as part of it's local community. At this point, it uses * the local centrality metric to forward a message within the community. */ DTNHost dest = m.getTo(); DistributedBubbleRap de = getOtherDecisionEngine(otherHost); // Which of us has the dest in our local communities, this host or the peer boolean peerInCommunity = de.commumesWithHost(dest); boolean meInCommunity = this.commumesWithHost(dest); if(peerInCommunity && !meInCommunity) // peer is in local commun. of dest return true; else if(!peerInCommunity && meInCommunity) // I'm in local commun. of dest return false; else if(peerInCommunity) // we're both in the local community of destination { // Forward to the one with the higher local centrality (in our community) if(de.getLocalCentrality() > this.getLocalCentrality()) return true; else return false; } // Neither in local community, forward to more globally central node else if(de.getGlobalCentrality() > this.getGlobalCentrality()) return true; return false; } public boolean shouldDeleteSentMessage(Message m, DTNHost otherHost) { // DiBuBB allows a node to remove a message once it's forwarded it into the // local community of the destination DistributedBubbleRap de = this.getOtherDecisionEngine(otherHost); return de.commumesWithHost(m.getTo()) && !this.commumesWithHost(m.getTo()); } public boolean shouldDeleteOldMessage(Message m, DTNHost hostReportingOld) { DistributedBubbleRap de = this.getOtherDecisionEngine(hostReportingOld); return de.commumesWithHost(m.getTo()) && !this.commumesWithHost(m.getTo()); } public RoutingDecisionEngine replicate() { return new DistributedBubbleRap(this); } protected boolean commumesWithHost(DTNHost h) { return community.isHostInCommunity(h); } protected double getLocalCentrality() { return this.centrality.getLocalCentrality(connHistory, community); } protected double getGlobalCentrality() { return this.centrality.getGlobalCentrality(connHistory); } private DistributedBubbleRap getOtherDecisionEngine(DTNHost h) { MessageRouter otherRouter = h.getRouter(); assert otherRouter instanceof DecisionEngineRouter : "This router only works " + " with other routers of same type"; return (DistributedBubbleRap) ((DecisionEngineRouter)otherRouter).getDecisionEngine(); } public Set getLocalCommunity() {return this.community.getLocalCommunity();} }