Kadmelia K-Bucket算法中的路由表,而无需遍历节点ID中的每个位

时间:2018-07-03 13:13:10

标签: go bit-manipulation dht kademlia

上下文

我正在尝试实现Kadmelia的K-Bucket算法以跟踪更近的节点。我从理论上了解了算法的工作原理

  1. 当新节点为CompletableFuture
  2. 如果存储桶大小未超过k(存储桶大小),我们会将其添加到当前存储桶中
  3. 否则,我们将存储桶拆分,并通过循环遍历每个位将其划分为父存储桶中的触点,并将它们拆分为两个存储桶。
  4. 这还意味着对于给定的节点,将有added个存储桶(或列表)

问题

问题与本示例http://blog.notdot.net/2009/11/Implementing-a-DHT-in-Go-part-1

中采用的方法有关

鉴于我们已将Node定义为长度为20的字节数组

k * 8

我试图了解 const IdLength = 20 type NodeID [IdLength]byte 函数在实际计算前缀并填充路由表方面的作用。我了解该方法的每个组件的作用。我的意思是说,我了解位运算符的作用,并了解PrefixLen与1一起检查是否设置了位。

我不明白的是返回值以及为什么用这种方式设置它们。

AND

返回值如何适合用作路由表的索引?



func (node NodeID) PrefixLen() (ret int) {
  for i := 0; i < IdLength; i++ {
    for j := 0; j < 8; j++ {
      if (node[i] >> uint8(7 - j)) & 0x1 != 0 {
        return i * 8 + j;
      }
    }
  }
  return IdLength * 8 - 1;
}

这种方法与遍历每个位有何相同?作者如何使用PrefixLen方法获得相同的结果。

您能否通过示例帮助我理解这一点。预先感谢。

1 个答案:

答案 0 :(得分:3)

  

这种方法与遍历每个位有何相同?

循环简单地遍历字节,然后对每个字节遍历位进行移位和屏蔽。因此实际上,它确实对所有位进行了迭代,因为存储器的最小可寻址单元通常为一个字节,所以这些位恰好被打包为字节。

  

我不明白的是返回值以及为什么用这种方式设置它们。

它只是根据i个完整字节和最后一个部分字节中的j位来计算位的位置。

  

上下文

这里的上下文实际上是错误的,因为您在查看具有固定数组布局的代码示例时试图解释可拆分路由表的设计。 That is a common source of confusion