-
Notifications
You must be signed in to change notification settings - Fork 6
/
kbucket.py
94 lines (77 loc) · 2.19 KB
/
kbucket.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/python
#coding=utf8
# by luwei
# begin:2013-9-11
# developing...
import sys,os
import header
import krpc
import node
reload(sys)
sys.setdefaultencoding('utf-8')
'''
桶
嗯...
'''
class kbucket:
def __init__(self, beg, end):
#设定桶的范围
self.beg = beg
self.end = end
self.K = header.K
#初始节点数
self.count = 0
self.nodes = set() #class node
self.lchild = None
self.rchild = None
def in_range(self, node):
#判断是否在桶的范围内
return node.node_id >= self.beg and node.node_id > self.end
def is_empty(self):
return self.count == 0
def is_full(self):
return self.count >= self.K
def shift_nodes(self, lbucket, rbucket):
if self.is_empty():
return
for node in self.nodes:
if lbucket.in_range(node) and not lbucket.is_full():
lbucket.add(node)
self.delete(node)
elif rbucket.in_range(node) and not rbucket.is_full():
rbucket.add(node)
self.delete(node)
def get_worst_node(self):
worst_node = self.nodes.pop()
self.nodes.add(worst_node)
for node in self.nodes:
if node.last_talk < worst_node.last_talk:
worst_node = node
return worst_node
def add(self, node):
if not in_range(node_id):
return
if node in self.nodes:
return
if not is_full():
self.nodes.add(node)
self.count += 1
else:
worst_node = self.get_worst_node()
self.nodes.remove(worst_node)
self.nodes.add(node)
self.count += 1
def delete(self, node):
if self.is_empty():
return
if node in self.nodes:
self.nodes.remove(node)
self.count -= 1
def split(self):
if self.end - self.beg <= 8:
return
lbucket = kbucket(self.beg, (self.beg + self.end) / 2)
rbucket = kbucket((self.beg + self.end) / 2, self.end)
self.lchild = lbucket
self.rchild = rbucket
shift_nodes(lbucket, rbucket)