/** * Prints all leaf pages * * @param currentPageId * @param keyType * @throws IOException * @throws ConstructPageException * @throws IteratorException * @throws InvalidFrameNumberException * @throws HashEntryNotFoundException * @throws PageUnpinnedException * @throws ReplacerException */ private static void _printAllLeafPages(PageID currentPageId, int keyType) throws IOException, ConstructPageException, IteratorException, InvalidFrameNumberException, HashEntryNotFoundException, PageUnpinnedException, ReplacerException { BTSortedPage sortedPage = new BTSortedPage(currentPageId, keyType); if (sortedPage.getType() == NodeType.INDEX) { BTIndexPage indexPage = new BTIndexPage((Page) sortedPage, keyType); _printAllLeafPages(indexPage.getPrevPage(), keyType); TID genid = new TID(); for (KeyDataEntry entry = indexPage.getFirst(genid); entry != null; entry = indexPage.getNext(genid)) { _printAllLeafPages(((IndexData) entry.data).getData(), keyType); } } if (sortedPage.getType() == NodeType.LEAF) { printPage(currentPageId, keyType); } SystemDefs.JavabaseBM.unpinPage(currentPageId, true /*dirty*/); }
/** * Prints tree * * @param currentPageId * @param prefix * @param i * @param keyType * @throws IOException * @throws ConstructPageException * @throws IteratorException * @throws HashEntryNotFoundException * @throws InvalidFrameNumberException * @throws PageUnpinnedException * @throws ReplacerException */ private static void _printTree(PageID currentPageId, String prefix, int i, int keyType) throws IOException, ConstructPageException, IteratorException, HashEntryNotFoundException, InvalidFrameNumberException, PageUnpinnedException, ReplacerException { BTSortedPage sortedPage = new BTSortedPage(currentPageId, keyType); prefix = prefix + " "; i++; if (sortedPage.getType() == NodeType.INDEX) { BTIndexPage indexPage = new BTIndexPage((Page) sortedPage, keyType); System.out.println(i + prefix + indexPage.getPrevPage()); _printTree(indexPage.getPrevPage(), prefix, i, keyType); TID genid = new TID(); for (KeyDataEntry entry = indexPage.getFirst(genid); entry != null; entry = indexPage.getNext(genid)) { System.out.println(i + prefix + (IndexData) entry.data); _printTree(((IndexData) entry.data).getData(), prefix, i, keyType); } } SystemDefs.JavabaseBM.unpinPage(currentPageId, true /*dirty*/); }
/** * used for debug: to print a page out. The page is either BTIndexPage, or BTLeafPage. * * @param pageno the number of page. Input parameter. * @param keyType It specifies the type of key. It can be AttrType.attrString or * AttrType.attrInteger. Input parameter. * @exception IOException error from the lower layer * @exception IteratorException error for iterator * @exception ConstructPageException error for BT page constructor * @exception HashEntryNotFoundException error from the lower layer * @exception ReplacerException error from the lower layer * @exception PageUnpinnedException error from the lower layer * @exception InvalidFrameNumberException error from the lower layer */ public static void printPage(PageID pageno, int keyType) throws IOException, IteratorException, ConstructPageException, HashEntryNotFoundException, ReplacerException, PageUnpinnedException, InvalidFrameNumberException { BTSortedPage sortedPage = new BTSortedPage(pageno, keyType); int i; i = 0; if (sortedPage.getType() == NodeType.INDEX) { BTIndexPage indexPage = new BTIndexPage((Page) sortedPage, keyType); System.out.println(""); System.out.println("**************To Print an Index Page ********"); System.out.println("Current Page ID: " + indexPage.getCurPage().pid); System.out.println("Left Link : " + indexPage.getLeftLink().pid); TID genid = new TID(); for (KeyDataEntry entry = indexPage.getFirst(genid); entry != null; entry = indexPage.getNext(genid)) { if (keyType == AttrType.attrInteger) System.out.println( i + " (key, pageId): (" + (IntegerKey) entry.key + ", " + (IndexData) entry.data + " )"); if (keyType == AttrType.attrString) System.out.println( i + " (key, pageId): (" + (StringKey) entry.key + ", " + (IndexData) entry.data + " )"); i++; } System.out.println("************** END ********"); System.out.println(""); } else if (sortedPage.getType() == NodeType.LEAF) { BTLeafPage leafPage = new BTLeafPage((Page) sortedPage, keyType); System.out.println(""); System.out.println("**************To Print an Leaf Page ********"); System.out.println("Current Page ID: " + leafPage.getCurPage().pid); System.out.println("Left Link : " + leafPage.getPrevPage().pid); System.out.println("Right Link : " + leafPage.getNextPage().pid); TID genid = new TID(); for (KeyDataEntry entry = leafPage.getFirst(genid); entry != null; entry = leafPage.getNext(genid)) { if (keyType == AttrType.attrInteger) System.out.println( i + " (key, [pageNo, slotNo]): (" + (IntegerKey) entry.key + ", " + (LeafData) entry.data + " )"); if (keyType == AttrType.attrString) System.out.println( i + " (key, [pageNo, slotNo]): (" + (StringKey) entry.key + ", " + (LeafData) entry.data); i++; } System.out.println("************** END ********"); System.out.println(""); } else { System.out.println("Sorry!!! This page is neither Index nor Leaf page."); } SystemDefs.JavabaseBM.unpinPage(pageno, true /*dirty*/); }
/** * overrides the test4 function in TestDriver * * @return whether test4 has passed */ protected boolean test4() { System.out.print("\n Test 4 exercises some of the internals " + "of the buffer manager\n"); int index; int numPages = NUMBUF + 10; Page pg = new Page(); PageId pid = new PageId(); PageId[] pids = new PageId[numPages]; boolean status = OK; System.out.print(" - Allocate bunch of pages together \n"); for (int i = 0; i < numPages / NUMBUF; i++) { for (index = i * NUMBUF; status == OK && index < (i + 1) * NUMBUF; ++index) { pg = new Page(); try { pid = SystemDefs.JavabaseBM.newPage(pg, 1); } catch (Exception e) { status = FAIL; System.err.print("*** Could not allocate new page number " + index + 1 + "\n"); e.printStackTrace(); } if (status == OK) { pids[index] = pid; } if (status == OK) { // Copy the page number + 99999 onto each page. It seems // unlikely that this bit pattern would show up there by // coincidence. int data = pid.pid + 99999; try { Convert.setIntValue(data, 0, pg.getpage()); } catch (IOException e) { System.err.print("*** Convert value failed\n"); status = FAIL; e.printStackTrace(); } } } for (index = i * NUMBUF; status == OK && index < (i + 1) * NUMBUF; ++index) { try { SystemDefs.JavabaseBM.unpinPage(pids[index], true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin page " + pids[index].pid + "\n"); e.printStackTrace(); } } } if (status == OK) { System.out.print(" - Read the pages\n"); for (int i = 0; i < numPages / NUMBUF; i++) { for (index = i * NUMBUF; status == OK && index < (i + 1) * NUMBUF; ++index) { pg = new Page(); pid = pids[index]; try { SystemDefs.JavabaseBM.pinPage(pid, pg, false); } catch (Exception e) { status = FAIL; System.err.print("*** Could not pin page " + pid.pid + "\n"); e.printStackTrace(); } if (status == OK) { int data = 0; try { data = Convert.getIntValue(0, pg.getpage()); } catch (IOException e) { System.err.print("*** Convert value failed \n"); status = FAIL; } if (data != pid.pid + 99999) { status = FAIL; System.err.print("*** Read wrong data back from page " + pid.pid + "\n"); } } } for (index = i * NUMBUF; status == OK && index < (i + 1) * NUMBUF; ++index) { try { SystemDefs.JavabaseBM.unpinPage(pids[index], true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin page " + pids[index].pid + "\n"); e.printStackTrace(); } } } } if (status == OK) { System.out.print(" Test 4 completed successfully.\n"); } return status; }
/** * overrides the test3 function in TestDriver. It exercises some of the internal of the buffer * manager * * @return whether test3 has passed */ protected boolean test3() { System.out.print("\n Test 3 exercises some of the internals " + "of the buffer manager\n"); int index; int numPages = NUMBUF + 10; Page pg = new Page(); PageId pid = new PageId(); PageId[] pids = new PageId[numPages]; boolean status = OK; System.out.print( " - Allocate and dirty some new pages, one at " + "a time, and leave some pinned\n"); for (index = 0; status == OK && index < numPages; ++index) { try { pid = SystemDefs.JavabaseBM.newPage(pg, 1); } catch (Exception e) { status = FAIL; System.err.print("*** Could not allocate new page number " + index + 1 + "\n"); e.printStackTrace(); } if (status == OK) pids[index] = pid; if (status == OK) { // Copy the page number + 99999 onto each page. It seems // unlikely that this bit pattern would show up there by // coincidence. int data = pid.pid + 99999; try { Convert.setIntValue(data, 0, pg.getpage()); } catch (IOException e) { System.err.print("*** Convert value failed\n"); status = FAIL; e.printStackTrace(); } // Leave the page pinned if it equals 12 mod 20. This is a // random number based loosely on a bug report. if (status == OK) { if (pid.pid % 20 != 12) { try { SystemDefs.JavabaseBM.unpinPage(pid, /*dirty:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin dirty page " + pid.pid + "\n"); } } } } } if (status == OK) { System.out.print(" - Read the pages\n"); for (index = 0; status == OK && index < numPages; ++index) { pid = pids[index]; try { SystemDefs.JavabaseBM.pinPage(pid, pg, false); } catch (Exception e) { status = FAIL; System.err.print("*** Could not pin page " + pid.pid + "\n"); e.printStackTrace(); } if (status == OK) { int data = 0; try { data = Convert.getIntValue(0, pg.getpage()); } catch (IOException e) { System.err.print("*** Convert value failed \n"); status = FAIL; } if (data != pid.pid + 99999) { status = FAIL; System.err.print("*** Read wrong data back from page " + pid.pid + "\n"); } } if (status == OK) { try { SystemDefs.JavabaseBM.unpinPage(pid, true); // might not be dirty } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin page " + pid.pid + "\n"); e.printStackTrace(); } } if (status == OK && (pid.pid % 20 == 12)) { try { SystemDefs.JavabaseBM.unpinPage(pid, /*dirty:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin page " + pid.pid + "\n"); e.printStackTrace(); } } } } if (status == OK) System.out.print(" Test 3 completed successfully.\n"); return status; }
/** * overrides the test2 function in TestDriver. It tests whether illeagal operation can be caught. * * @return whether test2 has passed */ protected boolean test2() { System.out.print("\n Test 2 exercises some illegal buffer " + "manager operations:\n"); // We choose this number to ensure that pinning this number of buffers // should fail. int numPages = SystemDefs.JavabaseBM.getNumUnpinnedBuffers() + 1; Page pg = new Page(); PageId pid, lastPid; PageId firstPid = new PageId(); boolean status = OK; System.out.print(" - Try to pin more pages than there are frames\n"); try { firstPid = SystemDefs.JavabaseBM.newPage(pg, numPages); } catch (Exception e) { System.err.print("*** Could not allocate " + numPages); System.err.print(" new pages in the database.\n"); e.printStackTrace(); return false; } pid = new PageId(); lastPid = new PageId(); // First pin enough pages that there is no more room. for (pid.pid = firstPid.pid + 1, lastPid.pid = firstPid.pid + numPages - 1; status == OK && pid.pid < lastPid.pid; pid.pid = pid.pid + 1) { try { SystemDefs.JavabaseBM.pinPage(pid, pg, /*emptyPage:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not pin new page " + pid.pid + "\n"); e.printStackTrace(); } } // Make sure the buffer manager thinks there's no more room. if (status == OK && SystemDefs.JavabaseBM.getNumUnpinnedBuffers() != 0) { status = FAIL; System.err.print( "*** The buffer manager thinks it has " + SystemDefs.JavabaseBM.getNumUnpinnedBuffers() + " available frames,\n" + " but it should have none.\n"); } // Now pin that last page, and make sure it fails. if (status == OK) { try { SystemDefs.JavabaseBM.pinPage(lastPid, pg, /*emptyPage:*/ true); } catch (ChainException e) { status = checkException(e, "bufmgr.BufferPoolExceededException"); if (status == FAIL) { System.err.print("*** Pinning too many pages\n"); System.out.println(" --> Failed as expected \n"); } } catch (Exception e) { e.printStackTrace(); } if (status == OK) { status = FAIL; System.err.print("The expected exception was not thrown\n"); } else { status = OK; } } if (status == OK) { try { SystemDefs.JavabaseBM.pinPage(firstPid, pg, /*emptyPage:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not acquire a second pin on a page\n"); e.printStackTrace(); } if (status == OK) { System.out.print(" - Try to free a doubly-pinned page\n"); try { SystemDefs.JavabaseBM.freePage(firstPid); } catch (ChainException e) { status = checkException(e, "bufmgr.PagePinnedException"); if (status == FAIL) { System.err.print("*** Freeing a pinned page\n"); System.out.println(" --> Failed as expected \n"); } } catch (Exception e) { e.printStackTrace(); } if (status == OK) { status = FAIL; System.err.print("The expected exception was not thrown\n"); } else { status = OK; } } if (status == OK) { try { SystemDefs.JavabaseBM.unpinPage(firstPid, false); } catch (Exception e) { status = FAIL; e.printStackTrace(); } } } if (status == OK) { System.out.print(" - Try to unpin a page not in the buffer pool\n"); try { SystemDefs.JavabaseBM.unpinPage(lastPid, false); } catch (ChainException e) { status = checkException(e, "bufmgr.HashEntryNotFoundException"); if (status == FAIL) { System.err.print("*** Unpinning a page not in the buffer pool\n"); System.out.println(" --> Failed as expected \n"); } } catch (Exception e) { e.printStackTrace(); } if (status == OK) { status = FAIL; System.err.print("The expected exception was not thrown\n"); } else { status = OK; } } for (pid.pid = firstPid.pid; pid.pid <= lastPid.pid; pid.pid = pid.pid + 1) { try { SystemDefs.JavabaseBM.freePage(pid); } catch (Exception e) { status = FAIL; System.err.print("*** Error freeing page " + pid.pid + "\n"); e.printStackTrace(); } } if (status == OK) System.out.print(" Test 2 completed successfully.\n"); return status; }
/** * overrides the test1 function in TestDriver. It tests some simple normal buffer manager * operations. * * @return whether test1 has passed */ protected boolean test1() { System.out.print("\n Test 1 does a simple test of normal buffer "); System.out.print("manager operations:\n"); // We choose this number to ensure that at least one page will have to be // written during this test. boolean status = OK; int numPages = SystemDefs.JavabaseBM.getNumUnpinnedBuffers() + 1; Page pg = new Page(); PageId pid; PageId lastPid; PageId firstPid = new PageId(); System.out.print(" - Allocate a bunch of new pages\n"); try { firstPid = SystemDefs.JavabaseBM.newPage(pg, numPages); } catch (Exception e) { System.err.print("*** Could not allocate " + numPages); System.err.print(" new pages in the database.\n"); e.printStackTrace(); return false; } // Unpin that first page... to simplify our loop. try { SystemDefs.JavabaseBM.unpinPage(firstPid, false /*not dirty*/); } catch (Exception e) { System.err.print("*** Could not unpin the first new page.\n"); e.printStackTrace(); status = FAIL; } System.out.print(" - Write something on each one\n"); pid = new PageId(); lastPid = new PageId(); for (pid.pid = firstPid.pid, lastPid.pid = pid.pid + numPages; status == OK && pid.pid < lastPid.pid; pid.pid = pid.pid + 1) { try { SystemDefs.JavabaseBM.pinPage(pid, pg, /*emptyPage:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not pin new page " + pid.pid + "\n"); e.printStackTrace(); } if (status == OK) { // Copy the page number + 99999 onto each page. It seems // unlikely that this bit pattern would show up there by // coincidence. int data = pid.pid + 99999; try { Convert.setIntValue(data, 0, pg.getpage()); } catch (IOException e) { System.err.print("*** Convert value failed\n"); status = FAIL; } if (status == OK) { try { SystemDefs.JavabaseBM.unpinPage(pid, /*dirty:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin dirty page " + pid.pid + "\n"); e.printStackTrace(); } } } } if (status == OK) System.out.print( " - Read that something back from each one\n" + " (because we're buffering, this is where " + "most of the writes happen)\n"); for (pid.pid = firstPid.pid; status == OK && pid.pid < lastPid.pid; pid.pid = pid.pid + 1) { try { SystemDefs.JavabaseBM.pinPage(pid, pg, /*emptyPage:*/ false); } catch (Exception e) { status = FAIL; System.err.print("*** Could not pin page " + pid.pid + "\n"); e.printStackTrace(); } if (status == OK) { int data = 0; try { data = Convert.getIntValue(0, pg.getpage()); } catch (IOException e) { System.err.print("*** Convert value failed \n"); status = FAIL; } if (status == OK) { if (data != (pid.pid) + 99999) { status = FAIL; System.err.print("*** Read wrong data back from page " + pid.pid + "\n"); } } if (status == OK) { try { SystemDefs.JavabaseBM.unpinPage(pid, /*dirty:*/ true); } catch (Exception e) { status = FAIL; System.err.print("*** Could not unpin page " + pid.pid + "\n"); e.printStackTrace(); } } } } if (status == OK) System.out.print(" - Free the pages again\n"); for (pid.pid = firstPid.pid; pid.pid < lastPid.pid; pid.pid = pid.pid + 1) { try { SystemDefs.JavabaseBM.freePage(pid); } catch (Exception e) { status = FAIL; System.err.print("*** Error freeing page " + pid.pid + "\n"); e.printStackTrace(); } } if (status == OK) System.out.print(" Test 1 completed successfully.\n"); return status; }