1 ## Copyright 2002-2003 Andrew Loewenstern, All Rights Reserved
2 # see LICENSE.txt for license information
4 """Some utitlity functions for use in apt-p2p's khashmir DHT."""
6 from twisted.trial import unittest
8 from khash import HASH_LENGTH
11 """Given a list of khashmir instances, finds min, max, and average number of nodes in tables."""
16 for bucket in buckets:
20 c = count(node.table.buckets)
29 return {'min':min, 'max':max, 'avg':avg}
32 """Extract the contact info from a compact node representation.
35 @param s: the compact representation
37 @return: the node ID, IP address and port to contact the node on
38 @raise ValueError: if the compact representation doesn't exist
40 if (len(s) != HASH_LENGTH+6):
43 host = '.'.join([str(ord(i)) for i in s[HASH_LENGTH:(HASH_LENGTH+4)]])
44 port = (ord(s[HASH_LENGTH+4]) << 8) | ord(s[HASH_LENGTH+5])
45 return {'id': id, 'host': host, 'port': port}
47 def compact(id, host, port):
48 """Create a compact representation of node contact info.
51 @param id: the node ID
53 @param host: the IP address of the node
55 @param port: the port number to contact the node on
57 @return: the compact representation
58 @raise ValueError: if the compact representation doesn't exist
61 s = id + ''.join([chr(int(i)) for i in host.split('.')]) + \
62 chr((port & 0xFF00) >> 8) + chr(port & 0xFF)
68 """Format a byte size for reading by the user.
71 @param s: the number of bytes
73 @return: the formatted size with appropriate units
76 r = str(int(s*1000.0)/1000.0) + 'B'
78 r = str(int(s*100.0)/100.0) + 'B'
80 r = str(int(s*10.0)/10.0) + 'B'
84 r = str(int((s/1024.0)*100.0)/100.0) + 'KiB'
86 r = str(int((s/1024.0)*10.0)/10.0) + 'KiB'
88 r = str(int(s/1024)) + 'KiB'
90 r = str(int((s/1048576.0)*100.0)/100.0) + 'MiB'
91 elif (s < 107374182L):
92 r = str(int((s/1048576.0)*10.0)/10.0) + 'MiB'
93 elif (s < 1073741824L):
94 r = str(int(s/1048576)) + 'MiB'
95 elif (s < 1099511627776L):
96 r = str(int((s/1073741824.0)*100.0)/100.0) + 'GiB'
98 r = str(int((s/1099511627776.0)*100.0)/100.0) + 'TiB'
101 class TestUtil(unittest.TestCase):
102 """Tests for the utilities."""
105 myid = '\xca\xec\xb8\x0c\x00\xe7\x07\xf8~])\x8f\x9d\xe5_B\xff\x1a\xc4!'
106 host = '165.234.1.34'
109 def test_compact(self):
110 d = uncompact(compact(self.myid, self.host, self.port))
111 self.failUnlessEqual(d['id'], self.myid)
112 self.failUnlessEqual(d['host'], self.host)
113 self.failUnlessEqual(d['port'], self.port)