예제 #1
0
  def __init__(self, node, peersParams):
    """ Constructor
    node : node using this manager
    peersParams : initialization parameters of the peer manager, a list
    [entitiesFileName, maxPeers, logger]
    """
    self.node = node    
    self.entitiesFileName = peersParams[0]
    self.maxPeers = peersParams[1]
    self.logger = peersParams[2]

    # hash table of peers indexed by ID
    self.peers     = {}
    # clountercloclwise ordered list of peers 
    self.ccwPeers  = CcwList()
    # distance ordered list of peers
    self.distPeers = DistList()
예제 #2
0
class PeersManager:
  """ Manage all the neighbours of a node """
  def __init__(self, node, peersParams):
    """ Constructor
    node : node using this manager
    peersParams : initialization parameters of the peer manager, a list
    [entitiesFileName, maxPeers, logger]
    """
    self.node = node    
    self.entitiesFileName = peersParams[0]
    self.maxPeers = peersParams[1]
    self.logger = peersParams[2]

    # hash table of peers indexed by ID
    self.peers     = {}
    # clountercloclwise ordered list of peers 
    self.ccwPeers  = CcwList()
    # distance ordered list of peers
    self.distPeers = DistList()


  def createPeer(self, netAddress):
    """ create a new Peer object
    netAddress : the network address of this peer, e.g. '193.168.25.36:2456'
    Return a Peer object"""
    host, port = netAddress.split(":")
    return Peer(netAddress, host, int(port))

    
  def getRandomPeer(self):
    """ Return a peer randomly chosen from a file
    Read the entities file and return a random peer
    """
    try:
      f = file(self.entitiesFileName, 'r')
    
      # read file
      list = f.readlines()
    
      # retrieve peer
      peer = random.choice(list)
      host, stringPort = string.splitfields(peer)
      port = int(stringPort)
      
      f.close()
    except:
      self.logger.critical("Cannot read file " + self.entitiesFileName)
      raise
    
    id = host + ":" + stringPort
    return Peer(id, host, port)
    
  def addPeer(self, p):
    """ add a new peer
    p : a peer object
    """
    referencePosition = self.node.position
    p.setLocalPosition(referencePosition) 

    id = p.getId()
    if not id:
      raise SolipsisInternalError("Error peer has no id")

    if self.peers.has_key(id):
      raise SolipsisInternalError("Error duplicate peer id:" + id)

    self.peers[p.getId()] = p
    
    self.ccwPeers.insert(p)
    self.distPeers.insert(p)

  def removePeer(self, p):
    """ remove a peer
    p : peer to remove """
    
    id = p.getId()
    if not id:
      raise SolipsisInternalError("Error peer has no id")

    if not self.peers.has_key(id):
      raise SolipsisInternalError("Error removing peer - no peer with id:" + id)
    
    del self.peers[id]
    self.ccwPeers.delete(p)
    self.distPeers.delete(p)

  def updatePeer(self, p):
    """ update information on a peer. """
    self.removePeer(p)
    self.addPeer(p)
    
  def getPeer(self, netAddress):
    """ Return the peer associated with this net address """
    # TODO check exception if this peer doesn't exist
    id = Node.createId(address[0], address[1])
    return self.peers[id]

  def heartbeat(self, id):
    """ Update status of a peer
    id : id of the peer that sent us a HEARTBEAT message
    """    
    peer = self.peers[id]
    peer.setActiveTime(time.time())

  def getPeerFromAddress(self, address):
    """ Get the peer with address 'address'
    address: address of the peer we are looking at
    Return : a peer, or None if no such peer was found
    """
    # Iterate through list of peers
    ids = self.peers.keys()
    for id in ids:
      p = self.peers[id]
      if p.address == address:
        return p

    # no peer with this address was found
    return None
    

  def getClosestPeer(self, target):
    """ Return the peer that is the closest to a target position
    """
    closestPeer = self.peers.values()[0]
    for p in self.peers.values():
      if p.isCloser(closestPeer, target):
        closestPeer = p

    return closestPeer
      

  def getPeerAround(self, nodePosition, targetPosition):
    """ Return the peer that is the closest to a target position and that
    is in the right half plane.
    nodePosition : position of the node asking for a peer around
    targetPosition : target position which we are looking around
    Return : a peer
             or None if there is no peer in the right half plane
    """
    found = False
    around = None
    distClosest = 0
    
    for p in self.peers.values():
      if Geometry.inHalfPlane(nodePosition, targetPosition, p.position):
        # first entity in right half-plane
        if not found:
          found = True 
          around = p
          distClosest = Geometry.distance(targetPosition, p.position)
        else:
          dist = Geometry.distance(targetPosition, p.position)
          # this peer is closer
          if dist < distClosest:
            around = p
            distClosest = dist

    return around

  def hasTooManyPeers(self):
    """ Check if we have too many neighbours
    Return True if we have too many peers"""
    return len(self.peers) > self.maxPeers

  def getWorstPeer(self):
    """ Choose a peer for removal. Removing this must NOT break the global
    connectivity rule. """
    
    # filter list of neighbors
    # keep only entities not in Awareness Area which do not provoke mis-respect
    # of Global Connectivity Rule

    FilterList = []
    endFilter = 1
    indexFilter = self.distPeers.length - 1
    nodePos = self.node.position
    
    while endFilter and indexFilter > 0:
      ent = self.distPeers.ll[indexFilter]
      distEnt = Geometry.distance(ent.position, nodePos)
        
      # first, verify that ent is not in Awareness Area
      if distEnt > self.node.awarenessRadius :
        if distEnt > ent.awarenessRadius:

          indInCcw = self.ccwPeers.ll.index(ent)
          successor = self.ccwPeers.ll[(indInCcw + 1) % self.ccwPeers.length]
          predecessor = self.ccwPeers.ll[indInCcw - 1]

          # then verify that ent is not mandatory for Rule respect
          if Geometry.inHalfPlane(predecessor.position, nodePos,
                         successor.position):
	    FilterList.append(ent)
      
      else:
        # stop iteration because all following entities are in Awareness Radius
        endFilter = 0

      indexFilter -= 1

    if FilterList <> []:

      # there is a posibility to remove any entity in FilterList.
      # By default, we decide to remove the farthest entity.
      # In article presented at RESH'02, we proposed several other possibilities
      # for more efficient choice.
      result = FilterList[0]
    
    else:
      result = 0

    return result

  def enumerate(self):
    """ return a list with all peers """
    return self.distPeers

  def update(self):
    """ position of the node has changed rrecompute all neighbours postion """
    self.logger.critical("manager.update NOT IMPLEMENTED")
    raise SolipsisInternalError("manager.update NOT IMPLEMENTED")