go - Kadmelia K-Bucket 算法中的路由表,无需遍历节点 ID 中的每一位
问题描述
语境
我正在尝试实现 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 方法达到相同的结果。
您能否通过示例帮助我理解这一点。提前致谢。
解决方案
这种方法与循环遍历每一位有何相同之处?
循环简单地迭代字节,然后对每个字节进行移位和掩码。所以实际上它确实迭代了所有位,这些位恰好被打包成字节,因为最小的可寻址内存单元通常是一个字节。
我不明白的是返回值以及为什么以这种方式设置它们。
i
它只是根据完整字节和j
最后部分字节中的位来计算位位置。
语境
这里的上下文实际上是被误导的,因为您在查看具有固定阵列布局的代码示例时试图解释可拆分路由表设计。这是一个常见的混淆来源。
推荐阅读
- c++ - 避免运算符第一个参数上的浮点数和非浮点数的模板运算符重载冲突
- hadoop - 什么是 apache hbase rest api ip 和端口?
- c# - 如何从另一个页面传递数据?
- javascript - 在道具中遇到问题“无法读取未定义的属性‘地图’”
- vba - 单元格值取决于活动单元格
- sql-server - 如何使用位列进行分组?
- linux - chown: 无效用户: '+x'
- c# - 如何获取更新的 C# 的 2 个文本框中的值的总和
- json - 如何在 kentico kontent 中重新导入 DeliveryAPI 结果
- javascript - 如何使用 Wavesurfer JS 检测波形何时加载到画布中