【问题标题】:Easiest way to find the correct kademlia bucket找到正确 kademlia 存储桶的最简单方法
【发布时间】:2011-02-09 01:01:22
【问题描述】:

Kademlia protocol 中,节点 ID 是 160 位数字。节点存储在桶中,桶 0 存储除最后一位之外与该节点具有相同 ID 的所有节点,桶 1 存储除最后 2 位之外与该节点具有相同 ID 的所有节点,以此类推为所有 160 个存储桶打开。

找到我应该将新节点放入哪个存储桶的最快方法是什么?

我的存储桶只是存储在一个数组中,需要这样的方法:

Bucket[] buckets; //array with 160 items

public Bucket GetBucket(Int160 myId, Int160 otherId)
{
    //some stuff goes here
}

显而易见的方法是从最重要的位开始,逐位比较,直到找到差异,我希望有一个更好的方法,基于聪明的位旋转。

实用说明: 我的 Int160 存储在一个包含 20 项的字节数组中,适合这种结构的解决方案将是首选。

【问题讨论】:

    标签: language-agnostic bit-manipulation dht bitfoo


    【解决方案1】:

    您愿意考虑一个由 5 个 32 位整数组成的数组吗? (或 3 个 64 位整数)?使用整个单词可能比使用字节提供更好的性能,但该方法在任何情况下都应该有效。

    XOR 两个节点 ID 的对应词,从最重要的开始。如果 XOR 结果为零,则转到下一个最重要的字。

    否则,使用constant time method from Hacker's Delight. 查找此 XOR 结果中设置的最高有效位。如果设置了最高有效位,则该算法产生 32 (64),如果设置了最低有效位,则结果为 1,依此类推。这个索引,结合当前单词的索引,会告诉你哪位不同。

    【讨论】:

    • 字节似乎是最自然的做事方式,正如你所说的整数可能会更快
    【解决方案2】:

    对于初学者,您可以逐字节(或逐字)比较,当您发现差异时,在该字节(或单词)内搜索差异的第一位。

    在我看来,将节点添加到存储桶数组的速度如此之快,以至于您是否巧妙地进行位旋转以找到字节(或单词)中的第一个差异,或者只是搅动,这对我来说似乎有点难以置信在一个循环到 CHAR_BIT (或其他东西)。不过有可能。

    此外,如果 ID 本质上是随机且均匀分布的,那么您将在大约 255/256 的时间发现前 8 位存在差异。如果你关心的只是一般情况下的行为,而不是最坏情况下的行为,那么就做一件愚蠢的事情:你的循环不太可能运行很长时间。

    不过,作为参考,数字 xy 之间的第一位差异是在 x ^ y 中设置的第一位。如果您使用 GNU C 编程,__builtin_clz 可能是您的朋友。或者可能是__builtin_ctz,我有点困……

    不过,您的代码看起来像 Java,所以我猜您要查找的 bitfoo 是 integer log

    【讨论】:

    • C#,接近java。正如你所说,这个算法的速度可能并不重要,我主要是出于兴趣问这个问题。之前关于比特旋转的问题已经出现了一些巧妙的技巧,这些技巧很有趣,可以解开它们的工作原理
    猜你喜欢
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2016-08-27
    • 1970-01-01
    • 2021-03-28
    • 2018-08-14
    • 1970-01-01
    相关资源
    最近更新 更多