/** * Add a page to the free list. * * @param pageId the page id to add */ void free(int pageId) { full = false; store.logUndo(this, data); used.clear(pageId - getPos()); store.update(this); }
private void updateRowCount(int offset) { if (rowCount != UNKNOWN_ROWCOUNT) { rowCount += offset; } if (rowCountStored != UNKNOWN_ROWCOUNT) { rowCountStored = UNKNOWN_ROWCOUNT; index.getPageStore().logUndo(this, data); if (written) { writeHead(); } index.getPageStore().update(this); } }
@Override protected void remapChildren(int old) { if (firstOverflowPageId == 0) { return; } PageDataOverflow overflow = index.getPageOverflow(firstOverflowPageId); overflow.setParentPageId(getPos()); index.getPageStore().update(overflow); }
@Override protected void remapChildren(int old) { for (int i = 0; i < entryCount + 1; i++) { int child = childPageIds[i]; PageData p = index.getPage(child, old); p.setParentPageId(getPos()); index.getPageStore().update(p); } }
@Override protected void remapChildren() { for (int i = 0; i < entryCount + 1; i++) { int child = childPageIds[i]; PageBtree p = index.getPage(child); p.setParentPageId(getPos()); index.getPageStore().update(p); } }
private void updateRowCount(int offset) { if (rowCount != UNKNOWN_ROWCOUNT) { rowCount += offset; } if (rowCountStored != UNKNOWN_ROWCOUNT) { rowCountStored = UNKNOWN_ROWCOUNT; index.getPageStore().logUndo(this, data); if (written) { writeHead(); } index.getPageStore().update(this); } }
/** * Mark a page as used. * * @param pageId the page id */ void allocate(int pageId) { int idx = pageId - getPos(); if (idx >= 0 && !used.get(idx)) { // set the bit first, because logUndo can // allocate other pages, and we must not // return the same page twice used.set(idx); store.logUndo(this, data); store.update(this); } }
private void removeAllRows() { try { PageBtree root = getPage(rootPageId); root.freeRecursive(); root = PageBtreeLeaf.create(this, rootPageId, PageBtree.ROOT); store.removeFromCache(rootPageId); store.update(root); rowCount = 0; } finally { store.incrementChangeCount(); } }
/** * Read the given page. * * @param id the page id * @return the page */ PageBtree getPage(int id) { Page p = store.getPage(id); if (p == null) { PageBtreeLeaf empty = PageBtreeLeaf.create(this, id, PageBtree.ROOT); // could have been created before, but never committed store.logUndo(empty, null); store.update(empty); return empty; } else if (!(p instanceof PageBtree)) { throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "" + p); } return (PageBtree) p; }
private void removeAllRows() { try { PageData root = getPage(rootPageId, 0); root.freeRecursive(); root = PageDataLeaf.create(this, rootPageId, PageData.ROOT); store.removeFromCache(rootPageId); store.update(root); rowCount = 0; lastKey = 0; } finally { store.incrementChangeCount(); } }
@Override void setRowCountStored(int rowCount) { this.rowCount = rowCount; if (rowCountStored != rowCount) { rowCountStored = rowCount; index.getPageStore().logUndo(this, data); if (written) { changeCount = index.getPageStore().getChangeCount(); writeHead(); } index.getPageStore().update(this); } }
@Override void setRowCountStored(int rowCount) { if (rowCount < 0 && pageStoreInternalCount) { return; } this.rowCount = rowCount; if (rowCountStored != rowCount) { rowCountStored = rowCount; index.getPageStore().logUndo(this, data); if (written) { changeCount = index.getPageStore().getChangeCount(); writeHead(); } index.getPageStore().update(this); } }
/** * One of the children has moved to another page. * * @param oldPos the old position * @param newPos the new position */ void moveChild(int oldPos, int newPos) { for (int i = 0; i < entryCount + 1; i++) { if (childPageIds[i] == oldPos) { index.getPageStore().logUndo(this, data); written = false; changeCount = index.getPageStore().getChangeCount(); childPageIds[i] = newPos; index.getPageStore().update(this); return; } } throw DbException.throwInternalError(oldPos + " " + newPos); }
/** * One of the children has moved to a new page. * * @param oldPos the old position * @param newPos the new position */ void moveChild(int oldPos, int newPos) { for (int i = 0; i < entryCount + 1; i++) { if (childPageIds[i] == oldPos) { index.getPageStore().logUndo(this, data); written = false; changeCount = index.getPageStore().getChangeCount(); childPageIds[i] = newPos; index.getPageStore().update(this); return; } } throw DbException.throwInternalError(oldPos + " " + newPos); }
@Override int addRowTry(Row row) { index.getPageStore().logUndo(this, data); int keyOffsetPairLen = 4 + Data.getVarLongLen(row.getKey()); while (true) { int x = find(row.getKey()); PageData page = index.getPage(childPageIds[x], getPos()); int splitPoint = page.addRowTry(row); if (splitPoint == -1) { break; } if (length + keyOffsetPairLen > index.getPageStore().getPageSize()) { return entryCount / 2; } long pivot = splitPoint == 0 ? row.getKey() : page.getKey(splitPoint - 1); PageData page2 = page.split(splitPoint); index.getPageStore().update(page); index.getPageStore().update(page2); addChild(x, page2.getPos(), pivot); index.getPageStore().update(this); } updateRowCount(1); return -1; }
@Override boolean remove(long key) { int i = find(key); if (keys == null || keys[i] != key) { throw DbException.get(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, index.getSQL() + ": " + key + " " + (keys == null ? -1 : keys[i])); } index.getPageStore().logUndo(this, data); if (entryCount == 1) { freeRecursive(); return true; } removeRow(i); index.getPageStore().update(this); return false; }
/** * Set the overflow page id. * * @param old the old overflow page id * @param overflow the new overflow page id */ void setOverflow(int old, int overflow) { if (SysProperties.CHECK && old != firstOverflowPageId) { DbException.throwInternalError("move " + this + " " + firstOverflowPageId); } index.getPageStore().logUndo(this, data); firstOverflowPageId = overflow; if (written) { changeCount = index.getPageStore().getChangeCount(); writeHead(); data.writeInt(firstOverflowPageId); } index.getPageStore().update(this); }
@Override public void moveTo(Session session, int newPos) { PageStore store = index.getPageStore(); readAllRows(); PageBtreeLeaf p2 = PageBtreeLeaf.create(index, newPos, parentPageId); store.logUndo(this, data); store.logUndo(p2, null); p2.rows = rows; p2.entryCount = entryCount; p2.offsets = offsets; p2.onlyPosition = onlyPosition; p2.parentPageId = parentPageId; p2.start = start; store.update(p2); if (parentPageId == ROOT) { index.setRootPageId(session, newPos); } else { PageBtreeNode p = (PageBtreeNode) store.getPage(parentPageId); p.moveChild(getPos(), newPos); } store.free(getPos()); }
@Override boolean remove(long key) { int at = find(key); // merge is not implemented to allow concurrent usage // TODO maybe implement merge PageData page = index.getPage(childPageIds[at], getPos()); boolean empty = page.remove(key); index.getPageStore().logUndo(this, data); updateRowCount(-1); if (!empty) { // the first row didn't change - nothing to do return false; } // this child is now empty index.getPageStore().free(page.getPos()); if (entryCount < 1) { // no more children - this page is empty as well return true; } removeChild(at); index.getPageStore().update(this); return false; }
@Override SearchRow remove(SearchRow row) { int at = find(row, false, false, true); SearchRow delete = getRow(at); if (index.compareRows(row, delete) != 0 || delete.getKey() != row.getKey()) { throw DbException.get(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, index.getSQL() + ": " + row); } index.getPageStore().logUndo(this, data); if (entryCount == 1) { // the page is now empty return row; } removeRow(at); memoryChange(); index.getPageStore().update(this); if (at == entryCount) { // the last row changed return getRow(at - 1); } // the last row didn't change return null; }