手写数据库轮子项目 MYDB 之五 | DataManager (DM) 数据之页面索引与向上管理 DataItem

本章介绍一个实现简单的页面索引,并且实现了 DM 层对于上层的抽象:DataItem。

一、页面索引

页面索引,缓存了每一页的空闲空间。用于在上层模块进行插入操作时,能够快速找到一个合适空间的页面,而无需从磁盘或者缓存中检查每一个页面的信息。

1. PageIndex

PageIndex 将一页的空间划分成了 40 个区间。在启动时,就会遍历所有的页面信息,获取页面的空闲空间,安排到这 40 个区间中。insert 在请求一个页时,会首先将所需的空间向上取整,映射到某一个区间,随后取出这个区间的任何一页,都可以满足需求。

    // 将一页划成40个区间
    private static final int INTERVALS_NO = 40;
    private static final int THRESHOLD = PageCache.PAGE_SIZE / INTERVALS_NO; /// 每个区间的大小

    private Lock lock;

    /// lists 是一个数组,数组中的每一个元素是一个 ArrayList 列表, 每个列表中保存了多个 PageInfo
    /// lists 中第 i 个元素表示的是空余容量还剩 i 个区间的页面的集合
    private List<PageInfo>[] lists;

PageInfo 实际保存了某页的页号,和该页空闲的区间大小。

public class PageInfo {
    public int pgno;
    public int freeSpace;

    public PageInfo(int pgno, int freeSpace) {
        this.pgno = pgno;
        this.freeSpace = freeSpace;
    }
}

2. 通过 PageIndex 获取页面

    public PageInfo select(int spaceSize) {
        lock.lock();
        try {
            int number = spaceSize / THRESHOLD;  /// 要存 spaceSize 大小的数据,需要多少个区间
            if(number < INTERVALS_NO) number ++;  /// 向上取整
            while(number <= INTERVALS_NO) {
                if(lists[number].size() == 0) { /// 如果还有 number 个空余区间的页面数量为0
                    number ++; /// 只能换一个更大的区间
                    continue;
                }
                return lists[number].remove(0); /// 随意取出任何一页,注意使用的是remove
            }
            return null;
        } finally {
            lock.unlock();
        }
    }

被选择的页,会直接从 PageIndex 中移除,这意味着,同一个页面是不允许并发写的。在上层模块使用完这个页面后,需要将其重新插入 PageIndex。

    public void add(int pgno, int freeSpace) {
        lock.lock();
        try {
            int number = freeSpace / THRESHOLD;  /// 该页面还有多少个空余空间
            lists[number].add(new PageInfo(pgno, freeSpace));
        } finally {
            lock.unlock();
        }
    }

3. 填充 PageIndex

在 DataManager 被创建时,需要获取所有页面并填充 PageIndex。

    void fillPageIndex() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值