.net 如何存储多个数据块的哈希,并通过哈希检索列表?

.net 如何存储多个数据块的哈希,并通过哈希检索列表?,.net,performance,algorithm,low-level,.net,Performance,Algorithm,Low Level,我正在从事一个实现重复数据消除的开源项目。(有关项目的链接,请参见下面的两个超链接) 该项目的性能目前还不错,但随着更多的块写入磁盘,性能会下降。 这是由于HashManager。对于写入的每个块,hashmanager存储一个哈希块ID对。对于重复数据消除过程,需要具有给定哈希的块标识符列表。(使用的哈希为Crc32) 有关HashManager的接口,请参阅 当前接口将列表存储在256个文件(crc&0xFF)中,并将完整列表加载到内存中。当需要另一个列表时,将保存上一个列表并加载下一个列表

我正在从事一个实现重复数据消除的开源项目。(有关项目的链接,请参见下面的两个超链接) 该项目的性能目前还不错,但随着更多的块写入磁盘,性能会下降。 这是由于HashManager。对于写入的每个块,hashmanager存储一个哈希块ID对。对于重复数据消除过程,需要具有给定哈希的块标识符列表。(使用的哈希为Crc32) 有关HashManager的接口,请参阅

当前接口将列表存储在256个文件(crc&0xFF)中,并将完整列表加载到内存中。当需要另一个列表时,将保存上一个列表并加载下一个列表。除此之外,这可能会导致内存耗尽,这意味着性能下降

有什么好的选择可以克服这个问题


(只是为了澄清:在重复数据消除之前,会完全检查块以查看它们是否匹配)

我不是磁盘结构方面的专家,但我听说B-树通常用于实现存储在磁盘上的键值映射。所以我想你可以有一个CRC的B树索引,然后有一些链接存储到块ID列表中。您还可以将列表合并到B树结构中,方法是有效地拥有一个键,该键是CRC和块ID的串联,然后在B树上执行有效的前缀/范围查询


:“在计算机科学中,B-树是一种树数据结构,它保持数据排序,并允许在对数时间内进行搜索、顺序访问、插入和删除。B-树是二元搜索树的一种推广,因为一个节点可以有两个以上的子节点。(Comer 1979,第123页)与自平衡二进制搜索树不同,B-树针对读写大数据块的系统进行了优化。它通常用于数据库和文件系统。”

如果您使用256个列表文件来存储CRC,第一个明显的步骤是将所有以零字节开头的CRC放在列表0中,在列表文件1等中,所有字节为1的文件只在每个文件中存储crc的最后三个字节。这将节省25%的密钥存储,并可能加快处理速度

第二件事是制作一个4GB内存标志数组,以显示是否在列表中注册了一个4字节的crc。这将大大加快向数组中添加新项的速度,因为您将知道是否需要首先查找现有条目-如果位为零,则表示尚未使用crc

根据data domain开发人员的一篇论文,这种不必要的查找是最慢摄取过程的原因(他们有不同的方法来避免它)

我假设您正在保存列表,因为您正在修改它们。我建议您不要重写整个列表,而是将所有更改放在文件末尾,这样您就可以附加到文件末尾,而不是重写整个列表。使用了一种链表结构,该结构以文件末尾的指针开始,每次追加都会在文件末尾的列表中写入一个新的头。您可以通过在列表的更高位置写入一个新条目并启用删除标志来标记要删除的条目。然后可以定期对每个列表进行垃圾收集,以减少列表大小(例如,每周或每月进行一次批处理)。您可以对列表进行同样的修改。只需编写一个新条目来替换旧条目,可能还需要一个标志。然后定期进行垃圾收集以删除旧条目

你可以做任何事情来构建列表,这样你就不需要每次都在内存中加载整个内容,这会加快速度。尽可能少地移动数据,尽可能少地移动

这是我写的第一篇关于堆栈溢出的文章,如果我的文章没有遵循首选规范,请原谅


我注意到我的回复编辑区上面的说明,我不应该要求澄清,我想这是为了让我可以有更多的乐趣,只是猜测确切的问题是什么。我希望我的猜测是接近的,我的答案包含有用的元素

我在搜索中遇到了B-树,但在我看来,这似乎是一个复杂的算法。您熟悉任何好的实现吗?