/** * Compares one PageId to another. * * @param o The object to compare against (must be a PageId) * @return true if the objects are equal (e.g., page numbers and table ids are the same) */ public boolean equals(Object o) { if (!(o instanceof PageId)) return false; PageId other = (PageId) o; if (this.getTableId() != other.getTableId() || this.pageNumber() != other.pageNumber()) return false; return true; }
/** * Retrieve the specified page with the associated permissions. Will acquire a lock and may block * if that lock is held by another transaction. * * <p>The retrieved page should be looked up in the buffer pool. If it is present, it should be * returned. If it is not present, it should be added to the buffer pool and returned. If there is * insufficient space in the buffer pool, an page should be evicted and the new page should be * added in its place. * * @param tid the ID of the transaction requesting the page * @param pid the ID of the requested page * @param perm the requested permissions on the page * @throws IOException * @throws NoSuchElementException */ public Page getPage(TransactionId tid, PageId pid, Permissions perm) throws TransactionAbortedException, DbException, NoSuchElementException, IOException { if (this.deadPool.containsKey(pid)) { return this.deadPool.get(pid); } else { if (this.deadPool.size() >= this.numPages) { throw new DbException("Too many pages!"); } else { this.deadPool.put( pid, Database.getCatalog().getDatabaseFile(pid.getTableId()).readPage(pid)); return this.deadPool.get(pid); } } }
/** * 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); } } }
/** * Retrieve the specified page with the associated permissions. Will acquire a lock and may block * if that lock is held by another transaction. * * <p>The retrieved page should be looked up in the buffer pool. If it is present, it should be * returned. If it is not present, it should be added to the buffer pool and returned. If there is * insufficient space in the buffer pool, an page should be evicted and the new page should be * added in its place. * * @param tid the ID of the transaction requesting the page * @param pid the ID of the requested page * @param perm the requested permissions on the page * @throws DbException * @throws TransactionAbortedException */ public Page getPage(TransactionId tid, PageId pid, Permissions perm) throws DbException, TransactionAbortedException { lockManager.acquireLock(tid, pid, perm); if (pageIdToPages.containsKey(pid)) { return pageIdToPages.get(pid); } if (currentPages.get() == maxPages) { evictPage(); } int tableId = pid.getTableId(); Catalog catalog = Database.getCatalog(); DbFile dbFile = catalog.getDatabaseFile(tableId); Page page = dbFile.readPage(pid); pageIdToPages.put(pid, page); currentPages.incrementAndGet(); return page; }