hashtable - 基于磁盘的快速哈希表?

标签 hashtable

我有一组哈希值(MD5 的前 64 位,因此它们分布非常随机),我希望能够查看新哈希值是否在一组中,并将其添加到一组中。

集合不太大,最大的元素有数百万个,但是集合有数百个,所以我无法将它们全部保存在内存中。

到目前为止我的一些想法:

  • 我尝试将所有内容都保存在 sqlite 表中,但是一旦它无法容纳内存中的所有内容,它就会变得非常非常慢。
  • 布隆过滤器听起来错误率非常高。我不介意微小的错误率(64 位哈希已经在 4G 元素集上产生了 1 次冲突),但像 1% 这样的错误率太高了。
  • 在文件中保留带有间隙的哈希值的排序列表,并在间隙不足时调整大小。哈希值是均匀分布的,因此即使是非常简单的方案也应该有效。

我是否遗漏了一些非常明显的东西?关于如何实现良好的基于​​磁盘的哈希表有任何提示吗?

最佳答案

这是我最终使用的解决方案:

  • 每组一个文件
  • 文件包含 2^k 个桶,每个桶 256 字节或 32 个 8 字节条目
  • 空条目只是被清零(000...是一个有效的散列,但我不关心 2^-64 的碰撞机会,如果一切都可以与其他一切发生冲突,根据散列的本质)。
  • 每个哈希都驻留在通过其前 k 位猜测的存储桶中
  • 如果任何存储桶溢出,则将文件大小加倍并拆分每个存储桶
  • 所有内容都是通过 mmap() 访问的,而不是 read()/write()

它比 sqlite 快得令人难以置信,尽管它是低级 Perl 代码,而且 Perl 确实不适合高性能数据库。它不适用于任何比 MD5 分布更不均匀的东西,它假设一切都非常均匀以保持实现简单。

一开始我用seek()/sysread()/syswrite()尝试过,速度很慢,mmap()版本确实快很多。

关于hashtable - 基于磁盘的快速哈希表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/495161/

相关文章:

Swift Dictionary 在扩展中使用键访问值

c# - 使用键的克隆从哈希表中检索值; C#

java - 破解面试19.8-创建哈希表时,当我在 if-else 语句中添加 else 时,为什么会得到错误的输出

python - 如果使用很长的字符串作为键,在 Dict 中搜索的时间复杂度是多少?

C++ 哈希链接函数

java - 按位与在 Java 哈希表哈希查找中?

c++ - unordered_map 索引错误

powershell foreach-object 与 if 语句

为 hashmap 创建可变数量的链表

c - 从不兼容的指针类型 C 返回