MINIBASE源代码阅读笔记之heapfile
Heapfile
用来管理heap file里的dir page们
成员
- _firstDirPageId:这个文件的第一个dir page
- _ftype:文件类型
- _file_deleted:删除的时候用的falg
- _fileName:文件名
方法
HeapFile:接收名字,如果是null就开个临时的heapfile(离开的时候会被destructor干掉),否则打开已有文件or创建新文件
- 先假设文件已经被干掉,设置filedeleted与_fileName
- 如果name是null,起一个临时文件名,否则用给的名字。(这里看到了古老的strdup……)
- 试图用DB->getfileentry获得第一个dir page并将得到的page id写进_firstDirPageId
- 如果失败,说明文件还不存在
- 用Buffer Manager创建一个新dir page到frame中
- 将这个创建了第一个dir page的file entry加入DB中
- 接着为这个已经在内存里的dir page初始化一个实体HFPage,设好id,将前后设为空,然后让Buffer manager unpin并指明它是dirty的
- 如果成功,说明文件已经存在,往下走
- 如果失败,说明文件还不存在
- 将暂设的_file_deleted设回去
- 完成之后保证:firstDirPageId指向这个file的第一个 dir page,fileName对应系统里实际存在的文件,此时还没pin过任何data page
~HeapFile:执行前需要保证所有page都没有被pin,所有private member都是有效的
- 首先删除_fileName
- 如果是temp file,用deleteFile删掉这个临时文件
- 如果不是,而且这时有多个USER,需要对第一个dirPage加锁然后unpin
getRecCnt:返回整个文件里有多少record
- 遍历每个dir page(查看前要先pin),把里面每个data page的info里的recct累加进answer
- 每个dir page遍历之后要转换到下一个page,并且unpin
insertRecord:接收一个record的指针,内容长度,用来写分配好的rid的参数
- 遍历每个dir page,寻找其中有足够空间(dpinfo.availspace>=recLen)的data page
- 如果当前dir page里已有的data page都不够放:
- 目前的dir page还能够增加新的data page,创建新的data page(_newDataPage),将新的data page插入当前dir page(调用dir page的insertRecord),再在这个新的data page插入record
- 目前的dir page已满,去找下一个dir page(。。。有点蠢?不过record是尽量放到前面的dir page里好点)
- 如果有下一个dir page,unpin现在的dir page,pin下一个dir page,回到outer loop继续找
- 如果已经没有下一个dir page了,怒再创建一个dir page,先buffer manager的newPage,各种初始化,设current dir page的下一个dir page是这个新的dir page(接到链表尾巴),unpin现在的dir page,current dir page轮换到这个新的,然后回到outer loop,这下空间总够了。。
- 找到了可以放的data page之后,pin之,一通检查,然后将record插进去,将它的recct++,更新availspace
- unpin datapage,注意要说明它是dirty的
- 更新dir page里作为record的dpinfo(前面更新的是data page自带的dpinfo)
deleteRecord:接收rid,删除record
- 先把关联的dir page、data page的指针、id和info都拿到手
- 在data page里删掉record,修改recct
- 如果这个时候data page空了(recct==0),free掉data page,在dir page里删掉对应的record
- 如果这个时候dir page也跟着空了(getFirstRecord没返回OK),也删掉这个dir page
- 要检查有没有前一个dir page,有的话绕过去
- 再检查有没有后一个dir page,有的话绕过去
- 检查完之后unpin这个dir page,然后free掉
- 如果没啥空的,该unpin就unpin,然后返回
updateRecord:接收rid,新record的指针和长度,负责把新的record覆盖掉rid所指的record
- 先找data page,找到了去找record,如果长度不和原来一样,报错就跑(= =b)
- 用memcpy修改,unpin掉data page和dir page,返回
getRecord:接收rid,指针,长度,读取指定长度的数据写进指针里
- 调用_findDataPage找有这个rid的data page
- 如果找不到,返回状态码
- 如果找得到,再对这个data page调用getRecord,将record写进来,unpin掉用过的page,返回
openScan:发起scan
- new一个scan,传进this。。。跑人。。
deleteFile:将这个file从database删除
- 如果_file_deleted这个flag是true,说明已经删掉了,报错
- 遍历所有dirPage,删除它们reference的所有data Page(没删完之前要pin住dir page)
- 遍历dirPage的每一个record,里面存有这个file里每一个data page的id,用buffer manager free掉每一个data page(deallocate硬盘空间)
- 获取它后面的dir Page(如果有),删除它自己。如果有下一个dir Page,让buffer manager pin住再进入下一个pass
- 最后删掉file_entry和header page,搞定
- _newDatapage:接收DataPageInfo来分配一个新的data page,注意这个只是用来分配新page的,需要在其他地方将这个新的data page加入directory中
- 先让buffer manager newPage,这样可以进到buffer pool里
- 设置好这个新page的信息(前后为空,pageid设好)
- 设置对应的dpinfo
- _findDatapage:给getRecord和upadateRecord用的,接收rid,将找到的reocrd的位置对应记录在dirPage和dataPage的id与指针参数里,datapage在dir page里的rid,也就是根据rid找它对应的datapa page
- 遍历每个dir page的每个data page,用returnRecord确定在不在data page里,找啊找直到找到为止,把对应的参数写好,返回
- 查看之前要pin,看完要unpin
- 如果找不到,最后面把指针设为NULL,各种id设为INVALID_PAGE,返回
DataPageInfo
描述data page的状况,这是dir page里的record
- availspace: 还剩多少可用空间
- recct: 里面有多少record
- PageId
MINIBASE源代码阅读笔记之heapfile的更多相关文章
- MINIBASE源代码阅读笔记之DB
DB 管理数据库的类 file_entry:dir page的元素,保存不同文件对应的page directory_page:dir page的专用结构体,里面有个初始长度为0的variable si ...
- MINIBASE源代码阅读笔记之buffer manager
BufDesc frame 们的 descriptor(见BufHashTbl注释),包括 pageNo: 这个 frame 在文件里的id,page number prevframe: -1 表示此 ...
- MINIBASE源代码阅读笔记之HFPage
HFPage heap file的page的类 成员 slot_t:用来表示页里的slot,包括offset和length slot[]:倒着生长的slot array slotCnt:有多少已用sl ...
- Mongodb源代码阅读笔记:Journal机制
Mongodb源代码阅读笔记:Journal机制 Mongodb源代码阅读笔记:Journal机制 涉及的文件 一些说明 PREPLOGBUFFER WRITETOJOURNAL WRITETODAT ...
- CI框架源代码阅读笔记5 基准測试 BenchMark.php
上一篇博客(CI框架源代码阅读笔记4 引导文件CodeIgniter.php)中.我们已经看到:CI中核心流程的核心功能都是由不同的组件来完毕的.这些组件类似于一个一个单独的模块,不同的模块完毕不同的 ...
- CI框架源代码阅读笔记3 全局函数Common.php
从本篇開始.将深入CI框架的内部.一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说.全局函数具有最高的载入优先权.因此大多数的框架中BootStrap ...
- CI框架源代码阅读笔记2 一切的入口 index.php
上一节(CI框架源代码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程.这里再次贴出流程图.以备參考: 作为CI框架的入口文件.源代码阅读,自然由此開始. 在源代码阅读的 ...
- Spark源代码阅读笔记之DiskStore
Spark源代码阅读笔记之DiskStore BlockManager底层通过BlockStore来对数据进行实际的存储.BlockStore是一个抽象类,有三种实现:DiskStore(磁盘级别的持 ...
- Java Jdk1.8 HashMap源代码阅读笔记二
三.源代码阅读 3.元素包括containsKey(Object key) /** * Returns <tt>true</tt> if this map contains a ...
随机推荐
- 洛谷P1455 搭配购买
题目描述 明天就是母亲节了,电脑组的小朋友们在忙碌的课业之余挖空心思想着该送什么礼物来表达自己的心意呢?听说在某个网站上有卖云朵的,小朋友们决定一同前往去看看这种神奇的商品,这个店里有n朵云,云朵已经 ...
- php中foreach使用引用的陷阱
有时候我们为了在循环过程中改变数组项的值,在foreach的时候变量入口可以加个&符合, 表示,循环过程中使用数组中原来的值,而不是一个复制的值,如 foreach ($array as &a ...
- Drivers Dissatisfaction 最小生成树+LCA
题意:给一张n个点m条边的连通图,每条边(ai,bi)有一个权值wi和费用ci, 表示这条边每降低1的权值需要ci的花费.现在一共有S费用可以用来降低某些边的权值 (可以降到负数),求图中的一棵权值和 ...
- 删除rabbitmq中持久化的队列和数据
在windows中的rabbitmq安装目录中的/sbin目录下: rabbitmqctl.bat stop_app rabbitmqctl.bat reset rabbitmqctl start_a ...
- I/O多路复用一些概念
一.前言 在事件驱动模型中,我们说当程序遇到I/O操作时,注册 一个回调到事件循环中,主程序继续做其他事情.当I/O操作完成后,再切换回原来的任务.这就是说I/O操作是和程序本身没关系的,其实I/O操 ...
- 调试android chrome web page简明备忘
必备工具 adb tools.android chrome 先开启手机调试模式 adb forward tcp:9919 localabstract:chrome_devtools_remote 成功 ...
- Eclipse 断点调试
Eclipse 开发专用的Debug模式,用于发现问题解决问题. 1. 设置断点,程序会在改位置停止. 2. 按F5(step into), F6(step over)执行.F5指跳入,逐语句.会进入 ...
- /i,/m,/s,/x,/A,/s,/U,/x,/j,/u 等正则修饰符用法~
i (PCRE_CASELESS) 如果设置了这个修饰符,模式中的字母会进行大小写不敏感匹配. m (PCRE_MULTILINE) 默认情况下,PCRE 认为目标字符串是由单行字符组成的(然而实际上 ...
- Paramiko使用
1.下载安装 pycrypto-2.6.1.tar.gz (apt-get install python-dev) 解压,进入,python setup.py build[编译],python set ...
- Oracle笔记之表空间
Oracle中有一个表空间的概念,一个数据库可以有好几个表空间,表放在表空间下. 1. 创建表空间 创建表空间使用create tablespace命令: CREATE TABLESPACE foo_ ...