MCPcopy Create free account
hub / github.com/1345414527/MIT6.830 / splitLeafPage

Method splitLeafPage

src/java/simpledb/index/BTreeFile.java:267–317  ·  view source on GitHub ↗

Split a leaf page to make room for new tuples and recursively split the parent node as needed to accommodate a new entry. The new entry should have a key matching the key field of the first tuple in the right-hand page (the key is "copied up"), and child pointers pointing to the two leaf pages resul

(TransactionId tid, Map<PageId, Page> dirtypages, BTreeLeafPage page, Field field)

Source from the content-addressed store, hash-verified

265 * @throws TransactionAbortedException
266 */
267 public BTreeLeafPage splitLeafPage(TransactionId tid, Map<PageId, Page> dirtypages, BTreeLeafPage page, Field field)
268 throws DbException, IOException, TransactionAbortedException {
269 // some code goes here
270 //
271 // Split the leaf page by adding a new page on the right of the existing
272 // page and moving half of the tuples to the new page. Copy the middle key up
273 // into the parent page, and recursively split the parent as needed to accommodate
274 // the new entry. getParentWithEmtpySlots() will be useful here. Don't forget to update
275 // the sibling pointers of all the affected leaf pages. Return the page into which a
276 // tuple with the given key field should be inserted.
277 //1. 将当前page的后半部分放入新page
278 int half = page.getNumTuples()/2;
279 BTreeLeafPage newPage = (BTreeLeafPage)getEmptyPage(tid,dirtypages,BTreePageId.LEAF);
280 Iterator<Tuple> iterator = page.reverseIterator();
281 while(iterator.hasNext() && half>0){
282 Tuple next = iterator.next();
283 //这里要先删除在插入,就很坑
284 page.deleteTuple(next);
285 newPage.insertTuple(next);
286 --half;
287 }
288 //2. 获取当前要插入的父节点,并插入新节点
289 Tuple up = iterator.next();
290 BTreeInternalPage parentPage = getParentWithEmptySlots(tid, dirtypages, page.getParentId(), field);
291 BTreeEntry insertEntry = new BTreeEntry(up.getField(keyField), page.getId(), newPage.getId());
292 parentPage.insertEntry(insertEntry);
293 //3. 设置节点间的关系
294 // page newPage rightSibling
295 if(page.getRightSiblingId()!=null){
296 BTreeLeafPage right = (BTreeLeafPage) getPage(tid, dirtypages, page.getRightSiblingId(), Permissions.READ_WRITE);
297 right.setLeftSiblingId(newPage.getId());
298 dirtypages.put(right.getId(),right);
299 }
300 newPage.setRightSiblingId(page.getRightSiblingId());
301 newPage.setLeftSiblingId(page.getId());
302 page.setRightSiblingId(newPage.getId());
303
304 page.setParentId(parentPage.getId());
305 newPage.setParentId(parentPage.getId());
306
307 //4. 增加脏页
308 dirtypages.put(parentPage.getId(),parentPage);
309 dirtypages.put(page.getId(),page);
310 dirtypages.put(newPage.getId(),newPage);
311
312 //5. 返回要插入field的页
313 if (field.compare(Op.GREATER_THAN_OR_EQ, up.getField(keyField))) {
314 return newPage;
315 }
316 return page;
317 }
318
319 /**
320 * Split an internal page to make room for new entries and recursively split its parent page

Callers 3

testSplitLeafPagesMethod · 0.95
testReusePageMethod · 0.95
insertTupleMethod · 0.95

Calls 15

getEmptyPageMethod · 0.95
insertTupleMethod · 0.95
getFieldMethod · 0.95
insertEntryMethod · 0.95
getPageMethod · 0.95
setLeftSiblingIdMethod · 0.95
setRightSiblingIdMethod · 0.95
putMethod · 0.80
hasNextMethod · 0.65
nextMethod · 0.65
deleteTupleMethod · 0.65

Tested by 2

testSplitLeafPagesMethod · 0.76
testReusePageMethod · 0.76