Objective c git-DAG的增量线性化

Objective c git-DAG的增量线性化,objective-c,git,visualization,directed-acyclic-graphs,Objective C,Git,Visualization,Directed Acyclic Graphs,我是这本书的作者。可以看出,GitX的一个特性是分支的可视化 这种可视化目前是通过读取从git以正确顺序发出的提交来完成的。对于每个提交,父级都是已知的,因此以正确的方式建立通道相当容易 我想通过使用我自己的提交池并自己对提交进行线性化来加快这个过程。这允许我重用现有的已加载提交,并允许git更快地发出提交,因为它不必按正确的顺序发出提交 然而,我不确定要用什么算法来实现这一点。建筑是增量的,这一点很重要,因为提交的加载可能需要很长时间(100000次提交大于5秒,应该全部显示) Gitk也走了

我是这本书的作者。可以看出,GitX的一个特性是分支的可视化

这种可视化目前是通过读取从git以正确顺序发出的提交来完成的。对于每个提交,父级都是已知的,因此以正确的方式建立通道相当容易

我想通过使用我自己的提交池并自己对提交进行线性化来加快这个过程。这允许我重用现有的已加载提交,并允许git更快地发出提交,因为它不必按正确的顺序发出提交

然而,我不确定要用什么算法来实现这一点。建筑是增量的,这一点很重要,因为提交的加载可能需要很长时间(100000次提交大于5秒,应该全部显示)

Gitk也走了同样的路,有一个补丁展示了它是如何实现的,但是我的TCL技能很弱,补丁没有得到很彻底的评论,而且有点难以遵循

我还希望这个算法是有效的,因为它必须处理成千上万的提交。它还必须显示在表中,因此快速访问特定行非常重要

我将描述到目前为止我的输入、我想要的输出和一些观察结果

输入:

  • 我有一个哈希表形式的当前提交池,该哈希表将提交ID映射到提交对象。此池不必完整(具有所有必需的提交)
  • 我有一个单独的线程从git加载新提交,每次加载新提交时都可以调用回调。没有保证提交的顺序,但在大多数情况下,下一次提交是上一次提交的父级
  • 提交对象有自己的修订id及其所有父对象的修订id
  • 我有一份应该列入名单的分支机构负责人名单。也就是说,没有一个DAG的“顶部”应该显示。也不必有一个图根
输出:

  • 我需要按拓扑顺序线性化这些提交。也就是说,在父级已列出之后,无法列出提交
  • 我还需要可以在上面的截图中看到的“分支线”。这些可能需要预先计算,因为它们中的大多数依赖于自己的孩子
几句话:

  • 有必要重新定位提交列表。例如,我们可能必须提交不相关的(分支头),直到出现一个提交,使一个头成为另一个头的祖先
  • 必须显示多个分支提示
  • 重要的是,此过程是增量的,以便在数据仍在加载时,至少有部分视图可用。这意味着必须在中途插入新数据,并且必须重新调整分支线

我没有使用GitX,所以可能我遗漏了一些东西,但似乎您可以从每个当前分支的头从子分支走回到父分支,直到您可以绘制一些图形屏幕为止

这可能不会为早期扎根的分支提供最佳的视觉布局。但是,响应性似乎比等待绘制一个交叉次数最少的图表更重要,因为大多数用户可能对最近的活动感兴趣。

标准是O(n)(好,O(V+E)),也就是说,您应该能够在几分之一秒内对内存中的一百万次提交进行排序。不需要像Tcl那样的增量黑客


顺便说一句,我每天都使用GitX(看起来比OS X上的Gitk好得多),而且没有任何问题(可能是因为我的存储库中没有那些疯狂的合并):

好吧,所以我也很难阅读整个补丁,但让我们看看我是否能从我所发现的东西中拼凑出它

首先,gitk通过将一系列提交压缩成一个弧来简化事情,其中包含一系列提交,每个提交只有一个父级和一个子级。除此之外,这样做可以大大减少你必须考虑的节点数量,这将有助于你使用的任何算法。作为奖励,相关的提交最终将分组在一起

在读取新提交时查找弧时,这确实会带来一些复杂性。有几种情况:

  • 新提交只有一个父级,或者没有父级。它延伸了一条(可能是空的)弧。大多数情况下,您只需扩展最近的圆弧。有几个有趣的子类别:
    • 如果现有弧的父弧已经有子弧(即,其父弧原来是一个分支点,我推测您事先不知道该分支点),则可能会导致分割现有弧
    • 它可能是将两个圆弧连接在一起的“缺失链接”
    • 您可能已经知道此提交有多个子项
  • 新提交有多个父级(合并提交)
您可能希望在圆弧中包含多子或多父提交,或者将它们分开可能更有意义。无论哪种方式,以增量方式构建这组圆弧都不会太困难

一旦你有了这些弧,你仍然要尝试线性化它们。在您的例子中,前面提到的第一个算法听起来很有用,因为您有一组已知的分支点用作初始集S

其他说明:

  • 重新定位提交应该是可管理的。首先,您只需注意连接两条弧的时间,无论是通过新的合并提交、新发现的分支点,还是将两条弧合并为一条弧。任何给定的弧都可以很容易地保持其当前的行号范围(假设您可以在连续的行上放置一个弧),因此遍历树检查所有新的祖先是否稍后出现应该是相当快的
  • 关于drawi我知道的还不够多