@w1024020103
2017-03-21 11:20
字数 3332
阅读 635
CS61B
2.3. HeapFile Mutability
Now, we will begin to implement methods to support modifying tables. We begin at the level of individual pages and files. There are two main sets of operations: adding tuples and removing tuples.
Removing tuples: To remove a tuple, you will need to implement deleteTuple. Tuples contain RecordIDs which allow you to find the page they reside on, so this should be as simple as locating the page a tuple belongs to and modifying the headers of the page appropriately.
现在,我们要实现能够支持修改tables的方法。我们从独立的pages和files开始着手。有两类主要的运算符:添加rows和删除rows.
删除rows:要删除一行,你需要执行deleteRow。rows包含了RowId,它可以帮你找到他们所在的页,所以deleteRow其实很简单,只需要找到一行所属的那一page,然后恰当修改这个page的headers。
Adding tuples: The insertTuple method in HeapFile.java is responsible for adding a tuple to a heap file. To add a new tuple to a HeapFile, you will have to find a page with an empty slot. If no such pages exist in the HeapFile, you need to create a new page and append it to the physical file on disk. You will need to ensure that the RecordID in the tuple is updated correctly.
添加rows: HeapFile.java里的insertRow方法负责在一个heap file里添加一行。要在一个HeapFile里添加一行,你需要找到一页有empty slot的page。如果这个HeapFile里面没有这样的页,那你就要新建一个page然后设置它到磁盘上文件的路径。你必须确保这个row的RowId被正确地更新。
Exercise 3. Implement the remaining skeleton methods in:
src/simpledb/HeapPage.java
src/simpledb/HeapFile.java
(Note that you do not necessarily need to implement writePage at this point).
To implement HeapPage, you will need to modify the header bitmap for methods such as insertTuple() and deleteTuple(). You may find that the getNumEmptySlots() and isSlotUsed() methods we asked you to implement in Lab 1 serve as useful abstractions. Note that there is a markSlotUsed method provided as an abstraction to modify the filled or cleared status of a tuple in the page header.
要实现HeapPage,你需要修改insertRow()和deleteRow()等方法的header bitmap. 你可能会发现我们在Lab 1让你实现的getNumEmptySlots()和 isSlotUsed()现在能给你一些提示。注意到有一个markSlotUsed方法用来修改page header里一个row是被填满了还是空的状态。
Note that it is important that the HeapFile.insertTuple() and HeapFile.deleteTuple() methods access pages using the BufferPool.getPage() method; otherwise, your implementation of transactions in the next lab will not work properly.
注意,在HeapFile.insertTuple()和HeapFile.deleteTuple()里采用BufferPool.getPage() 方法来访问pages是非常重要的。否则,在下一个lab里你的transactions实施起来可能出问题。
Implement the following skeleton methods in src/simpledb/BufferPool.java:
insertTuple()
deleteTuple()
These methods should call the appropriate methods in the HeapFile that belong to the table being modified (this extra level of indirection is needed to support other types of files — like indices — in the future).
这些方法应该调用正在被修改的table所属的HeapFile里适当的方法。
At this point, your code should pass the unit tests in HeapPageWriteTest and HeapFileWriteTest. We have not provided additional unit tests for HeapFile.deleteTuple() or BufferPool.
在写HeapFile.java的deleteRow()方法时,一直不知道怎么从BufferPool.getPage返回的Page变到需要的HeapPage, 结果查了大神的代码,只需要一个简单的cast就可以了:
HeapPage pageThisRowIn = (HeapPage) Database.getBufferPool().getPage(tid,pid,Permissions.READ_WRITE);
修改了HeapPage的insertRow()方法,我误以为所有的slots都是依顺序被use, 因此要插入直接从现在的最后一行的下一行开始插入。但实际上不是的,被use的和unused的slots是无序排列的,所以要先遍历所有slots找到那些empty slot来插入!
写HeapFile.java的insertRow()时,看到返回的是一个ArrayList<Page>
,不明白为什么,卡了好一会儿。实际上就是新建一个ArrayList,之后把插入了一行的这一页添加到这个ArrayList里面,返回它就行了。
在运行HeapPageWriteTest测试的时候,我发现又踩了一个老坑,在比较插入行的RowDesc和该页的RowDesc时,我写了:
RowDesc newrd = r.getRowDesc();
if(newrd != rd){
throw new DbException("RowDesc is mismatch");
}
测试不通过,我改成了:
RowDesc newrd = r.getRowDesc();
if(!newrd.equals(rd)){
throw new DbException("RowDesc is mismatch");
}
测试通过!
通俗来说,如何记住区别?(不严谨的说法)
==:等于。
equals:相同。