class Ciri::P2P::Kad::KBucket

Attributes

end_id[R]
k_size[R]
last_updated[R]
nodes[R]
replacement_cache[R]
start_id[R]

Public Class Methods

new(start_id:, end_id:, k_size: K_BUCKET_SIZE) click to toggle source
# 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

Public Instance Methods

add(node) click to toggle source

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.

# 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) click to toggle source
# File lib/ciri/p2p/kad.rb, line 121
def cover?(node)
  @start_id <= node.id && node.id <= @end_id
end
delete(node) click to toggle source
# File lib/ciri/p2p/kad.rb, line 117
def delete(node)
  @nodes.delete(node)
end
distance_to(id) click to toggle source
# File lib/ciri/p2p/kad.rb, line 84
def distance_to(id)
  midpoint ^ id
end
full?() click to toggle source
# File lib/ciri/p2p/kad.rb, line 125
def full?
  @nodes.size == k_size
end
head() click to toggle source
# File lib/ciri/p2p/kad.rb, line 147
def head
  @nodes[0]
end
include?(node) click to toggle source
# File lib/ciri/p2p/kad.rb, line 151
def include?(node)
  @nodes.include?(node)
end
midpoint() click to toggle source

use to compute node distance with kbucket

# File lib/ciri/p2p/kad.rb, line 80
def midpoint
  @start_id + (@end_id - @start_id) / 2
end
nodes_by_distance_to(id) click to toggle source

find neighbour nodes

# 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() click to toggle source
# File lib/ciri/p2p/kad.rb, line 155
def size
  @nodes.size
end
split() click to toggle source

split to two kbucket by midpoint

# 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