Bustub架构简单分析
写在前面 在这篇文章中我们先抛开SQL在bustub的中的历程,直接快进到最后开始执行的阶段,这篇文章只关注设计上的细节。 至于如何理顺这些细节在[[CMU15-445 Project3 - Query Execution]]文章中会有详细的介绍,这里就不再赘述。😃 架构总览 上图中catalog其实不是特别准确,按照我的理解应该是下面这种情况👇。通过一个table_id双向映射表的名字和实体table。 接下来就按照从上到下的顺序依次介绍各个部分的结构。 Catalog 下面这个图是是整个catalog关于table的。👇这里引出了TableInfo. Catalog中不仅仅包含table的信息还储存了index的信息。这里引出了IndexInfo,但是后边用的不是很多。 接下来看TableInfo的组成。(TableInfo的定义就在Catalog.h文件中) TableInfo name_:就是表的名字 table_: 是一个每个节点都是tablepage的双向链表 oid_: 顾名思义就是表的id Schema_:其实到现在我都没有很弄懂这个是干什么的东西,但是chat给出了答案。 什么是Schema 按照我的理解应该是一个类似于表头的包含各种配置信息的一个抽象集合。现在就看看源码。👇 在bustub中schema的信息似乎没有包含很多,就是对每一个列的数据类型约束进行了记录。以及对所有的列进行一个汇总,方便获取到每一个列。 ==Column== 实际上每个列的实现实体是Column,在这个实体中包含列名,数据类型,长度等基本信息。 ⚠️值得注意的是column对于varchar单独做了处理🙂,变长数组终究还是不一样啊。 TableHeap 实质上就是配合TablePage里面的信息构成的双向链表,我觉得这个设计真的非常的巧妙。只用了基本的pre_page_id 和next_page_id这两个变量就把双向链表给建立起来而且耦合度非常的低。 first_page_id_: 就是第一个pageid bufferpool:所有的page都需要从bufferpool中去取。 TablePage的结构 ok看到这里有疑问了? 那么多的信息都存在那里, 这继承的加上初始化的也不够啊。 答案在这里👇 通过偏移量直接在page的剩余空间里去定义各种变量。 ==通过InsertTuple()函数了解详细结构== 直接看源代码: if (tuple.size_ + 32 > BUSTUB_PAGE_SIZE) { // larger than one page size txn->SetState(TransactionState::ABORTED); return false; } auto cur_page = static_cast<TablePage *>(buffer_pool_manager_->FetchPage(first_page_id_)); if (cur_page == nullptr) { txn->SetState(TransactionState::ABORTED); return false; } 这主要是判断一些前置条件的合法性 为什么要用tuple的大小+32进行比较呢? 文末给出答案 在第一页中进行插入,如果没有足够的空间就开一个新页然后插进去 ⚠️需要注意的是,在离开第一页的时候仍然要持有写锁,因为还要写next_page_id变量. 💡跟随代码跳转到TablePage::InserTuple(). ...