diff --git a/p2/.idea/workspace.xml b/p2/.idea/workspace.xml
index 830143f..f33fa25 100644
--- a/p2/.idea/workspace.xml
+++ b/p2/.idea/workspace.xml
@@ -1,8 +1,563 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1551027011045
+
+
+ 1551027011045
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/src/tests/BMTest.java
+ 769
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No facets are configured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+ p2
+
+
+
+
+
+
+
+
+
+
+
+
+ lib
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/p2/src/bufmgr/BufMgr.java b/p2/src/bufmgr/BufMgr.java
index ba904aa..64f4470 100644
--- a/p2/src/bufmgr/BufMgr.java
+++ b/p2/src/bufmgr/BufMgr.java
@@ -1,5 +1,6 @@
package bufmgr;
+import diskmgr.DiskMgr;
import diskmgr.DiskMgrException;
import global.Minibase;
import global.Page;
@@ -30,6 +31,9 @@ public class BufMgr {
// ago
private Queue fifo = null;
//END OF REQUIRED INSTANCE VARIABLES
+ private int nextIndex = 0;
+ private boolean isFull = false;
+
/**
* Create the BufMgr object. Allocate pages (frames) for the buffer pool in main
@@ -92,7 +96,86 @@ public class BufMgr {
*/
public void pinPage(PageId pageno, Page page, boolean emptyPage)
throws BufferPoolExceededException, DiskMgrException {
- //YOUR CODE HERE
+ Integer foundEntry = hashTable.get(pageno.pid);
+
+ if (foundEntry != null) {
+ FrameDescriptor desc = bufDescr[foundEntry];
+ desc.PinCount++;
+ page.setPage(bufFrames[foundEntry]);
+ } else {
+ Page foundPage = new Page();
+ if (isFull) {
+ int index = -1;
+
+ for (Integer item : fifo) {
+ Integer pointer = hashTable.get(item);
+ if (pointer != null && bufDescr[pointer].PinCount <= 0) {
+ index = pointer;
+ break;
+ }
+ }
+
+ if (index <= -1) {
+ throw new BufferPoolExceededException("No item found with 0 pin count");
+ }
+
+// Integer head = fifo.poll();
+//
+// if (head != null) {
+// index = hashTable.get(head);
+// } else {
+// throw new BufferPoolExceededException("No head found in FIFO Queue");
+// }
+
+ if (bufDescr[index].DirtyBit) {
+ try {
+ // TODO: May be wrong error.
+ flushPage(new PageId(bufDescr[index].PageNumber));
+ } catch (HashEntryNotFoundException e) {
+ throw new DiskMgrException(e.getMessage());
+ }
+ }
+
+ Minibase.DiskManager.read_page(pageno, foundPage);
+
+ // Something to do with pin counts?
+ if (bufDescr[index] != null) {
+ hashTable.remove(bufDescr[index].PageNumber);
+ }
+
+ bufFrames[index] = foundPage;
+ FrameDescriptor desc = new FrameDescriptor();
+ desc.PageNumber = pageno.pid;
+ desc.PinCount = 1;
+ bufDescr[index] = desc;
+ hashTable.put(pageno.pid, index);
+ } else {
+ Minibase.DiskManager.read_page(pageno, foundPage);
+
+ if (bufDescr[nextIndex] != null) {
+ hashTable.remove(bufDescr[nextIndex].PageNumber);
+ }
+
+ bufFrames[nextIndex] = foundPage;
+ FrameDescriptor desc = new FrameDescriptor();
+ desc.PageNumber = pageno.pid;
+ bufDescr[nextIndex] = desc;
+ desc.PinCount++;
+ hashTable.put(pageno.pid, nextIndex);
+
+ if (nextIndex < bufFrames.length) {
+ nextIndex++;
+ }
+
+ if (nextIndex >= bufFrames.length) {
+ isFull = true;
+ }
+ }
+
+ page.setPage(foundPage);
+ }
+
+ fifo.remove(foundEntry);
}
/**
@@ -110,7 +193,27 @@ public class BufMgr {
*/
public void unpinPage(PageId pageno, boolean dirty)
throws HashEntryNotFoundException, PageUnpinnedException {
- //YOUR CODE HERE
+ Integer foundEntry = hashTable.get(pageno.pid);
+
+ if (foundEntry != null) {
+ FrameDescriptor desc = bufDescr[foundEntry];
+
+ if (dirty) {
+ desc.DirtyBit = true;
+ }
+
+ if (desc.PinCount > 0) {
+ desc.PinCount--;
+ if (desc.PinCount == 0) {
+ fifo.offer(foundEntry);
+ }
+ } else {
+ throw new PageUnpinnedException("Pin count for Page ID " + pageno.pid + " is " + desc.PinCount);
+ }
+
+ } else {
+ throw new HashEntryNotFoundException("Could not fine Page ID: " + pageno.pid);
+ }
}
/**
@@ -127,7 +230,30 @@ 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
+// if (!isFull) {
+ PageId pageId = null;
+
+ try {
+ pageId = Minibase.DiskManager.allocate_page(howmany);
+ } catch (BufMgrException e) {
+ throw new DiskMgrException(e.getMessage());
+ }
+
+ try {
+ pinPage(pageId, firstpage, false);
+ return pageId;
+ } catch (BufferPoolExceededException e) {
+ try {
+ Minibase.DiskManager.deallocate_page(pageId, howmany);
+ } catch (BufMgrException e1) {
+ throw new DiskMgrException(e1.getMessage());
+ }
+
+ throw new BufferPoolExceededException(e.getMessage());
+ }
+// } else {
+// throw new BufferPoolExceededException("Pool is full, cannot hold anymore pages");
+// }
}
/**
@@ -151,6 +277,18 @@ public class BufMgr {
hashTable.remove(globalPageId.pid);
resetFrameDescriptor(frameId);
}
+
+ if (isFull) {
+ isFull = false;
+ }
+
+ if (nextIndex > 0) {
+ int move = nextIndex;
+ nextIndex--;
+
+ fifo.remove(hashTable.get(globalPageId.pid));
+ }
+
// then delete from disk
try {
Minibase.DiskManager.deallocate_page(globalPageId);