【问题标题】:find unique values from a large file从大文件中查找唯一值
【发布时间】:2013-05-16 21:49:17
【问题描述】:

我有一个带有 MD5 哈希流(包含重复项)的大文件(比如 10 TB),我获得了 10MB 的内存(非常有限)和无限的硬盘空间。使用给定条件查找所有唯一哈希(消除重复)。请帮忙,这显然不是作业题

【问题讨论】:

  • "这显然不是作业题"
  • 性能重要吗?我的意思是可以使用一些 O(n^2) 解决方案吗?
  • @AdelQodmani 对于 10 *terabytes 的 16 字节哈希,O(n^2) 和 O(nlogn) 之间的性能差异是天文数字。

标签: c algorithm memory-management hash bigdata


【解决方案1】:

您可以使用外部排序算法(例如使用polyphase merge sort)对哈希进行排序,之后您只需遍历文件并跳过任何等于最新哈希的哈希

hash mostRecentHash;
while(fileHasHashes) {
    temp = fileWithDuplicates.readHash();
    if(!hashesAreEqual(mostRecentHash, temp)) {
        mostRecentHash = temp;
        fileWithoutDuplicates.writeHash(mostRecentHash);
    }
}

【讨论】:

  • 外部多相归并排序是对此的完美算法。 +1
  • +1 删除了我的答案,因为这是一个更好的解决方案。
  • 那他为什么要我使用无限数据库??
  • 如果您应该使用数据库,那么只需在添加之前检查数据库中是否已经存在哈希值。 Select hash From hashes_table Where hash = currentHash,如果返回 null/false,则 Insert Into hashes_table (hash) Values (currentHash)
【解决方案2】:

如果性能无关紧要,并且您的文件系统没有限制,那么您可以简单地为每个哈希创建一个文件。如果在创建过程中遇到EEXIST,那么有重复,可以跳过。

for (each hash) {
    r = open(hash_to_filename(hash), O_CREAT|O_EXCL);
    if (r < 0) {
        if (errno == EEXIST) continue;
        perror(hash);
        exit(EXIT_FAILURE);
    }
    close(r);
    output(hash);
}

这样做的好处是它保留了哈希值在流中首次出现的顺序。

此方案的实际性能取决于文件系统的性能。如果将文件组织在 B-Tree 中,那么性能将大致为 O(N log(N))。如果文件系统使用哈希表来组织文件,那么性能预计为 O(N),但这取决于冲突发生的频率(并且常数因子很高,因为磁盘访问)。

【讨论】:

  • 这显然不是一个糟糕的解决方案。
【解决方案3】:

我喜欢 Zim-Zam 的解决方案...提出一个小的变化。

如果我们可以假设指纹在 128 位空间上均匀分布,那么 我们可以使用像桶排序这样的东西将指纹分桶成(较小的)桶文件,单独对桶文件进行排序,然后使用堆将桶文件合并到一个排序文件中吗?这可能会降低 nlogn 成本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多