良好的测试覆盖率和基准测试。 尚未编写文档或进行实际应用。 计划用于我自己的项目。 API 可能会有重大更改。
除非你对 B+ 树已经感兴趣,否则你可能不想使用这个项目。 同时,我认为其基础很好,并且可以完成在 Swift 中无法完成的事情,而无需重复大部分工作。
欢迎任何想法或反馈。
该项目提供了一个用 Swift 编写的内存位置(无键)B+ 树实现。 该项目还包括两种有用的集合类型,它们使用 B+ 树作为其底层存储。
List<Element>
实现任意元素的随机访问集合。 它类似于标准库中的 Array,但查找、插入和删除以及写入时复制都具有对数复杂度。
IdentifiedList<Element: Identifiable>
实现与 List 相同的随机访问集合,但使用 Identifiable 元素。 除了维护列表之外,它还在字典中跟踪这些元素 ID。 它能够在常数时间内实现 contains(id: Element.ID),并在对数时间内实现 offset(id: Element.ID)。
SummarizedTree<Context>
是作为上述集合基本存储的底层原始集合。 它是一个通用的 B+ 树,可以通过提供的上下文类型进行自定义。
上下文允许你定义自己的 CollectionSummary 类型。 List 和 IdentifiedList 集合仅汇总元素计数。
使用自定义摘要类型,你可以索引并在你选择的属性上提供对数搜索。 例如,你可以构建一个 Rope,而摘要类型可能包括 byteCount、charCount 和 lineCount。 这将允许你以对数时间在所有这些值之间进行转换。
上下文还允许你在树的根中存储附加状态,并在元素和树节点添加到树中或从树中删除时接收回调。 这就是 IdentifiedList 如何通过在上下文中跟踪附加信息来实现高效的 contains 和 offset 实现的原因。
内存 B+ 树是 Array 的快速连续内存和树的对数属性之间的折衷方案。 在 B+ 树中,所有元素都存储在树的叶子中连续内存缓冲区中。 一个小的 B+ 树将只有一个叶子并将所有元素存储在一个缓冲区中。
随着插入更多元素,叶子最终将溢出到多个叶子中。 添加内部节点以创建平衡树。 这种拆分和树管理会增加开销,但也允许以下属性:
对于少量元素,Array 总是更快,“少量”可能在 1000 左右。 对于大多数变异操作(和搜索),最终会出现一个交叉点,在该交叉点 B+ 树会变得更快。 这些基准测试可以让你了解这些交叉点何时发生。
我希望 Swift Collections(这是一个开始!)项目将发布类似的数据结构。 它可能会得到更好的实施、记录和支持。
也可能它不会像这个项目那样适合我自己的需求。 我期望我将继续使用这个项目,并尝试从 Swift Collections 代码中复制任何改进。