目录树的递归N路合并/差异算法?

时间:2010-02-02 16:33:07

标签: java algorithm merge tree diff

哪些算法或Java库可用于N路,目录的递归差异/合并?

我需要能够生成具有许多相同文件的文件夹树列表,并且具有包含许多类似文件的子目录。我希望能够使用双向合并操作来快速删除尽可能多的冗余。

目标:

  • 查找在它们之间有许多类似文件的目录对。
  • 生成可与双向合并同步以消除重复的目录对的简短列表
  • 应该递归操作(可能有更高级目录的嵌套重复)
  • 运行时间和存储空间应为O(n log n)目录和文件数
  • 应该能够使用嵌入式数据库或页面到磁盘来处理比内存中更多的文件(100,000 +)。
  • 可选:在文件夹
  • 之间生成祖先和更改集
  • 可选:根据可以消除的重复次数对合并操作进行排序

我知道如何使用哈希在大致O(n)空间中查找重复文件,但是我不知道如何从这里找到文件夹和子项之间的部分重叠集。

编辑:一些澄清 棘手的部分是“完全相同”内容(否则哈希文件哈希将起作用)和“相似”(不会)之间的区别。基本上,我想在一组目录中提供这个算法,并让它返回一组我可以执行的双向合并操作,以尽可能减少重复,尽可能少的冲突。它正在有效地构建一个祖先树,显示哪些文件夹是相互派生的。

最终目标是让我将一堆不同的文件夹合并到一个公共树中。例如,我可能有一个包含编程项目的文件夹,然后将其一些内容复制到另一台计算机上进行处理。然后我可能备份和中间版本到闪存驱动器。除了我可能有8或10个不同版本,组织结构或文件夹名称略有不同。我需要能够一步一步地合并它们,所以我可以选择如何在每一步中合并更改。

这实际上或多或少是我打算用我的实用程序(从不同的时间点汇集一堆分散的备份)。我想如果我能做得对,我可以将其作为一个小型开源工具发布。我认为相同的技巧可能对比较XML树有用。

1 个答案:

答案 0 :(得分:2)

似乎只需要处理文件名和大小(以及时间戳,如果你发现它们是可靠的),以避免读取所有这些文件并散列或区分它们。

这就是我想到的。

  • 从文件系统加载所有数据。它会很大,但它会适合记忆。

  • 列出具有相似性得分的候选目录对。对于两个树中显示的每个目录名,对于共享该名称的所有目录对,得1分。对于出现在两个树中的每个文件名(但不常见,它没有意义),对包含具有该名称的文件的所有目录对得1分。如果两个文件相同,则获得奖励积分。如果文件名没有出现在其他任何地方,则得分奖励积分每次给出分数时,也要给所有祖先对赋予一些分数,这样如果/ x / y / foo.txt类似于b / z / y / foo.txt,那么对(a/x/y, b/z/y)(a/x, b/z)(a, b)都获得积分。

  • 可选地,丢弃所有分数太低而无法理解的对,并严格检查其他对。到目前为止,我们只考虑了目录相似的方式。再看,并惩罚显示具有共同祖先迹象的目录对。 (这样做的一般方法是计算两个目录可能具有的最大分数,如果它们都具有所有文件并且它们都是相同的;并且如果实际上只实现了该分数的一小部分,则拒绝该对但是做一些廉价和启发式的东西或完全跳过这一步可能会更好。)

  • 选择得分最佳的候选目录对。输出它。从争用中消除这些目录及其所有子目录。重复。

选择正确的数据结构作为练习。

此算法不会尝试查找具有不同文件名的类似文件。你可以使用像rsync算法这样的大型文件集来做到这一点,但我不确定你是否需要它。

该算法没有认真尝试确定两个文件是否实际相似。对于相同的文件名和奖励积分,相同的大小和时间戳只得1分。你当然可以分散它们来分配更精确的分数。我怀疑这是值得的。