示例#1
0
 def __init__(self, loadFromDatabase  = config.dbconnected):
     """
     Let's load the routing table here into memory.
     """
     self._routingtable = {}
     self._dbconnected = loadFromDatabase
     if loadFromDatabase:
         self._rtm_db = RoutingTableManagerDB()
         for entry in self._rtm_db.getRoutingTableEntries():
             self.addEntry(entry, 1)
示例#2
0
class RoutingTableManager:
    """
    Holds the routing table in the memory.
    
    Architecture:
    
        1. For each reachable community we have one entry in the dictionary - key is the community id,
            value is an ordered list
        2. The ordered list is the list of routing entries with destination community, the key for ordering is
            the costs for the route.
    """

    def __init__(self, loadFromDatabase  = config.dbconnected):
        """
        Let's load the routing table here into memory.
        """
        self._routingtable = {}
        self._dbconnected = loadFromDatabase
        if loadFromDatabase:
            self._rtm_db = RoutingTableManagerDB()
            for entry in self._rtm_db.getRoutingTableEntries():
                self.addEntry(entry, 1)

    def __str__(self):
        """
        Some basic information about the object
        """
        return "RoutingTableManager: %d communities routable" %(len(self._routingtable))
        
    def addEntry(self, entry, loading = 0, skipMoreExpensive = 1):
        """
        Adds an routing entry to the manager.
        
        If loading is false, the new value is written through to the database.
        
        @param entry: Routing table entry to add
        @type entry: L{RoutingTableEntry}
        @param loading: Indicates, whether the change shall be written through to the routing table
        @type loading: C{Boolean}
        @param skipMoreExpensive: Inidicates, whether new entries with same src, dst community and same gw but higher costs than current value shall be skipped
        @type skipMoreExpensive: C{Boolean}
        """
        if not self._routingtable.has_key(entry.getDestinationTC()):
            self._routingtable[entry.getDestinationTC()] = {}
        if not self._routingtable[entry.getDestinationTC()].has_key(entry.getSourceTC()):
            self._routingtable[entry.getDestinationTC()][entry.getSourceTC()] = []
        entries = self._routingtable[entry.getDestinationTC()][entry.getSourceTC()]
        
        # put the new entry into the list at the correct position
        pos = 0
        for e in entries:
            if skipMoreExpensive:
                # if we have exactly this entry in the routing table already
                if e.getGWCommunityId() == entry.getGWCommunityId() and e.getGWMemberId() == entry.getGWMemberId():
                    # simply skip it if costs are higher
                    if e.getCosts() <= entry.getCosts(): 
                        pass
                    else:
                        # update the entry in the manager / database
                        self._routingtable[entry.getDestinationTC()][entry.getSourceTC()][pos] = entry
                        if not loading and self._dbconnected:
                            self._rtm_db.updateRoutingTableEntry(e, entry)
                    return
            if e.getCosts() > entry.getCosts():
                break
            pos += 1
        self._routingtable[entry.getDestinationTC()][entry.getSourceTC()].insert(pos, entry)
        
        if not loading and self._dbconnected:
            self._rtm_db.addRoutingTableEntry(entry)
                
    def getAllEntriesForCommunityPair(self, sourceCommunityId, destinationCommunityId):
        """
        Returns all entries for the pair - source commuity - destination community
        """
        return self._routingtable[destinationCommunityId][sourceCommunityId]

    def getNexthopForCommunity(self, destinationcommunityid, sourcecommunityid = None):
        """
        Returns the member id of the next hop on the route towards the final destination's community.
        
        Automatically, the route with the lowest costs for this destination community is chosen.
        
        If L{sourcecommunityid} is not given, any will be chosen, in fact the one which causes the lowest costs.
        """
        if not sourcecommunityid:
            # ok, there is not src given, so let's just iterate through the communities, the local member
            # is member of; take the one with the shortest route finally.
            from communitymanager import getMemberManager
            from errorhandling import G4dsCommunicationException
            retList = []
            for commid in getMemberManager().getLocalMember().getCommunityIds():
                try:
                    bestForSource = self.getNexthopForCommunity(destinationcommunityid, commid)
                    retList.append(bestForSource)
                except G4dsCommunicationException, msg:
                    # fair enough; nothing to get for this src
                    pass
                    
            if not len(retList):
                raise G4dsCommunicationException('No route found for community %s.' %(destinationcommunityid))
            
            fastest = retList[0]
            for entry in retList[1:]:
                if entry[2] < fastest[2]:
                    fastest = entry
            return fastest
        
        from errorhandling import G4dsCommunicationException
        try:
            entries = self.getAllEntriesForCommunityPair(sourcecommunityid, destinationcommunityid)
        except KeyError, msg:
            raise G4dsCommunicationException('No route found for community %s.' %(destinationcommunityid))