什么是合理的数据结构,允许两个根路径之间的有效同步?

时间:2011-06-30 21:20:55

标签: data-structures synchronization filesystems fingerprint red-black-tree

我正在开发一个涉及维护两个本地目录之间一致性的应用程序。具体来说,目录应该是相同的,但其中一个目录中的所有文件都以某种特定的方式被修改(这部分对我的问题并不重要)。

在运行时,我的应用程序运行两个进程来监听每个路径下发生的更改,并执行相关操作以在必要时使它们恢复同步。

就我的具体问题而言:我正在寻找有关何时启动申请的琐事情况的建议。此时,每个进程都需要检查它正在查看的路径下的所有文件/文件夹,以查看在应用程序未运行时是否有任何更改。 (我们假设操作系统无法通知应用程序关闭时发生的任何事情,因此需要直接检查每个文件/文件夹。)

每个进程都可以访问(并维护)其指定路径下所有文件/文件夹的持久数据结构。我认为应该在每个文件和文件夹的数据结构中保存以下内容:

  • 文件/文件夹名称;
  • 文件哈希(CRC32);
  • 文件/文件夹最后的mod数据;和
  • 文件/文件夹大小。

这些信息显然有助于检查文件/文件夹的任何更改,但存储它们的最佳方法是什么?

在我看来,一种明智的方法来处理应用程序启动的情况是每个进程递归扫描其指定路径下的所有文件/文件夹,并将扫描的每个文件的元数据与存储在其中的元数据进行比较数据结构。然后,进程还应遍历数据结构,以查找已从路径中删除的内容。在此过程中可能遇到的一些情况是:

  • 文件已修改(在数据结构中找到文件名,但散列不同);
  • 添加了
  • 文件(在数据结构中找不到相同的文件名或哈希值);
  • 文件已重命名(数据结构中存在具有相同哈希的文件,但文件名不相同);
  • 添加了
  • 文件夹(数据结构中没有文件夹名称);
  • 文件夹已删除(数据结构中的文件夹名称,但不在路径下);
  • 文件夹已重命名(棘手的)。

那么,用于此任务的最佳数据结构是什么?在我的脑海中,我正在考虑某种形式的排序关联数组,例如红黑树,它存储filefolder个对象。每个file对象包含namehashmod-date个属性,而每个folder对象包含namechildren个属性,其中children存储另一个关联数组,其中包含所有内容。给定任意文件的路径,例如/foo/bar/file.txt,从根(foo)开始,检查bar,依此类推,直到到达file.txt为止父对象。

我能想到的另一种选择是仅仅存储平面的所有内容,这样就会有一个红黑树,其中每个键是每个文件/文件夹的完整路径,值是file / folder对象。这可能会更快地进行检索,但是无论如何都不可能检测重命名的文件/文件夹而不会遍历所有值,这听起来很昂贵。在第一种方法中,识别重命名可能只涉及检查数据结构的一部分而不是全部。

对不起,上述想法并没有经过深思熟虑。这个领域的最新技术水平是什么,对这些类型的问题有什么好的方法吗?

1 个答案:

答案 0 :(得分:0)

您正在为文件系统建模,因此使用分层数据结构非常自然。毕竟,您不需要将dir1 \ dir2 \ foo.txt中的文件与dir3 \ bar.txt进行比较,对吧?您没有提到目录之间的文件移动是您正在跟踪的内容。

因此,数据结构可能是:

interface IFSEntry {
  string name
  datetime creationDate
  pure virtual bool Compare(IFSEntry other)
  pure virtual void UpdateFrom(IFSEntry other)
  pure virtual bool WasRenamed(Dictionary<string,IFSEntry> possibleOriginals, out string oldName)
  ...
} 

class File : IFSEntry {
  ...
} 

class Directory : IFSEntry {
  private Dictionary<string,IFSEntry> children;
  ...
}

UpdateFrom和Compare的Directory实现会逐步减少他们的孩子。

通过比较CRC,文件重命名会相对简单。你会错过两个地方都有变化并重命名的文件。如果运行比较的时间证明存在性能问题,则可以将CRC字典添加到Directory类。

对于目录移动,如果子文件也发生了变化,那么你就会遇到模糊逻辑情况。最好有一个合并工具,用户可以针对这种情况进行操作。

如果文件在两个位置都发生了变化,那么如果发生冲突的更改,您还需要面向用户的合并策略。我认为这总是一个好主意,只是为了让用户注意文档没有失去连贯性。