语境
我正在尝试实现 Kadmelia 的 K-Bucket 算法来跟踪更近的节点。我从理论上理解算法是如何工作的
- 当一个新节点
added
- 如果桶大小没有超过 k(桶大小),我们将它添加到当前桶中
- 否则,我们拆分桶并通过循环每个位来划分父桶中的联系人并将它们分成两个桶。
- 这也意味着对于给定的节点,会有
k * 8
桶(或列表)
问题
问题是指本示例中采用的方法http://blog.notdot.net/2009/11/Implementing-a-DHT-in-Go-part-1
假设我们已将 Node 定义为长度为 20 的字节数组
const IdLength = 20
type NodeID [IdLength]byte
我试图了解该PrefixLen
函数实际计算前缀和填充路由表的作用。我了解该方法的每个组件的作用。我的意思是,我了解位移运算符的作用,并AND
用 1 检查该位是否已设置。
我不明白的是返回值以及为什么以这种方式设置它们。
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;
}
返回值如何适合用作路由表的索引?
...
prefix_length := contact.id.Xor(table.node.id).PrefixLen();
bucket := table.buckets[prefix_length];
...
这种方法与循环遍历每一位有何相同之处?作者如何使用 PrefixLen 方法达到相同的结果。
您能否通过示例帮助我理解这一点。提前致谢。