6.830 Lab 总览

项目结构


 

相关类和方法


TupleDesc.java:

  • class TDItem :用于组织每一列的辅助类,包含fieldType和fieldName两个属性。
  • ​​​​​​TupleDesc构造函数:创建一个TDItem数组,描述一个tuple包括哪些field。
  • numFields():返回TDItem数组的大小。
  • getFieldName(int i):返回TDItem数组中下标i的fieldName。
  • getFieldType(int i):返回TDItem数组中下标i的fieldType。
  • fieldNameToIndex(String name):遍历TDItem数组找到对应fieldName的下标。getSize():遍历TDItem数组,求每一列fieldType大小总和。
  • merge(TupleDesc td1, TupleDesc td2):把两个TupleDesc合二为一。
  • equals(Object o):判断两个TupleDesc的列属性是否相同。

Tuple.java:

  • Tuple构造函数:创建fields数组。
  • getTupleDesc():返回当前tuple的TupleDesc结构。
  • getRecordId()、setRecordId:获得/设置当前tuple的RecordId,RecordId代表了当前tuple在disk上的位置。
  • setField(int i, Field f):为fields数组下标i处的field赋新值。
  • getField(int i):获得fields数组下标i处的field值。
  • fields():返回一个迭代器,迭代此tuple内fields数组的所有元素。

Catalog.java:

  • class Table:为Catalog存储的一个个表建立的辅助类,Table类的构造函数需要三个参数,第一个参数是DbFile类型,是table的内容;第二个参数是String类型,是table 的name;第三个参数是pkeyField,代表表中主键的fieldName。
  • Catalog构造函数:创建一个<Interger,Table>的哈希表,用于存储已经实例化的表。
  • addTable(DbFile file, String name, String pkeyField):在哈希表中添加一个Table。
  • getTableId(String name):遍历哈希表中的Tables,找到对应名字返回table的Id。
  • getTupleDesc(int tableid):返回tableid表对应的TupleDesc表结构。
  • getDatabaseFile(int tableid):返回tableid表对应的表数据DbFile。
  • getPrimaryKey(int tableid):返回tableid表对应的主键名。
  • getTableName(int id):返回tableid表对应的TableName。
  • clear():从Catalog中删除所有的tables。
  • loadSchema(String catalogFile):利用正则化从file中读取表的结构,并在数据库中创建所有合适的表。

BufferPool.java:

  • class Lock:为Transaction设置锁的辅助类,Lock类的构造函数需要两个参数,第一个参数是加锁Transaction的TransactionId;第二个参数是锁的类型(0 for shared lock and 1 for exclusive lock)。
  • class PageLockManager:管理基于页的加锁解锁所需的辅助类,创建一个<PageId,Vector<Lock>>的哈希表,保存每页上拥有的锁集合。有三个内置方法,第一个是acquireLock(PageId pid,TransactionId tid,int lockType)用来加锁;第二个是releaseLock(PageId pid,TransactionId tid)用来解锁;第三个是holdsLock(PageId pid,TransactionId tid)用来判断是否有锁。
  • BufferPool(int numPages):BufferPool的构造函数,创建一个BufferPool实例缓存最大numPages数量的Pages,通过<PageId,Page>类型的pageStore哈希表管理缓存pages。
  • getPageSize():获得每个Page大小,默认是4096。
  • getPage(TransactionId tid, PageId pid, Permissions perm):根据pid获取Page,如果在pageStore中,返回对应Page,如果不在就添加进哈希表,如果缓存的page数量超过缓存最大numPages数量,调用evictPage()淘汰一个页。获得page时在tid代表的Transaction上加锁,perm代表锁的类型,保证使用返回Page时的安全性。
  • releasePage(TransactionId tid, PageId pid):调用 lockManager.releaseLock(pid,tid) 解锁。
  • holdsLock(TransactionId tid, PageId p):判断特定Transaction是否在特定Page上加了锁。
  • transactionComplete(TransactionId tid, boolean commit):如果commit,则调用flushPages(tid)将缓存中的页数据写入disk。如果没有commit,则调用 restorePages(tid) 回滚commit,重置pageStore中dirty的Page。
  • insertTuple(TransactionId tid, int tableId, Tuple t):在BufferPool中添加特定的tuple到tableId对应的表中,调用DbFile的insertTuple(tid, t)方法(其中有一个读写锁),并将添加了tuple的page mark dirty。
  • deleteTuple(TransactionId tid, Tuple t):从BufferPool中删除特定的tuple,调用DbFile的deleteTuple(tid, t)方法(其中有一个读写锁),并将删除了tuple的page mark dirty。
  • discardPage(PageId pid):从BufferPool的缓存中删除pid对应的page。
  • flushPage(PageId pid):将pid对应的Page从BuffePool的缓存中写入disk。
  • flushPages(TransactionId tid):将tid下所有BufferPool缓存中的Page都写入disk。
  • evictPage():当缓存的page数量超过缓存最大numPages数量,调用evictPage()淘汰一个页。先维护一个<PageId,Integer>类型的哈希表pageAge,根据Page载入cache的时间排序,淘汰缓存中最老的Page,当然这是最简单的一种实现,还有其他实现方式。

 

