Source code for icarus.models.strategy.offpath
"""Implementations of all off-path strategies"""
from __future__ import division
import networkx as nx
from icarus.registry import register_strategy
from icarus.util import inheritdoc, path_links
from .base import Strategy
__all__ = [
'NearestReplicaRouting'
]
[docs]@register_strategy('NRR')
class NearestReplicaRouting(Strategy):
"""Ideal Nearest Replica Routing (NRR) strategy.
In this strategy, a request is forwarded to the topologically closest node
holding a copy of the requested item. This strategy is ideal, as it is
implemented assuming that each node knows the nearest replica of a content
without any signaling
On the return path, content can be caching according to a variety of
metacaching policies. LCE and LCD are currently supported.
"""
def __init__(self, view, controller, metacaching, implementation='ideal',
radius=4, **kwargs):
"""Constructor
Parameters
----------
view : NetworkView
An instance of the network view
controller : NetworkController
An instance of the network controller
metacaching : str (LCE | LCD)
Metacaching policy used
implementation : str, optional
The implementation of the nearest replica discovery. Currently on
ideal routing is implemented, in which each node has omniscient
knowledge of the location of each content.
radius : int, optional
Radius used by nodes to discover the location of a content. Not
used by ideal routing.
"""
super(NearestReplicaRouting, self).__init__(view, controller)
if metacaching not in ('LCE', 'LCD'):
raise ValueError("Metacaching policy %s not supported" % metacaching)
if implementation not in ('ideal', 'approx_1', 'approx_2'):
raise ValueError("Implementation %s not supported" % implementation)
self.metacaching = metacaching
self.implementation = implementation
self.radius = radius
self.distance = nx.all_pairs_dijkstra_path_length(self.view.topology(),
weight='delay')
[docs] @inheritdoc(Strategy)
def process_event(self, time, receiver, content, log):
# get all required data
locations = self.view.content_locations(content)
nearest_replica = min(locations, key=lambda x: self.distance[receiver][x])
# Route request to nearest replica
self.controller.start_session(time, receiver, content, log)
if self.implementation == 'ideal':
self.controller.forward_request_path(receiver, nearest_replica)
elif self.implementation == 'approx_1':
# Floods actual request packets
paths = {loc: len(self.view.shortest_path(receiver, loc)[:self.radius])
for loc in locations}
# TODO: Continue
raise NotImplementedError("Not implemented")
elif self.implementation == 'approx_2':
# Floods meta-request packets
# TODO: Continue
raise NotImplementedError("Not implemented")
else:
# Should never reach this block anyway
raise ValueError("Implementation %s not supported"
% str(self.implementation))
self.controller.get_content(nearest_replica)
# Now we need to return packet and we have options
path = list(reversed(self.view.shortest_path(receiver, nearest_replica)))
if self.metacaching == 'LCE':
for u, v in path_links(path):
self.controller.forward_content_hop(u, v)
if self.view.has_cache(v) and not self.view.cache_lookup(v, content):
self.controller.put_content(v)
elif self.metacaching == 'LCD':
copied = False
for u, v in path_links(path):
self.controller.forward_content_hop(u, v)
if not copied and v != receiver and self.view.has_cache(v):
self.controller.put_content(v)
copied = True
else:
raise ValueError('Metacaching policy %s not supported'
% self.metacaching)
self.controller.end_session()