Heapfile

用来管理heap file里的dir page们

成员

  • _firstDirPageId:这个文件的第一个dir page
  • _ftype:文件类型
  • _file_deleted:删除的时候用的falg
  • _fileName:文件名

方法

  • HeapFile:接收名字,如果是null就开个临时的heapfile(离开的时候会被destructor干掉),否则打开已有文件or创建新文件

    1. 先假设文件已经被干掉,设置filedeleted与_fileName
    2. 如果name是null,起一个临时文件名,否则用给的名字。(这里看到了古老的strdup……)
    3. 试图用DB->getfileentry获得第一个dir page并将得到的page id写进_firstDirPageId
      1. 如果失败,说明文件还不存在
        1. 用Buffer Manager创建一个新dir page到frame中
        2. 将这个创建了第一个dir page的file entry加入DB中
        3. 接着为这个已经在内存里的dir page初始化一个实体HFPage,设好id,将前后设为空,然后让Buffer manager unpin并指明它是dirty的
      2. 如果成功,说明文件已经存在,往下走
    4. 将暂设的_file_deleted设回去
    5. 完成之后保证:firstDirPageId指向这个file的第一个 dir page,fileName对应系统里实际存在的文件,此时还没pin过任何data page
  • ~HeapFile:执行前需要保证所有page都没有被pin,所有private member都是有效的

    1. 首先删除_fileName
    2. 如果是temp file,用deleteFile删掉这个临时文件
    3. 如果不是,而且这时有多个USER,需要对第一个dirPage加锁然后unpin
  • getRecCnt:返回整个文件里有多少record

    1. 遍历每个dir page(查看前要先pin),把里面每个data page的info里的recct累加进answer
    2. 每个dir page遍历之后要转换到下一个page,并且unpin
  • insertRecord:接收一个record的指针,内容长度,用来写分配好的rid的参数

    1. 遍历每个dir page,寻找其中有足够空间(dpinfo.availspace>=recLen)的data page
    2. 如果当前dir page里已有的data page都不够放:
      1. 目前的dir page还能够增加新的data page,创建新的data page(_newDataPage),将新的data page插入当前dir page(调用dir page的insertRecord),再在这个新的data page插入record
      2. 目前的dir page已满,去找下一个dir page(。。。有点蠢?不过record是尽量放到前面的dir page里好点)
      3. 如果有下一个dir page,unpin现在的dir page,pin下一个dir page,回到outer loop继续找
      4. 如果已经没有下一个dir page了,怒再创建一个dir page,先buffer manager的newPage,各种初始化,设current dir page的下一个dir page是这个新的dir page(接到链表尾巴),unpin现在的dir page,current dir page轮换到这个新的,然后回到outer loop,这下空间总够了。。
    3. 找到了可以放的data page之后,pin之,一通检查,然后将record插进去,将它的recct++,更新availspace
    4. unpin datapage,注意要说明它是dirty的
    5. 更新dir page里作为record的dpinfo(前面更新的是data page自带的dpinfo)
  • deleteRecord:接收rid,删除record

    1. 先把关联的dir page、data page的指针、id和info都拿到手
    2. 在data page里删掉record,修改recct
    3. 如果这个时候data page空了(recct==0),free掉data page,在dir page里删掉对应的record
    4. 如果这个时候dir page也跟着空了(getFirstRecord没返回OK),也删掉这个dir page
      1. 要检查有没有前一个dir page,有的话绕过去
      2. 再检查有没有后一个dir page,有的话绕过去
      3. 检查完之后unpin这个dir page,然后free掉
    5. 如果没啥空的,该unpin就unpin,然后返回
  • updateRecord:接收rid,新record的指针和长度,负责把新的record覆盖掉rid所指的record

    1. 先找data page,找到了去找record,如果长度不和原来一样,报错就跑(= =b)
    2. 用memcpy修改,unpin掉data page和dir page,返回
  • getRecord:接收rid,指针,长度,读取指定长度的数据写进指针里

    1. 调用_findDataPage找有这个rid的data page
    2. 如果找不到,返回状态码
    3. 如果找得到,再对这个data page调用getRecord,将record写进来,unpin掉用过的page,返回
  • openScan:发起scan

    1. new一个scan,传进this。。。跑人。。
  • deleteFile:将这个file从database删除

    1. 如果_file_deleted这个flag是true,说明已经删掉了,报错
    2. 遍历所有dirPage,删除它们reference的所有data Page(没删完之前要pin住dir page)
      1. 遍历dirPage的每一个record,里面存有这个file里每一个data page的id,用buffer manager free掉每一个data page(deallocate硬盘空间)
      2. 获取它后面的dir Page(如果有),删除它自己。如果有下一个dir Page,让buffer manager pin住再进入下一个pass
    3. 最后删掉file_entry和header page,搞定
  • _newDatapage:接收DataPageInfo来分配一个新的data page,注意这个只是用来分配新page的,需要在其他地方将这个新的data page加入directory中
    1. 先让buffer manager newPage,这样可以进到buffer pool里
    2. 设置好这个新page的信息(前后为空,pageid设好)
    3. 设置对应的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的更多相关文章

  1. MINIBASE源代码阅读笔记之DB

    DB 管理数据库的类 file_entry:dir page的元素,保存不同文件对应的page directory_page:dir page的专用结构体,里面有个初始长度为0的variable si ...

  2. MINIBASE源代码阅读笔记之buffer manager

    BufDesc frame 们的 descriptor(见BufHashTbl注释),包括 pageNo: 这个 frame 在文件里的id,page number prevframe: -1 表示此 ...

  3. MINIBASE源代码阅读笔记之HFPage

    HFPage heap file的page的类 成员 slot_t:用来表示页里的slot,包括offset和length slot[]:倒着生长的slot array slotCnt:有多少已用sl ...

  4. Mongodb源代码阅读笔记:Journal机制

    Mongodb源代码阅读笔记:Journal机制 Mongodb源代码阅读笔记:Journal机制 涉及的文件 一些说明 PREPLOGBUFFER WRITETOJOURNAL WRITETODAT ...

  5. CI框架源代码阅读笔记5 基准測试 BenchMark.php

    上一篇博客(CI框架源代码阅读笔记4 引导文件CodeIgniter.php)中.我们已经看到:CI中核心流程的核心功能都是由不同的组件来完毕的.这些组件类似于一个一个单独的模块,不同的模块完毕不同的 ...

  6. CI框架源代码阅读笔记3 全局函数Common.php

    从本篇開始.将深入CI框架的内部.一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说.全局函数具有最高的载入优先权.因此大多数的框架中BootStrap ...

  7. CI框架源代码阅读笔记2 一切的入口 index.php

    上一节(CI框架源代码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程.这里再次贴出流程图.以备參考: 作为CI框架的入口文件.源代码阅读,自然由此開始. 在源代码阅读的 ...

  8. Spark源代码阅读笔记之DiskStore

    Spark源代码阅读笔记之DiskStore BlockManager底层通过BlockStore来对数据进行实际的存储.BlockStore是一个抽象类,有三种实现:DiskStore(磁盘级别的持 ...

  9. Java Jdk1.8 HashMap源代码阅读笔记二

    三.源代码阅读 3.元素包括containsKey(Object key) /** * Returns <tt>true</tt> if this map contains a ...

随机推荐

  1. django 表单验证和字段验证

    表单验证和字段验证 表单验证发生在数据验证之后.如果你需要自定义这个过程,有几个不同的地方可以修改,每个地方的目的不一样.表单处理过程中要运行三种类别的验证方法.它们通常在你调用表单的is_valid ...

  2. ORACLE 中如何截取到时间的年月日中的年、月、日

    在Oracle中,要获得日期中的年份,例如把sysdate中的年份取出来,并不是一件难事.常用的方法是:Select to_number(to_char(sysdate,'yyyy')) from d ...

  3. python 之 strip()--(转载)

    原博地址:http://www.jb51.net/article/37287.htm 函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm)        删除s字符串中开头.结尾 ...

  4. poj2115 C Looooops

    C Looooops Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29262   Accepted: 8441 Descr ...

  5. vim 单文件中查找方法

    1.vim 单文件中查找方法 正常模式下使用 / 或 ? 命令执行向后搜索或向前搜索 /love   从光标位置向前搜索关键词 love ?love   从光标位置向后搜索关键词 love 正常模式下 ...

  6. [LeetCode] “全排列”问题系列(一) - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题

    一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer上的一道例题入手,小谈一下这种类型题目的解法. 二.上手 最典型的permutation题目是这样的 ...

  7. King's Sanctuary(简单几何)

    King's Sanctuary Time Limit: 1000 ms Memory Limit: 65535 kB Solved: 111 Tried: 840 Submit Status Bes ...

  8. asp.net mvc 站点优化

    基于上篇:IIS网站日志分析 现象 服务端:IIS 日志, #Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-u ...

  9. Oracle Number类型超长小数位为0问题

    碰到了一个非常奇怪的问题,从Excel拷贝出来的数据,位数很长,通过Pl Sql 导出到Oracle后为0了,而且设置查询条件为0时,无法查询出来,条件大于0居然能查询出来,通过to_number也是 ...

  10. 51nod 1161 Partial Sums

    给出一个数组A,经过一次处理,生成一个数组S,数组S中的每个值相当于数组A的累加,比如:A = {1 3 5 6} => S = {1 4 9 15}.如果对生成的数组S再进行一次累加操作,{1 ...