HeapPageId.java  :

  • HeapPageId的构造函数:对于特定table中的一页特定Page,设置一个page id 结构,参数为int类型的tableId和int类型的pgNo。
  • getTableId():返回PageId对应的tableId。
  • getPageNumber():返回tableId对应的表包含的page数量。
  • equals(Object o):判断两个pageId对象是否相等。

 

RecordID.java:

  • RecordId的构造函数:RecordId是对一个特定Table中特定一个Page的一个特定tuple的引用,构造时用到的参数是PageId类型的 pid 和 int类型的 tupleno,其中pid是该tuple所在的Page对应的Id,tupleno是该tuple是该Page中第几个。
  • getTupleNumber():返回RecordId引用tuple的tupleno。
  • getPageId():返回RecordId引用tuple的pid。
  • equals(Object o):判断两个RecordId对象是否相等。

HeapPage.java:

  • class HeapPageIterator:用于迭代HeapPage,有hasNext()、next()、remove()等方法。
  • HeapPage的构造函数:有两个参数,第一个是HeapPageId,第二个是byte[] 类型的data。在构造函数中为data分配空间,并将空间中开始部分用于header,header中保存了此页slots的bitmap信息。
  • getNumTuples():返回此页中能够存储的tuple数量,用于构造函数中分配slot。
  • getHeaderSize():返回此页需要多少bytes作为header。
  • getBeforeImage():在修改前返回此页的view,用于recovery。
  • getId():返回此页的pid。
  • readNextTuple(DataInputStream dis, int slotId):寻找到下一个被占用的slot,返回读取的tuple。
  • getPageData():返回byte[] 类型的此页数据。
  • deleteTuple(Tuple t):从此页中删除特定的tuple数据,同时修改header中对应的bit,指示此slot处的数据已经被删除了。(这里其实没有删除数据,只是在header处显示此处数据为空,可用其他数据替换)。
  • insertTuple(Tuple t):利用getFirstNotUsedSlot()函数找到第一个空闲的slot,加入数据,同时修改header中对应的bit,指示此slot处有数据。
  • getFirstNotUsedSlot():找到第一个为空的slot下标。
  • markDirty(boolean dirty, TransactionId tid):标识此页的dirty/not dirty状态,同时利用tid说明是哪一个Transaction做了该标识。
  • TransactionId isDirty():返回最后一个dirtied了此页的Transaction的tid,如果不dirty返回null。
  • getNumEmptySlots():返回此页中为空的slot数量。
  • isSlotUsed(int i):判断下标为i的slot是否被占用。
  • markSlotUsed(int i, boolean value):在header中标识下标为i的slot是否被占用,true在header的bit位上标1,false则标0。

 

