123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- from dht_common import between, SIZE_OF_HASH, SIZE_OF_IP_ADDRESS
- class Base_Node(object):
- def __init__(self, nodeID, documentSize, numItems=0, table=[]):
- self.nodeID = nodeID
- self.nextNode = None
- self.documentSize = documentSize
- self.numItems = numItems
- self.table = dict(table)
- self.numRounds = 0
- self.numMessagesSent = 0
- self.numMessagesRecv = 0
- self.numBytesSent = 0
- self.numBytesRecv = 0
- self.lastNumRounds = 0
- self.lastNumMessagesSent = 0
- self.lastNumMessagesRecv = 0
- self.lastNumBytesSent = 0
- self.lastNumBytesRecv = 0
- def insert(self):
- self.numItems += 1
- self.numRounds += 1
- self.numMessagesSent += 1
- self.numMessagesRecv += 1
- self.numBytesSent += SIZE_OF_HASH
- self.numBytesRecv += self.documentSize
- # There has to be some way of inserting finger table values,
- # so this is it (Normally only the DHT should be interfacing with it)
- def insert_relation(self, nodeID, fingerTableValue):
- # nextNode is kept up to date so that when doing finger table searches,
- # we can know when we own something or it needs to go somewhere else
- if not self.nextNode or between(nodeID, self.nodeID, self.nextNode):
- self.nextNode = nodeID
- self.table[nodeID] = fingerTableValue
- def retrieve(self):
- self.numRounds += 1
- self.numMessagesSent += 1
- self.numMessagesRecv += 1
- self.numBytesSent += self.documentSize
- self.numBytesRecv += SIZE_OF_HASH
- def get_finger_table_val(self, searchID):
- # if we should own this ID, say so
- if between(searchID, self.nodeID, self.nextNode):
- retval = (self.nodeID, -1)
- else: # otherwise, find the best option in the finger table and give that back
- options = [x for (x,y) in self.table.items() if x <= searchID]
- closest = max(options) if len(options) > 0 else max([x for (x,y) in self.table.items()])
- retval = (closest, self.table[closest])
- self.numRounds += 1
- self.numMessagesSent += 1
- self.numMessagesRecv += 1
- self.numBytesSent += SIZE_OF_HASH + SIZE_OF_IP_ADDRESS
- self.numBytesRecv += SIZE_OF_HASH
- return retval
- def get_num_rounds(self):
- self.lastNumRounds = self.numRounds
- return self.numRounds
- def get_recent_num_rounds(self):
- retval = self.numRounds - self.lastNumRounds
- self.lastNumRounds = self.numRounds
- return retval
- def get_num_messages_sent(self):
- self.lastNumMessagesSent = self.numMessagesSent
- return self.numMessagesSent
- def get_recent_num_messages_sent(self):
- retval = self.numMessagesSent - self.lastNumMessagesSent
- self.lastNumMessagesSent = self.numMessagesSent
- return retval
- def get_num_messages_recv(self):
- self.lastNumMessagesRecv = self.numMessagesRecv
- return self.numMessagesRecv
- def get_recent_num_messages_recv(self):
- retval = self.numMessagesRecv - self.lastNumMessagesRecv
- self.lastNumMessagesRecv = self.numMessagesRecv
- return retval
- def get_num_bytes_sent(self):
- self.lastNumBytesSent = self.numBytesSent
- return self.numBytesSent
- def get_recent_num_bytes_sent(self):
- retval = self.numBytesSent - self.lastNumBytesSent
- self.lastNumBytesSent = self.numBytesSent
- return retval
- def get_num_bytes_recv(self):
- self.lastNumBytesRecv = self.numBytesRecv
- return self.numBytesRecv
- def get_recent_num_bytes_recv(self):
- retval = self.numBytesRecv - self.lastNumBytesRecv
- self.lastNumBytesRecv = self.numBytesRecv
- return retval
- # Normally this file is a class to be used elsewhere,
- # but if you run it directly it performs some rudimentary unit tests
- # TODO: Add unit tests for size calculations
- if __name__ == "__main__":
- SIZE_OF_DOCUMENTS_IN_TEST = 1024
- test = Base_Node(0, SIZE_OF_DOCUMENTS_IN_TEST)
-
- [test.insert(x, x) for x in range(10)]
- retrievals = [test.retrieve(x) for x in range(10)]
- print("Insert and retrieval fires correctly.")
-
- test.retrieve("nothere")
- print("Nonexistant entries fires correctly.")
- test.insert_relation(1, 1)
- test.insert_relation(2, 2)
- test.insert_relation(4, 4)
- test.insert_relation(8, 8)
- assert test.get_finger_table_val(1) == (1, 1)
- assert test.get_finger_table_val(3) == (2, 2)
- assert test.get_finger_table_val(4) == (4, 4)
- assert test.get_finger_table_val(7) == (4, 4)
- assert test.get_finger_table_val(0) == (0, -1)
- print("Finger table stuff working correctly")
|