比特币原理分析之布谷鸟散列浅析

场景描述

  当比特币节点收到新区块或者新交易时, 会对交易进行签名验证(ECDSA) 存在问题: 1、昂贵的ECDSA签名校验; 2、重复验证的可能(如果交易已经被接受,保存在内存池中,区块过来再进行校验)。

思考:缓存?开放寻址法散列、 链式散列、 布谷鸟散列。。

原理

 Cuckoo hashing 是计算机编程中的一种方案,用于解决表中散列函数值的散列冲突,具有最坏情况的常量查找时间。 这个名字来源于一些杜鹃的行为,杜鹃小鸡在孵化时将其他卵或幼鸟从巢中推出; 类似地,将新key插入到布谷鸟散列表中可以将旧key推送到表中的不同位置。

算法描述

假定使用两个散列函数 使用hashA、hashB计算对应的key位置:

1、两个位置均为空,则任选一个插入;

2、两个位置中一个为空,则插入到空的那个位置 ;

3、两个位置均不为空,则踢出一个位置后插入,被踢出的对调用该算法,再执行该算法找其另一个位置,循环直到插入成功;

 4、如果被踢出的次数达到一定的阈值,则认为hash表已满,并进行重新哈希rehash。

开放寻址法散列

如图所示。当插入F时,通过哈希函数将F映射到表中所指位置,发现该位置已存有D了,向后扫描探查,直到碰到一个空位,再将F插入。而查询一个G时,则需要从对应的位置开始向后找,直到找到G(命中),或找到空位(G不在表中)。这种结构对内存的利用不佳,如果想让哈希表尽量存满(k, v)对,那么插入/查询的性能将会严重下降。

链式散列

利用拉链法解决冲突的哈希表,它的特点是空间利用率比较高,除了顺序存下所有(k, v)对之外仅需要一个索引来记录链表头,但由于链表的空间不连续,导致查询性能一般。

 

布谷鸟散列

查询操作的理论复杂度为最差O(1),优于Dense的期望查询复杂度O(1)和Chain的O(1+α),而Cuckoo的插入复杂度为均摊O(1)。我们引入Cuckoo是希望它在实际应用中,能够在较高的空间利用率下,仍然维持不错的查询性

Cuckoo利用两个哈希函数来实现最差O(1)的查询复杂度: 对任意一个Key可求出两个哈希值,相当于映射到两个桶,如A被映射到1,4,说明它可以被存到1号或4号桶,而实际在1号桶。本图中,用箭头连接某个Key实际存入的桶和另一个对应的桶,如1--->4。 当插入一个F时,如果对应的两个桶至少有一个为空,则将其插入到这个位置,否则任选一个桶,不妨设为A所在的1号桶。我们将其中原有的A = Key’/Value’踢出,将新的F存入。对于刚取出的A,它之所以存储在1号桶是因为用了两个哈希函数之一,那么我们用另外一个哈希函数,知道A对应的位置还有4号桶。若4号桶为空,则将A放入,整个过程就结束了。而事实上,4号桶中还存有B = Key’’/Value’’,那么把它们踢出并重复上面的操作。整个过程中进行踢出、填入操作的,形如“1->4-> … ->空位”这样的序列我们将其称为Cuckoo Kick路径。 当查询一个F时,分别检查它的的哈希值对应的两个位置即可。

讨论交流

空间、查询速度。。。 bitcoin  Cuckoo Hash ?

猜你喜欢

转载自blog.csdn.net/guoguangwu/article/details/88863561