Class: Ciri::P2P::Kad::KBucket
- Inherits:
-
Object
- Object
- Ciri::P2P::Kad::KBucket
- Defined in:
- lib/ciri/p2p/kad.rb
Instance Attribute Summary collapse
-
#end_id ⇒ Object
readonly
Returns the value of attribute end_id.
-
#k_size ⇒ Object
readonly
Returns the value of attribute k_size.
-
#last_updated ⇒ Object
readonly
Returns the value of attribute last_updated.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#replacement_cache ⇒ Object
readonly
Returns the value of attribute replacement_cache.
-
#start_id ⇒ Object
readonly
Returns the value of attribute start_id.
Instance Method Summary collapse
-
#add(node) ⇒ Object
Try add node into bucket if node is exists, it is moved to the tail if the node is node exists and bucket not full, it is added at tail if the bucket is full, node will added to replacement_cache, and return the head of the list, which should be evicted if it failed to respond to a ping.
- #cover?(node) ⇒ Boolean
- #delete(node) ⇒ Object
- #distance_to(id) ⇒ Object
- #full? ⇒ Boolean
- #head ⇒ Object
- #include?(node) ⇒ Boolean
-
#initialize(start_id:, end_id:, k_size: K_BUCKET_SIZE) ⇒ KBucket
constructor
A new instance of KBucket.
-
#midpoint ⇒ Object
use to compute node distance with kbucket.
-
#nodes_by_distance_to(id) ⇒ Object
find neighbour nodes.
- #size ⇒ Object
-
#split ⇒ Object
split to two kbucket by midpoint.
Constructor Details
#initialize(start_id:, end_id:, k_size: K_BUCKET_SIZE) ⇒ KBucket
Returns a new instance of KBucket.
70 71 72 73 74 75 76 77 |
# File 'lib/ciri/p2p/kad.rb', line 70 def initialize(start_id:, end_id:, k_size: K_BUCKET_SIZE) @start_id = start_id @end_id = end_id @k_size = k_size @nodes = [] @replacement_cache = [] @last_updated = Time.now.to_i end |
Instance Attribute Details
#end_id ⇒ Object (readonly)
Returns the value of attribute end_id.
68 69 70 |
# File 'lib/ciri/p2p/kad.rb', line 68 def end_id @end_id end |
#k_size ⇒ Object (readonly)
Returns the value of attribute k_size.
68 69 70 |
# File 'lib/ciri/p2p/kad.rb', line 68 def k_size @k_size end |
#last_updated ⇒ Object (readonly)
Returns the value of attribute last_updated.
68 69 70 |
# File 'lib/ciri/p2p/kad.rb', line 68 def last_updated @last_updated end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
68 69 70 |
# File 'lib/ciri/p2p/kad.rb', line 68 def nodes @nodes end |
#replacement_cache ⇒ Object (readonly)
Returns the value of attribute replacement_cache.
68 69 70 |
# File 'lib/ciri/p2p/kad.rb', line 68 def replacement_cache @replacement_cache end |
#start_id ⇒ Object (readonly)
Returns the value of attribute start_id.
68 69 70 |
# File 'lib/ciri/p2p/kad.rb', line 68 def start_id @start_id end |
Instance Method Details
#add(node) ⇒ Object
Try add node into bucket if node is exists, it is moved to the tail if the node is node exists and bucket not full, it is added at tail if the bucket is full, node will added to replacement_cache, and return the head of the list, which should be evicted if it failed to respond to a ping.
133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/ciri/p2p/kad.rb', line 133 def add(node) @last_updated = Time.now.to_i if @nodes.include?(node) @nodes.delete(node) @nodes << node elsif @nodes.size < k_size @nodes << node else @replacement_cache << node return head end nil end |
#cover?(node) ⇒ Boolean
121 122 123 |
# File 'lib/ciri/p2p/kad.rb', line 121 def cover?(node) @start_id <= node.id && node.id <= @end_id end |
#delete(node) ⇒ Object
117 118 119 |
# File 'lib/ciri/p2p/kad.rb', line 117 def delete(node) @nodes.delete(node) end |
#distance_to(id) ⇒ Object
84 85 86 |
# File 'lib/ciri/p2p/kad.rb', line 84 def distance_to(id) midpoint ^ id end |
#full? ⇒ Boolean
125 126 127 |
# File 'lib/ciri/p2p/kad.rb', line 125 def full? @nodes.size == k_size end |
#head ⇒ Object
147 148 149 |
# File 'lib/ciri/p2p/kad.rb', line 147 def head @nodes[0] end |
#include?(node) ⇒ Boolean
151 152 153 |
# File 'lib/ciri/p2p/kad.rb', line 151 def include?(node) @nodes.include?(node) end |
#midpoint ⇒ Object
use to compute node distance with kbucket
80 81 82 |
# File 'lib/ciri/p2p/kad.rb', line 80 def midpoint @start_id + (@end_id - @start_id) / 2 end |
#nodes_by_distance_to(id) ⇒ Object
find neighbour nodes
89 90 91 92 93 |
# File 'lib/ciri/p2p/kad.rb', line 89 def nodes_by_distance_to(id) @nodes.sort_by do |node| node.distance_to(id) end end |
#size ⇒ Object
155 156 157 |
# File 'lib/ciri/p2p/kad.rb', line 155 def size @nodes.size end |
#split ⇒ Object
split to two kbucket by midpoint
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ciri/p2p/kad.rb', line 96 def split split_point = midpoint lower = KBucket.new(start_id: @start_id, end_id: split_point) upper = KBucket.new(start_id: split_point + 1, end_id: @end_id) @nodes.each do |node| if node.id <= split_point lower.add(node) else upper.add(node) end end @replacement_cache.each do |node| if node.id <= split_point lower.replacement_cache << node else upper.replacement_cache << node end end [lower, upper] end |