/** * Remove the specified tuple from the buffer pool. Will acquire a write lock on the page the * tuple is removed from. May block if the lock cannot be acquired. * * <p>Marks any pages that were dirtied by the operation as dirty by calling their markDirty bit. * Does not need to update cached versions of any pages that have been dirtied, as it is not * possible that a new page was created during the deletion (note difference from addTuple). * * @param tid the transaction deleting the tuple. * @param t the tuple to delete */ public void deleteTuple(TransactionId tid, Tuple t) throws DbException, TransactionAbortedException { HeapFile heapFile = (HeapFile) Database.getCatalog().getDatabaseFile(t.getRecordId().getPageId().getTableId()); Page dirtiedPage = heapFile.deleteTuple(tid, t); dirtiedPage.markDirty(true, tid); }
/** * Commit or abort a given transaction; release all locks associated to the transaction. * * @param tid the ID of the transaction requesting the unlock * @param commit a flag indicating whether we should commit or abort */ public void transactionComplete(TransactionId tid, boolean commit) throws IOException { if (commit) { Set<PageId> dirtiedFlushedPages = transactionsToDirtiedFlushedPages.get(tid); for (PageId pageId : pageIdToPages.keySet()) { Page page = pageIdToPages.get(pageId); if (tid.equals(page.isDirty())) { flushPage(pageId); // use current page contents as the before-image // for the next transaction that modifies this page. page.setBeforeImage(); } else if (dirtiedFlushedPages != null && dirtiedFlushedPages.contains(pageId)) { page.setBeforeImage(); } } } else { for (PageId pageId : pageIdToPages.keySet()) { Page page = pageIdToPages.get(pageId); if (tid.equals(page.isDirty())) { pageIdToPages.put(pageId, page.getBeforeImage()); page.markDirty(false, null); } } } transactionsToDirtiedFlushedPages.remove(tid); lockManager.releasePages(tid); // if commit, flush dirty pages associated with transaction // if !commit, restore dirty pages associated with transaction to // previous // state // release all locks (and other state? don't think there is any) }
/** * Add a tuple to the specified table behalf of transaction tid. Will acquire a write lock on the * page the tuple is added to(Lock acquisition is not needed for lab2). May block if the lock * cannot be acquired. * * <p>Marks any pages that were dirtied by the operation as dirty by calling their markDirty bit, * and updates cached versions of any pages that have been dirtied so that future requests see * up-to-date pages. * * @param tid the transaction adding the tuple * @param tableId the table to add the tuple to * @param t the tuple to add */ public void insertTuple(TransactionId tid, int tableId, Tuple t) throws DbException, IOException, TransactionAbortedException { HeapFile heapFile = (HeapFile) Database.getCatalog().getDatabaseFile(tableId); List<Page> dirtiedPages = heapFile.insertTuple(tid, t); for (Page dirtiedPage : dirtiedPages) { dirtiedPage.markDirty(true, tid); } }
/** * Flushes a certain page to disk * * @param pageId an ID indicating the page to flush */ private synchronized void flushPage(PageId pageId) throws IOException { if (pageIdToPages.containsKey(pageId)) { Page page = pageIdToPages.get(pageId); // append an update record to the log, with // a before-image and after-image. TransactionId dirtier = page.isDirty(); if (dirtier != null) { addDirtiedFlushedPage(dirtier, pageId); Database.getLogFile().logWrite(dirtier, page.getBeforeImage(), page); Database.getLogFile().force(); Database.getCatalog().getDatabaseFile(pageId.getTableId()).writePage(page); page.markDirty(false, null); } } }