我一直在服用一看就罗斯林CTP和,虽然它解决了类似的问题的表达式树API ,无论是不可改变的,但罗斯林在一个完全不同的方式这样做:
哪里结束? Document
? Project
? ISolution
? 该API促进树(而不是扣)的一步一步的变化,但不会每一步,使完整副本?
他们为什么他们做出这样的选择? 有一些有趣的把戏我失踪?
更新:这个问题是我在2012年6月8日博客的主题 。 感谢伟大的问题!
大的问题。 我们讨论你提出了很长,很长一段时间的问题。
我们希望有一个具有以下特征的数据结构:
- 不可改变的。
- 一棵树的形式。
- 便宜访问父节点的子节点。
- 可以从一个节点树映射到一个字符在文本中的偏移。
- 持久性 。
余辉我的意思是,当一个编辑就是文本的缓冲区的重用大部分在树中的现有节点的能力。 因为节点是不可改变的,没有障碍重用他们。 我们需要这种性能; 我们不能再解析每次投中关键时刻的文件的巨大wodges。 我们需要重新lex和重新分析所影响的编辑树的唯一部分。
现在,当你试图把这些东西全部五成一个数据结构,你马上碰到的问题:
- 你如何建立在首位的节点? 家长和孩子都指向对方,是不可改变的,所以哪一个被先建?
- 假设您管理来解决这个问题:你如何让它持续? 在不同的父母,你不能再使用一个子节点,因为这将涉及告诉它有一个新的父的孩子。 但孩子是不可改变的。
- 假如你设法解决这一问题:当你插入一个新的字符到编辑缓冲区, 映射到该点更改后的位置每个节点的绝对位置。 这使得它很难做出一个持久数据结构,因为任何编辑可以改变的大部分节点的跨越!
但在罗斯林的团队,我们经常做不可能的事情。 实际上,我们藉由保持两份分析树做不可能的事。 “绿色”树是不可变的,持久的,没有父的引用,是建立“自下而上”,每一个节点跟踪它的宽度而不是它的绝对位置 。 当编辑情况下,我们重建所影响的编辑,这是典型的有关树的总解析节点的O(log n)的绿色树的仅部分。
“红”树是周围绿树建立了一个不可改变的外观 ; 它是建立在需求的 “自上而下”和扔掉的每一个编辑。 它通过制造它们的需求为您从顶部树下降计算父引用。 它通过从宽度计算它们,再次,当你潜制造商的绝对位置。
你的用户,永远只能看到红色的树; 绿色的树是一个实现细节。 如果你窥视解析节点的内部状态,你会在实际上看到,在有不同类型的另一种解析节点的引用; 这是绿色的树节点。
顺便说一句,因为这些是我们用来绘制数据结构在设计会议上,白板笔的颜色,这些被称为“红/绿的树”。 有没有其他意义的颜色。
这种策略的好处是,我们得到了所有这些伟大的事情:永恒,持久性,父母的引用,等等。 成本是这个系统很复杂,会消耗大量的内存,如果“红”外立面得到大。 我们目前做实验,看看我们是否可以降低一些费用,而不会丢失的好处。