Abstracting Node Updates
为了更新磁盘中的页,我们首先要更新他在内存中的形式,这其中有几种在内存中表示节点的方式:我们可以直接访问节点在内存中的缓存,或是通过一个包装过的对象来访问,或是基于具体的语言来创建一个内存中的表现形式。
在没有使用托管内存的语言中,在 B-Tree 的节点中会存储原始的二进制数据,在需要的时候我们能够对对其中的内容进行解释,以及会通过指针来对他进行操作。在这种场景中,节点使用称为结构体的数据来定义,他将原始的二进制数据存储到了指针对应的地址中,并在运行时进行对应的转换。大部分情况下,由页缓存所管理的指针指向的内存区域会使用内存映射的方式来实现。
另一种方式是,B-Tree 节点通过对应编程语言的对象或结构体来组成,这些结构体可以用来进行插入、更新跟删除。在刷新时,对应页的变更首先会应用到内存,然后接着是磁盘。这种方式的优点是简化了并发的访问,因为对原始页数据的变更都通过了中间层的对象进行了分离,只是同时也会带来了更高的内存开销,因为我们需要保存同一个页的两个版本 (原始的二进制数据跟语言相关的结构)。
第三种方式是提供一个包装的对象来提供对缓存节点的访问,并在发生变更时同步应用到 B-Tree 中,这种方式通常会在使用了内存托管模型的语言中使用,包装的对象负责将变化应用到他后面对应的缓存中。
独立的管理基于磁盘的页,及他们缓存的版本,以及他们在内存中的表现,能够让这几种不同的形式有不同的生命周期。比如,我们可以缓冲插入、更新跟删除操作,并在读取时,对内存中的变更与磁盘中的版本进行协调。