HeapFile.java:

  • HeapFile的构造函数:通过特定的file文件构建一个heap file,有两个参数,第一个是File类型的f,第二个是TupleDesc类型的td。
  • getFile():返回磁盘中支持此HeapFile 的File类型文件。
  • getId():返回唯一标识此HeapFile的ID。
  • getTupleDesc():返回存储在这个DbFile中的table 的TupleDesc。
  • readPage(PageId pid):读取pid对应的Page。先找到File内要读取的Page Number,读取整个Page返回。
  • writePage(Page page):写pid对应的Page。先找到File内要写的Page Number,写入整个Page。
  • numPages():返回这个HeapFile中包含的page数量。
  • insertTuple(TransactionId tid, Tuple t):找到一个未满的page,如果不存在空闲的slot,创建新的一页存储tuple,之后添加,返回添加过的Page。
  • deleteTuple(TransactionId tid, Tuple t):找到对应的page,删除tuple,标识此page为dirty。

 

SeqScan.java:

  • SeqScan的构造函数:创建一次特定的transaction对特定table内的数据进行遍历,有三个参数,第一个参数是transaction对应的tid;第二个参数是tableId;第三个参数是表的别名,用于解析。
  • getTableName():返回对应tid。
  • getAlias():返回对应别名。
  • open():使用DbFileIterator打开table。
  • getTupleDesc():返回table 的TupleDesc类型。
  • close():使用DbFileIterator关闭table。

 

Predicate.java:

  • enum Op:枚举定义了EQUALS, GREATER_THAN, LESS_THAN, LESS_THAN_OR_EQ, GREATER_THAN_OR_EQ, LIKE,NOT_EQUALS这六种Predicate Op。
  • Predicate构造函数:这里有三个参数,第一个参数是field,是进行谓词比较的filed 数量;第二个参数是Op,是用于比较的谓词Operation;第三个参数是operand,时传入要比较的field value。
  • filter(Tuple t):在特定的field、Operation、operand下与tuple t进行比较。

 

JoinPredicate.java:

  • JoinPredicate的构造函数:JoinPredicate利用一个Predicate对两个tuples的fields进行比较,JoinPredicate最常被Join operator使用。构造函数创建在两个tuples的两个fields上创建一个新的Predicate。有三个参数,第一个参数和第二个参数是field1和field2,是Predicate中第一个tuple和第二个tuple的下标;第三个参数是op,是应用的operation。
  • filter(Tuple t1, Tuple t2):将Predicate用用两个特定tuples。

 

Aggregate.java:

  • Aggregate的构造函数:Aggregation operator用于计算一个Aggregate(e.g. sum,avg,max,min),我们需要对一列数据支持聚合。构造函数有四个参数,第一个参数是OpIterator类型的 child,用于不断提供tuples;第二个参数是 int 类型的 afield,标识着我们需要聚合的列;第三个参数是 int 类型的gfield,标识着结果中我们需要group by 的列;第四个参数是 Aggregator.Op类型的aop,是我们需要使用的Aggregation operator。
  • groupField():如果这个Aggregate伴随有 groupby,返回groupby的field 的索引。
  • groupFieldName():如果这个Aggregate伴随有 groupby,返回groupby的field 的Name。
  • fetchNext():返回下一个tuple。如果有groupby field,那么第一个field是我们group的field,第二个field是计算的aggregate结果;如果没有groupby field,只需要返回结果。
  • getTupleDesc():返回这个aggregate计算结果tuple的TupleDesc。

Insert.java:

  • class Insert的构造函数:把从child operator中读取到的tuples添加到tableId对应的表中。有三个参数,第一个参数是代表transaction的tid,第二个参数是OpIterator类型的迭代器child,第三个参数是tableId。
  • fetchNext():利用OpIterator类型的迭代器child找到一组要添加的记录,insert需要经过BufferPool,所以使用Database.getBufferPool().insertTuple(this.tid, this.tableId, t)方法进行添加。

Delete.java:

  • class Insert的构造函数:把从child operator中读取到的tuples从tableId对应的表中删除。有两个参数,第一个参数是代表transaction的tid,第二个参数是OpIterator类型的迭代器child。
  • fetchNext():利用OpIterator类型的迭代器child找到一组要删除的记录,insert需要经过BufferPool,所以使用Database.getBufferPool().deleteTuple(this.tid, t)方法进行删除。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值