From 5bd0da597002403c37593ff9844d905bcde902be Mon Sep 17 00:00:00 2001 From: Sean Date: Sat, 2 Mar 2024 11:45:02 -0500 Subject: [PATCH] finished Project 2 --- .../cs448p2/src/main/java/bufmgr/BufMgr.java | 88 +++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/Projects/cs448p2/src/main/java/bufmgr/BufMgr.java b/Projects/cs448p2/src/main/java/bufmgr/BufMgr.java index 67789c3..95c6009 100644 --- a/Projects/cs448p2/src/main/java/bufmgr/BufMgr.java +++ b/Projects/cs448p2/src/main/java/bufmgr/BufMgr.java @@ -109,7 +109,41 @@ public class BufMgr { */ public void pinPage(PageId pageno, Page page, boolean emptyPage) throws BufferPoolExceededException, DiskMgrException { - // YOUR CODE HERE + //Check if page already in memory + if (pageMap.containsKey(pageno.pid)) { + // page is already in memory + Integer frameno = pageMap.get(pageno.pid); + frmDescr[frameno].pinCount++; + + if (frmDescr[frameno].pinCount == 1) { + //the frame was marked previously removal, we need to undo that. + fifo.remove(frameno); + } + page.setPage(bufPool[frameno]); + } else { + if (fifo.size() > 0) { + // there is a page that can be removed + Integer frameno = fifo.remove(); + if (frmDescr[frameno].pageno != -1) { + // the frame is not empty + PageId oldPage = new PageId(frmDescr[frameno].pageno); + pageMap.remove(oldPage.pid); + if (frmDescr[frameno].dirtyBit) { + // the page has been written to, and needs to be written to disk + Minibase.DiskManager.write_page(oldPage, bufPool[frameno]); + } + } + // we now have an empty frame in frameno + // we can grab the new page + Minibase.DiskManager.read_page(pageno, bufPool[frameno]); + page.setPage(bufPool[frameno]); + pageMap.put(pageno.pid, frameno); + resetFrameDescriptor(frameno, pageno.pid); + frmDescr[frameno].pinCount++; + } else { + throw new BufferPoolExceededException("All pages in the buffer pool are pinned."); + } + } } /** @@ -129,7 +163,24 @@ public class BufMgr { */ public void unpinPage(PageId pageno, boolean dirty) throws PageNotFoundException, PageUnpinnedException { - // YOUR CODE HERE + if (!pageMap.containsKey(pageno.pid)) { + throw new PageNotFoundException("the page is not in memory"); + } + Integer frameno = pageMap.get(pageno.pid); + + if (frmDescr[frameno].pinCount > 0) { + frmDescr[frameno].pinCount--; + if (frmDescr[frameno].pinCount == 0) { + //add to fifo + fifo.add(frameno); + } + } else { + throw new PageUnpinnedException("the page is already unpinned"); + } + + if (dirty) { + frmDescr[frameno].dirtyBit = true; + } } /** @@ -149,8 +200,26 @@ public class BufMgr { * @throws BufferPoolExceededException if the new page cannot be pinned after the run is allocated due to the buffer being full. If this exception is thrown, the newly allocated pages should be deallocated */ public PageId newPage(Page firstpage, int howmany) throws DiskMgrException, BufferPoolExceededException { - // YOUR CODE HERE - return new PageId(); + PageId nPage = null; + + try { + nPage = Minibase.DiskManager.allocate_page(howmany); + + pinPage(nPage, firstpage, false); + return nPage; + + } catch (BufferPoolExceededException bee) { + try { + if (nPage != null){ + Minibase.DiskManager.deallocate_page(nPage, howmany); + } + } catch (BufMgrException be) { + throw new DiskMgrException("Exception in deallocating page."); + } + throw bee; + } catch (BufMgrException be) { + throw new DiskMgrException("Exception in allocating page."); + } } /** @@ -163,7 +232,16 @@ public class BufMgr { * @throws DiskMgrException if there is an error in the DiskMgr layer. This is likely caused by incorrect implementations in other methods of the Buffer Manager */ public void freePage(PageId pageno) throws PagePinnedException, DiskMgrException { - // YOUR CODE HERE + if (pageMap.containsKey(pageno.pid)) { + Integer frameno = pageMap.get(pageno.pid); + if (frmDescr[frameno].pinCount > 0) { + throw new PagePinnedException("The page is still pinned!"); + } else { + pageMap.remove(pageno.pid); + resetFrameDescriptor(frameno); + // bufPool[frameno] = new Page(); + } + } } /**