Skip to content

模型Model

Buffer Tree

施工中 · 内容逐步修订

buffer tree · 缓冲树

在高扇出树节点积累操作并批量下推,以排序量级 I/O 支持批量动态操作。

形式陈述 ​

结构 ​

在参数为 (M,B) 的外存模型中,以B-tree式高扇出层级为骨架,假设 M/B 至少为实现所需的固定常数,取扇出 Θ(M/B) 的多路树。每个内部节点除分隔键外还维护可容纳 Θ(M) 条操作的缓冲;新 insert/delete/search 请求先写入根缓冲,不立即沿路径执行。叶保存键或最终操作结果。

Flush 不变量 ​

缓冲满时,把其中 Θ(M) 条操作按目标孩子稳定分组,再顺序写入 Θ(M/B) 个孩子缓冲。读取原缓冲需要 O(M/B) 次 I/O;输出数据占同阶块数,每个孩子至多再付常数个边界块。因此一次 flush 共需 O(M/B) 次 I/O,每条操作每下降一层摊到 O(1/B)。这些常数同时要为操作数组、分隔键和输出块预留内存。

从空结构开始执行总共 N≥M 次更新时,驻留记录数至多为 N;操作通过的树层数因此至多为

O(logM/B⁡(N/B)).

结合平衡维护的摊还收费,从空树开始的 N 次更新共需 O((N/B)logM/B⁡(N/B)) 次 I/O,达到外存排序量级。这里采用摊还分析,将整段操作的成本分配给各次更新;尚在缓冲中的操作也属于逻辑状态。

直觉

外存访问的昂贵单位是一整块,而不是一次比较。Buffer Tree 故意推迟单条操作,让同一路径方向上的请求先凑成能填满许多块的批次,再顺序下推;延迟换来的不是更短的树高,而是让一次 I/O 同时为大量操作服务。

操作分组与批量下刷
例子与边界

批量插入例子 ​

日志索引连续收到数百万条插入。逐条 B-tree 查询会为每条记录访问一条根叶路径;buffer tree 先在根聚合,按键区间成批分给子树,让一次读入的块处理许多记录。同一键的插入与删除用时间戳保留先后顺序,随后按顺序合成为等价操作。

查询与边界 ​

即时点查询要检查根到叶路径上尚未下推的相关缓冲,并按时间合成同键操作;批量 search 则可随更新一起下推,延迟返回结果。批处理减少的是长期平均 I/O,单次查询或触发 flush 的更新仍可能承担较大开销。

操作排序与正确性 ​

同一键的更新可能同时位于祖先和后代缓冲。下推时应按时间戳稳定排序,或先按键分组,在相邻查询之间折叠成等价更新,确保较晚 delete 不被较早 insert 覆盖。批量 search 可作为带时间戳操作一路下推,在叶与此前更新合并后输出;合并更新时必须保留每个查询时刻的答案,不能只保存整段最后的净状态。

I/O 模型不计已经驻留内存的数据之间的比较成本;缓冲容量因而要与可用内存相匹配。若批处理结束时要把待办请求全部落实到叶层,还需执行最终清空,并计入未满缓冲的读写成本。

推论与应用

Buffer Tree 适合大量更新和可延迟查询的外存任务。它把逐条根叶访问改成按键区间分发操作批次;树的平衡负责控制层数,缓冲负责让每层的块传输被多条操作分担。

同一缓冲思想还可用于外存优先队列:沿最左路径下推相关操作后,把一批最小元素集中到内存中,再连续回答删除最小值请求。不同接口的关键区别在于何时必须返回答案,这决定了哪些请求可以继续积累、哪些缓冲需要立即处理。

参考资料
  • Lars Arge, The Buffer Tree: A New Technique for Optimal I/O Algorithms, WADS, 1995;另见 External Memory Data Structures,§5、Theorem 7,缓冲树的批量操作与优先队列界。
  • Jeffrey Vitter, External Memory Algorithms and Data Structures, ACM Computing Surveys, 2001.
关系图谱12 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系

使用的工具

被这些条目使用