“哈希表主体只承诺字典语义与负载参数,冲突策略应分层阅读:通用哈希给对固定键集的碰撞期望,Perfect Hashing针对静态集合换最坏常数查询,开放定址把键直接放入数组并依探测链,Cuck…”
形式陈述 ​
Cuckoo Hashing 是哈希表中的开放定址方案:每个键只允许落在少数候选位置,查询因此只检查常数个槽位,插入则通过重定位链恢复这一位置约束。
两位置不变量 ​
两个来自合适通用哈希族的独立函数给键
Cuckoo 图刻画 ​
把两张表的槽作为一个图的二分两侧顶点,每个键作为连接两个候选槽的边。为每条边选择一个端点存放,且每顶点容量一;经典单槽模型可成功放置,当且仅当每个连通分量的边数不超过顶点数,即分量至多含一个环。树分量沿路径定向即可,双环分量必有某槽承担两键。
直觉
每个键像一条连接两个候选槽的边,选择存储位置就是把这条边定向到一个端点。踢出链沿着当前定向寻找可改道的路径;若某个分量的边比槽还多,无论从哪一键开始踢都不可能成功,循环只是容量障碍在执行过程中的表现。
例子与边界
踢出路径例子 ​
新键
概率与装载边界 ​
在低于经典阈值、哈希足够随机时,插入期望摊还常数;接近阈值时复杂分量和长路径概率迅速增加。桶化 cuckoo、更多候选和 stash 改变阈值与查询位置数,须另写模型。查询的常数最坏界不含重建期间的并发语义;Las Vegas 版本通过重试保证结果正确,但运行时间随机。
推论与应用
候选位置由随机哈希函数决定,插入失败概率和重哈希次数因此属于随机化算法分析。查询的常数探测是条件性的:它依赖当前表已经成功构造,并不消除构造阶段的随机失败事件。
Rehash 的摊还语义 ​
检测到环后,给当前全部键重新抽一对哈希函数并从空表构建;若仍失败继续重试。只要装载低于相应随机图阈值,单次全表构建成功概率有常数下界,所以重试次数期望常数,重建总成本可向自上次扩容以来的插入摊还。
这个结论要求失败时更换函数,而不是沿同一环从另一个起点继续踢。扩容也改变图顶点数和阈值。若系统要求每次插入最坏延迟,需要增量 rehash、stash 或 deamortization,并重新说明查询要检查哪些旧/新位置。
失败分量怎样被识别 ​
设候选槽为
实现可按以下顺序处理:
- 限制一次踢出的最大步数,并记录本轮访问状态;
- 超限后把新键和被踢出的键一起保留在临时区,不能丢失;
- 抽取新哈希函数,从空表重插全部键;
- 若仍遇坏分量则重试,达到负载阈值时先扩容。
查找只检查两个槽的最坏
参考资料
- Rasmus Pagh, Flemming Friche Rodler, Cuckoo Hashing, Journal of Algorithms, 2004.
- Michael Mitzenmacher, Some Open Questions Related to Cuckoo Hashing, ESA, 2009.