@Override public long getDiskSpaceUsed() { PageData root = getPage(rootPageId, 0); return root.getDiskSpaceUsed(); }
@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); } }
PageDataLeaf getNextPage() { if (parentPageId == PageData.ROOT) { return null; } PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1); return next.getNextPage(keys[entryCount - 1]); }
@Override void freeRecursive() { index.getPageStore().logUndo(this, data); index.getPageStore().free(getPos()); for (int i = 0; i < entryCount + 1; i++) { int child = childPageIds[i]; index.getPage(child, getPos()).freeRecursive(); } }
/** * Get the row with the given key. * * @param key the key * @return the row */ public Row getRowWithKey(long key) { PageData root = getPage(rootPageId, 0); return root.getRowWithKey(key); }
@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; }
private void invalidateRowCount() { PageData root = getPage(rootPageId, 0); root.setRowCountStored(PageData.UNKNOWN_ROWCOUNT); }
@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; }
/** * Search for a specific row or a set of rows. * * @param session the session * @param first the key of the first row * @param last the key of the last row * @param multiVersion if mvcc should be used * @return the cursor */ Cursor find(Session session, long first, long last, boolean multiVersion) { PageData root = getPage(rootPageId, 0); return root.find(session, first, last, multiVersion); }
long getLastKey() { PageData root = getPage(rootPageId, 0); return root.getLastKey(); }
@Override PageDataLeaf getFirstLeaf() { int child = childPageIds[0]; return index.getPage(child, getPos()).getFirstLeaf(); }
@Override long getLastKey() { return index.getPage(childPageIds[entryCount], getPos()).getLastKey(); }
/** * Get the next leaf page. * * @param key the last key of the current page * @return the next leaf page */ PageDataLeaf getNextPage(long key) { int i = find(key) + 1; if (i > entryCount) { if (parentPageId == PageData.ROOT) { return null; } PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1); return next.getNextPage(key); } PageData page = index.getPage(childPageIds[i], getPos()); return page.getFirstLeaf(); }
@Override Cursor find(Session session, long minKey, long maxKey, boolean multiVersion) { int x = find(minKey); int child = childPageIds[x]; return index.getPage(child, getPos()).find(session, minKey, maxKey, multiVersion); }
@Override Row getRowWithKey(long key) { int at = find(key); PageData page = index.getPage(childPageIds[at], getPos()); return page.getRowWithKey(key); }
@Override public Cursor find(Session session, SearchRow first, SearchRow last) { long from = first == null ? Long.MIN_VALUE : first.getKey(); long to = last == null ? Long.MAX_VALUE : last.getKey(); PageData root = getPage(rootPageId, 0); return root.find(session, from, to, isMultiVersion); }
@Override public void writeRowCount() { if (SysProperties.MODIFY_ON_WRITE && rootPageId == 0) { // currently creating the index return; } try { PageData root = getPage(rootPageId, 0); root.setRowCountStored(MathUtils.convertLongToInt(rowCount)); } finally { store.incrementChangeCount(); } }
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 long getDiskSpaceUsed() { long count = 0; for (int i = 0; i < entryCount + 1; i++) { int child = childPageIds[i]; PageData page = index.getPage(child, getPos()); if (getPos() == page.getPos()) { throw DbException.throwInternalError("Page is its own child: " + getPos()); } count += page.getDiskSpaceUsed(); index.getDatabase().setProgress(DatabaseEventListener.STATE_SCAN_FILE, index.getTable() + "." + index.getName(), (int) (count >> 16), Integer.MAX_VALUE); } return count; }
@Override int getRowCount() { if (rowCount == UNKNOWN_ROWCOUNT) { int count = 0; for (int i = 0; i < entryCount + 1; i++) { int child = childPageIds[i]; PageData page = index.getPage(child, getPos()); if (getPos() == page.getPos()) { throw DbException.throwInternalError("Page is its own child: " + getPos()); } count += page.getRowCount(); index.getDatabase().setProgress(DatabaseEventListener.STATE_SCAN_FILE, index.getTable() + "." + index.getName(), count, Integer.MAX_VALUE); } rowCount = count; } return rowCount; }