/** * If the given name already denotes a file, this opens it; otherwise, this creates a new empty * file. A null name produces a temporary heap file which requires no DB entry. */ public HeapFile(String name) throws ChainException { this.name = name; PageId firstPageId; Page page = new Page(); pages = new ArrayList<PageId>(); pids = new HashSet<Integer>(); if (name == null) { // Temporary heap file firstPageId = global.Minibase.BufferManager.newPage(page, 1); current = new HFPage(page); current.setCurPage(firstPageId); pages.add(firstPageId); pids.add(firstPageId.pid); global.Minibase.BufferManager.unpinPage(firstPageId, true); } else { firstPageId = global.Minibase.DiskManager.get_file_entry(name); if (firstPageId == null) { firstPageId = global.Minibase.BufferManager.newPage(page, 1); global.Minibase.DiskManager.add_file_entry(name, firstPageId); global.Minibase.BufferManager.unpinPage(firstPageId, true); pages.add(firstPageId); pids.add(firstPageId.pid); global.Minibase.BufferManager.pinPage(firstPageId, page, false); recordNumber = 0; current = new HFPage(page); current.setCurPage(firstPageId); global.Minibase.BufferManager.unpinPage(firstPageId, true); return; } // add the new HFPages global.Minibase.BufferManager.pinPage(firstPageId, page, false); // System.err.println("hahahaha"+page.getData()); current = new HFPage(page); current.setData(page.getData()); pages.add(firstPageId); pids.add(firstPageId.pid); recordNumber += amount(current); global.Minibase.BufferManager.unpinPage(firstPageId, false); PageId currentPageId = current.getNextPage(); while (currentPageId.pid != 0 & currentPageId.pid != -1) { HFPage temp = new HFPage(); global.Minibase.BufferManager.pinPage(currentPageId, temp, false); pages.add(currentPageId); pids.add(currentPageId.pid); recordNumber += amount(temp); global.Minibase.BufferManager.unpinPage(currentPageId, false); currentPageId = temp.getNextPage(); } } }
/** * Deletes the heap file from the database, freeing all of its pages. * * @throws ChainException */ public void deleteFile() throws ChainException { if (delete) throw new ChainException(null, "files have already been deleted"); for (int i = 0; i < pages.size(); i++) try { global.Minibase.DiskManager.deallocate_page(pages.get(i)); } catch (Exception e) { throw new ChainException(null, "fail to deallocate page"); } global.Minibase.DiskManager.delete_file_entry(name); pages = null; pids = null; recordNumber = 0; delete = true; }