提交 1944438b authored 作者: Thomas Mueller's avatar Thomas Mueller

Page store: automatically compact the database (work in progress)

上级 d220c5d3
...@@ -1238,6 +1238,8 @@ public class Database implements DataHandler { ...@@ -1238,6 +1238,8 @@ public class Database implements DataHandler {
pageStore.checkpoint(); pageStore.checkpoint();
pageStore.trim(); pageStore.trim();
} catch (Throwable e) { } catch (Throwable e) {
int test;
// e.printStackTrace(System.out);
traceSystem.getTrace(Trace.DATABASE).error("close", e); traceSystem.getTrace(Trace.DATABASE).error("close", e);
} }
} }
......
...@@ -27,11 +27,10 @@ import org.h2.value.ValueNull; ...@@ -27,11 +27,10 @@ import org.h2.value.ValueNull;
* This is the most common type of index, a b tree index. * This is the most common type of index, a b tree index.
* Only the data of the indexed columns are stored in the index. * Only the data of the indexed columns are stored in the index.
*/ */
public class PageBtreeIndex extends BaseIndex { public class PageBtreeIndex extends PageIndex {
private PageStore store; private PageStore store;
private TableData tableData; private TableData tableData;
private final int headPos;
private boolean needRebuild; private boolean needRebuild;
private long rowCount; private long rowCount;
...@@ -41,25 +40,24 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -41,25 +40,24 @@ public class PageBtreeIndex extends BaseIndex {
// trace.setLevel(TraceSystem.DEBUG); // trace.setLevel(TraceSystem.DEBUG);
tableData = table; tableData = table;
if (!database.isPersistent() || id < 0) { if (!database.isPersistent() || id < 0) {
this.headPos = 0;
throw Message.throwInternalError("" + indexName); throw Message.throwInternalError("" + indexName);
} }
this.store = database.getPageStore(); this.store = database.getPageStore();
store.addIndex(this); store.addIndex(this);
if (headPos == Index.EMPTY_HEAD) { if (headPos == Index.EMPTY_HEAD) {
// new index // new index
rootPageId = store.allocatePage();
needRebuild = true; needRebuild = true;
this.headPos = headPos = store.allocatePage();
// TODO currently the head position is stored in the log // TODO currently the head position is stored in the log
// it should not for new tables, otherwise redo of other operations // it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things // must ensure this page is not used for other things
store.addMeta(this, session, headPos); store.addMeta(this, session);
PageBtreeLeaf root = new PageBtreeLeaf(this, headPos, store.createData()); PageBtreeLeaf root = new PageBtreeLeaf(this, rootPageId, store.createData());
root.parentPageId = PageBtree.ROOT; root.parentPageId = PageBtree.ROOT;
store.updateRecord(root, true, root.data); store.updateRecord(root, true, root.data);
} else { } else {
this.headPos = headPos; rootPageId = store.getRootPageId(this);
PageBtree root = getPage(headPos); PageBtree root = getPage(rootPageId);
rowCount = root.getRowCount(); rowCount = root.getRowCount();
if (rowCount == 0 && store.isRecoveryRunning()) { if (rowCount == 0 && store.isRecoveryRunning()) {
needRebuild = true; needRebuild = true;
...@@ -75,10 +73,6 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -75,10 +73,6 @@ public class PageBtreeIndex extends BaseIndex {
} }
} }
public int getHeadPos() {
return headPos;
}
public void add(Session session, Row row) throws SQLException { public void add(Session session, Row row) throws SQLException {
if (trace.isDebugEnabled()) { if (trace.isDebugEnabled()) {
trace.debug("add " + row.getPos()); trace.debug("add " + row.getPos());
...@@ -86,7 +80,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -86,7 +80,7 @@ public class PageBtreeIndex extends BaseIndex {
// safe memory // safe memory
SearchRow newRow = getSearchRow(row); SearchRow newRow = getSearchRow(row);
while (true) { while (true) {
PageBtree root = getPage(headPos); PageBtree root = getPage(rootPageId);
int splitPoint = root.addRowTry(newRow); int splitPoint = root.addRowTry(newRow);
if (splitPoint == -1) { if (splitPoint == -1) {
break; break;
...@@ -100,8 +94,8 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -100,8 +94,8 @@ public class PageBtreeIndex extends BaseIndex {
int rootPageId = root.getPos(); int rootPageId = root.getPos();
int id = store.allocatePage(); int id = store.allocatePage();
page1.setPageId(id); page1.setPageId(id);
page1.setParentPageId(headPos); page1.setParentPageId(rootPageId);
page2.setParentPageId(headPos); page2.setParentPageId(rootPageId);
PageBtreeNode newRoot = new PageBtreeNode(this, rootPageId, store.createData()); PageBtreeNode newRoot = new PageBtreeNode(this, rootPageId, store.createData());
newRoot.parentPageId = PageBtree.ROOT; newRoot.parentPageId = PageBtree.ROOT;
newRoot.init(page1, pivot, page2); newRoot.init(page1, pivot, page2);
...@@ -161,7 +155,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -161,7 +155,7 @@ public class PageBtreeIndex extends BaseIndex {
if (SysProperties.CHECK && store == null) { if (SysProperties.CHECK && store == null) {
throw Message.getSQLException(ErrorCode.OBJECT_CLOSED); throw Message.getSQLException(ErrorCode.OBJECT_CLOSED);
} }
PageBtree root = getPage(headPos); PageBtree root = getPage(rootPageId);
PageBtreeCursor cursor = new PageBtreeCursor(session, this, last); PageBtreeCursor cursor = new PageBtreeCursor(session, this, last);
root.find(cursor, first, bigger); root.find(cursor, first, bigger);
return cursor; return cursor;
...@@ -180,7 +174,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -180,7 +174,7 @@ public class PageBtreeIndex extends BaseIndex {
} }
return cursor; return cursor;
} }
PageBtree root = getPage(headPos); PageBtree root = getPage(rootPageId);
PageBtreeCursor cursor = new PageBtreeCursor(session, this, null); PageBtreeCursor cursor = new PageBtreeCursor(session, this, null);
root.last(cursor); root.last(cursor);
cursor.previous(); cursor.previous();
...@@ -223,7 +217,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -223,7 +217,7 @@ public class PageBtreeIndex extends BaseIndex {
if (rowCount == 1) { if (rowCount == 1) {
removeAllRows(); removeAllRows();
} else { } else {
PageBtree root = getPage(headPos); PageBtree root = getPage(rootPageId);
root.remove(row); root.remove(row);
rowCount--; rowCount--;
} }
...@@ -234,7 +228,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -234,7 +228,7 @@ public class PageBtreeIndex extends BaseIndex {
trace.debug("remove"); trace.debug("remove");
} }
removeAllRows(); removeAllRows();
store.freePage(headPos, false, null); store.freePage(rootPageId, false, null);
store.removeMeta(this, session); store.removeMeta(this, session);
} }
...@@ -250,11 +244,11 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -250,11 +244,11 @@ public class PageBtreeIndex extends BaseIndex {
} }
private void removeAllRows() throws SQLException { private void removeAllRows() throws SQLException {
PageBtree root = getPage(headPos); PageBtree root = getPage(rootPageId);
root.freeChildren(); root.freeChildren();
root = new PageBtreeLeaf(this, headPos, store.createData()); root = new PageBtreeLeaf(this, rootPageId, store.createData());
root.parentPageId = PageBtree.ROOT; root.parentPageId = PageBtree.ROOT;
store.removeRecord(headPos); store.removeRecord(rootPageId);
store.updateRecord(root, true, null); store.updateRecord(root, true, null);
rowCount = 0; rowCount = 0;
} }
...@@ -358,4 +352,11 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -358,4 +352,11 @@ public class PageBtreeIndex extends BaseIndex {
return true; return true;
} }
public void setRootPageId(Session session, int newPos) throws SQLException {
store.removeMeta(this, session);
this.rootPageId = newPos;
store.addMeta(this, session);
store.addIndex(this);
}
} }
...@@ -9,11 +9,13 @@ package org.h2.index; ...@@ -9,11 +9,13 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.store.Data; import org.h2.store.Data;
import org.h2.store.DataPage; import org.h2.store.DataPage;
import org.h2.store.Page; import org.h2.store.Page;
import org.h2.store.PageStore;
/** /**
* A b-tree leaf page that contains index data. * A b-tree leaf page that contains index data.
...@@ -283,4 +285,24 @@ public class PageBtreeLeaf extends PageBtree { ...@@ -283,4 +285,24 @@ public class PageBtreeLeaf extends PageBtree {
return "page[" + getPos() + "] b-tree leaf table:" + index.getId() + " entries:" + entryCount; return "page[" + getPos() + "] b-tree leaf table:" + index.getId() + " entries:" + entryCount;
} }
public void moveTo(Session session, int newPos) throws SQLException {
PageStore store = index.getPageStore();
PageBtreeLeaf p2 = new PageBtreeLeaf(index, newPos, store.createData());
readAllRows();
p2.rows = rows;
p2.entryCount = entryCount;
p2.offsets = offsets;
p2.onlyPosition = onlyPosition;
p2.parentPageId = parentPageId;
p2.start = start;
store.updateRecord(p2, false, null);
if (parentPageId == ROOT) {
index.setRootPageId(session, newPos);
} else {
PageBtreeNode p = (PageBtreeNode) store.getPage(parentPageId);
p.moveChild(getPos(), newPos);
}
store.freePage(getPos(), true, data);
}
} }
...@@ -9,6 +9,7 @@ package org.h2.index; ...@@ -9,6 +9,7 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.store.Data; import org.h2.store.Data;
...@@ -477,4 +478,42 @@ public class PageBtreeNode extends PageBtree { ...@@ -477,4 +478,42 @@ public class PageBtreeNode extends PageBtree {
return "page[" + getPos() + "] b-tree node table:" + index.getId() + " entries:" + entryCount; return "page[" + getPos() + "] b-tree node table:" + index.getId() + " entries:" + entryCount;
} }
public void moveTo(Session session, int newPos) throws SQLException {
PageStore store = index.getPageStore();
PageBtreeNode p2 = new PageBtreeNode(index, newPos, store.createData());
readAllRows();
p2.childPageIds = childPageIds;
p2.rows = rows;
p2.entryCount = entryCount;
p2.offsets = offsets;
p2.onlyPosition = onlyPosition;
p2.parentPageId = parentPageId;
p2.start = start;
store.updateRecord(p2, false, null);
if (parentPageId == ROOT) {
index.setRootPageId(session, newPos);
} else {
PageBtreeNode p = (PageBtreeNode) store.getPage(parentPageId);
p.moveChild(getPos(), newPos);
}
for (int i = 0; i < childPageIds.length; i++) {
PageBtree p = (PageBtree) store.getPage(childPageIds[i]);
p.setParentPageId(newPos);
store.updateRecord(p, true, p.data);
}
store.freePage(getPos(), true, data);
}
public void moveChild(int oldPos, int newPos) throws SQLException {
for (int i = 0; i < childPageIds.length; i++) {
if (childPageIds[i] == oldPos) {
written = false;
childPageIds[i] = newPos;
index.getPageStore().updateRecord(this, true, data);
return;
}
}
throw Message.throwInternalError();
}
} }
\ No newline at end of file
...@@ -399,4 +399,24 @@ public class PageDataLeaf extends PageData { ...@@ -399,4 +399,24 @@ public class PageDataLeaf extends PageData {
return "page[" + getPos() + "] data leaf table:" + index.getId() + " entries:" + entryCount; return "page[" + getPos() + "] data leaf table:" + index.getId() + " entries:" + entryCount;
} }
public void moveTo(Session session, int newPos) throws SQLException {
// PageStore store = index.getPageStore();
// PageBtreeLeaf p2 = new PageBtreeLeaf(index, newPos, store.createData());
// readAllRows();
// p2.rows = rows;
// p2.entryCount = entryCount;
// p2.offsets = offsets;
// p2.onlyPosition = onlyPosition;
// p2.parentPageId = parentPageId;
// p2.start = start;
// store.updateRecord(p2, false, null);
// if (firstOverflowPageId != 0) {
// }
// if (parentPageId == ROOT) {
// } else {
// PageBtreeNode p = (PageBtreeNode) store.getPage(parentPageId);
// p.moveChild(getPos(), newPos);
// }
}
} }
...@@ -329,4 +329,9 @@ public class PageDataNode extends PageData { ...@@ -329,4 +329,9 @@ public class PageDataNode extends PageData {
return "page[" + getPos() + "] data node table:" + index.getId() + " entries:" + entryCount; return "page[" + getPos() + "] data node table:" + index.getId() + " entries:" + entryCount;
} }
public void moveTo(Session session, int newPos) throws SQLException {
// TODO Auto-generated method stub
}
} }
...@@ -8,6 +8,7 @@ package org.h2.index; ...@@ -8,6 +8,7 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.store.Data; import org.h2.store.Data;
import org.h2.store.DataPage; import org.h2.store.DataPage;
...@@ -180,4 +181,9 @@ public class PageDataOverflow extends Page { ...@@ -180,4 +181,9 @@ public class PageDataOverflow extends Page {
this.parentPage = parent; this.parentPage = parent;
} }
public void moveTo(Session session, int newPos) throws SQLException {
// TODO Auto-generated method stub
}
} }
/*
* Copyright 2004-2009 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.index;
/**
* A page store index.
*/
public abstract class PageIndex extends BaseIndex {
protected int rootPageId;
public int getRootPageId() {
return rootPageId;
}
public int getHeadPos() {
return 0;
}
}
...@@ -33,11 +33,10 @@ import org.h2.value.ValueLob; ...@@ -33,11 +33,10 @@ import org.h2.value.ValueLob;
* all rows of a table. Each regular table has one such object, even if no * all rows of a table. Each regular table has one such object, even if no
* primary key or indexes are defined. * primary key or indexes are defined.
*/ */
public class PageScanIndex extends BaseIndex implements RowIndex { public class PageScanIndex extends PageIndex implements RowIndex {
private PageStore store; private PageStore store;
private TableData tableData; private TableData tableData;
private final int headPos;
private int lastKey; private int lastKey;
private long rowCount; private long rowCount;
private HashSet<Row> delta; private HashSet<Row> delta;
...@@ -55,22 +54,21 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -55,22 +54,21 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
this.store = database.getPageStore(); this.store = database.getPageStore();
store.addIndex(this); store.addIndex(this);
if (!database.isPersistent()) { if (!database.isPersistent()) {
this.headPos = 0;
throw Message.throwInternalError(table.getName()); throw Message.throwInternalError(table.getName());
} }
if (headPos == Index.EMPTY_HEAD) { if (headPos == Index.EMPTY_HEAD) {
// new table // new table
this.headPos = headPos = store.allocatePage(); rootPageId = store.allocatePage();
// TODO currently the head position is stored in the log // TODO currently the head position is stored in the log
// it should not for new tables, otherwise redo of other operations // it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things // must ensure this page is not used for other things
store.addMeta(this, session, headPos); store.addMeta(this, session);
PageDataLeaf root = new PageDataLeaf(this, headPos, store.createData()); PageDataLeaf root = new PageDataLeaf(this, rootPageId, store.createData());
root.parentPageId = PageData.ROOT; root.parentPageId = PageData.ROOT;
store.updateRecord(root, true, root.data); store.updateRecord(root, true, root.data);
} else { } else {
this.headPos = headPos; rootPageId = store.getRootPageId(this);
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
lastKey = root.getLastKey(); lastKey = root.getLastKey();
rowCount = root.getRowCount(); rowCount = root.getRowCount();
// could have been created before, but never committed // could have been created before, but never committed
...@@ -86,10 +84,6 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -86,10 +84,6 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
table.setRowCount(rowCount); table.setRowCount(rowCount);
} }
public int getHeadPos() {
return headPos;
}
public void add(Session session, Row row) throws SQLException { public void add(Session session, Row row) throws SQLException {
if (row.getPos() == 0) { if (row.getPos() == 0) {
row.setPos(++lastKey); row.setPos(++lastKey);
...@@ -112,7 +106,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -112,7 +106,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
} }
while (true) { while (true) {
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
int splitPoint = root.addRowTry(row); int splitPoint = root.addRowTry(row);
if (splitPoint == -1) { if (splitPoint == -1) {
break; break;
...@@ -126,8 +120,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -126,8 +120,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
int rootPageId = root.getPos(); int rootPageId = root.getPos();
int id = store.allocatePage(); int id = store.allocatePage();
page1.setPageId(id); page1.setPageId(id);
page1.setParentPageId(headPos); page1.setParentPageId(rootPageId);
page2.setParentPageId(headPos); page2.setParentPageId(rootPageId);
PageDataNode newRoot = new PageDataNode(this, rootPageId, store.createData()); PageDataNode newRoot = new PageDataNode(this, rootPageId, store.createData());
newRoot.parentPageId = PageData.ROOT; newRoot.parentPageId = PageData.ROOT;
newRoot.init(page1, pivot, page2); newRoot.init(page1, pivot, page2);
...@@ -177,8 +171,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -177,8 +171,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
empty.parentPageId = parent; empty.parentPageId = parent;
return empty; return empty;
} }
if (p.index.headPos != headPos) { if (p.index.rootPageId != rootPageId) {
throw Message.throwInternalError("Wrong index: " + p.index.getName() + ":" + p.index.headPos + " " + getName() + ":" + headPos); throw Message.throwInternalError("Wrong index: " + p.index.getName() + ":" + p.index.rootPageId + " " + getName() + ":" + rootPageId);
} }
if (parent != -1) { if (parent != -1) {
if (p.getParentPageId() != parent) { if (p.getParentPageId() != parent) {
...@@ -193,7 +187,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -193,7 +187,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException { public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException {
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
return root.find(session); return root.find(session);
} }
...@@ -226,7 +220,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -226,7 +220,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
removeAllRows(); removeAllRows();
} else { } else {
int key = row.getPos(); int key = row.getPos();
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
root.remove(key); root.remove(key);
invalidateRowCount(); invalidateRowCount();
rowCount--; rowCount--;
...@@ -248,7 +242,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -248,7 +242,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
private void invalidateRowCount() throws SQLException { private void invalidateRowCount() throws SQLException {
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
root.setRowCountStored(PageData.UNKNOWN_ROWCOUNT); root.setRowCountStored(PageData.UNKNOWN_ROWCOUNT);
} }
...@@ -257,7 +251,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -257,7 +251,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
trace.debug("remove"); trace.debug("remove");
} }
removeAllRows(); removeAllRows();
store.freePage(headPos, false, null); store.freePage(rootPageId, false, null);
store.removeMeta(this, session); store.removeMeta(this, session);
} }
...@@ -277,11 +271,11 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -277,11 +271,11 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
private void removeAllRows() throws SQLException { private void removeAllRows() throws SQLException {
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
root.freeChildren(); root.freeChildren();
root = new PageDataLeaf(this, headPos, store.createData()); root = new PageDataLeaf(this, rootPageId, store.createData());
root.parentPageId = PageData.ROOT; root.parentPageId = PageData.ROOT;
store.removeRecord(headPos); store.removeRecord(rootPageId);
store.updateRecord(root, true, null); store.updateRecord(root, true, null);
rowCount = 0; rowCount = 0;
lastKey = 0; lastKey = 0;
...@@ -292,7 +286,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -292,7 +286,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
public Row getRow(Session session, int key) throws SQLException { public Row getRow(Session session, int key) throws SQLException {
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
return root.getRow(key); return root.getRow(key);
} }
...@@ -348,7 +342,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -348,7 +342,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
// can not close the index because it might get used afterwards, // can not close the index because it might get used afterwards,
// for example after running recovery // for example after running recovery
PageData root = getPage(headPos, 0); PageData root = getPage(rootPageId, 0);
root.setRowCountStored(MathUtils.convertLongToInt(rowCount)); root.setRowCountStored(MathUtils.convertLongToInt(rowCount));
} }
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
*/ */
package org.h2.store; package org.h2.store;
import java.sql.SQLException;
import org.h2.engine.Session;
/** /**
* A page. Format: * A page. Format:
...@@ -66,4 +69,13 @@ public abstract class Page extends Record { ...@@ -66,4 +69,13 @@ public abstract class Page extends Record {
*/ */
public static final int TYPE_STREAM_DATA = 8; public static final int TYPE_STREAM_DATA = 8;
/**
* Copy the data to a new location, change the parent to point to the new
* location, and free up the current page.
*
* @param session the session
* @param newPos the new position
*/
public abstract void moveTo(Session session, int newPos) throws SQLException;
} }
...@@ -7,6 +7,7 @@ package org.h2.store; ...@@ -7,6 +7,7 @@ package org.h2.store;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.util.BitField; import org.h2.util.BitField;
...@@ -102,7 +103,7 @@ public class PageFreeList extends Page { ...@@ -102,7 +103,7 @@ public class PageFreeList extends Page {
if (free >= pageCount) { if (free >= pageCount) {
return -1; return -1;
} }
return free; return free + getPos();
} }
int getLastUsed() { int getLastUsed() {
...@@ -197,4 +198,10 @@ public class PageFreeList extends Page { ...@@ -197,4 +198,10 @@ public class PageFreeList extends Page {
return used.get(pageId - getPos()); return used.get(pageId - getPos());
} }
public void moveTo(Session session, int newPos) throws SQLException {
// the old data does not need to be copied, as free-list pages
// at the end of the file are not required
store.freePage(getPos(), true, data);
}
} }
...@@ -258,7 +258,7 @@ public class PageLog { ...@@ -258,7 +258,7 @@ public class PageLog {
int tableId = in.readInt(); int tableId = in.readInt();
Row row = readRow(in, data); Row row = readRow(in, data);
if (stage == RECOVERY_STAGE_UNDO && x == ADD) { if (stage == RECOVERY_STAGE_UNDO && x == ADD) {
store.allocateIfHead(pos, tableId, row); store.allocateIfIndexRoot(pos, tableId, row);
} else if (stage == RECOVERY_STAGE_REDO) { } else if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) { if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) { if (trace.isDebugEnabled()) {
...@@ -517,6 +517,7 @@ public class PageLog { ...@@ -517,6 +517,7 @@ public class PageLog {
} }
session.addLogPos(logSectionId, logPos); session.addLogPos(logSectionId, logPos);
row.setLastLog(logSectionId, logPos); row.setLastLog(logSectionId, logPos);
logPos++;
data.reset(); data.reset();
data.checkCapacity(row.getByteCount(data)); data.checkCapacity(row.getByteCount(data));
...@@ -545,6 +546,8 @@ public class PageLog { ...@@ -545,6 +546,8 @@ public class PageLog {
trace.debug("log truncate s:" + session.getId() + " table:" + tableId); trace.debug("log truncate s:" + session.getId() + " table:" + tableId);
} }
session.addLogPos(logSectionId, logPos); session.addLogPos(logSectionId, logPos);
logPos++;
data.reset(); data.reset();
out.write(TRUNCATE); out.write(TRUNCATE);
out.writeInt(session.getId()); out.writeInt(session.getId());
...@@ -579,6 +582,7 @@ public class PageLog { ...@@ -579,6 +582,7 @@ public class PageLog {
} }
undo = new BitField(); undo = new BitField();
logSectionId++; logSectionId++;
logPos = 0;
pageOut.fillPage(); pageOut.fillPage();
int currentDataPage = pageOut.getCurrentDataPageId(); int currentDataPage = pageOut.getCurrentDataPageId();
logSectionPageMap.put(logSectionId, currentDataPage); logSectionPageMap.put(logSectionId, currentDataPage);
...@@ -588,6 +592,10 @@ public class PageLog { ...@@ -588,6 +592,10 @@ public class PageLog {
return logSectionId; return logSectionId;
} }
long getLogPos() {
return logPos;
}
/** /**
* Remove all pages until the given log (excluding). * Remove all pages until the given log (excluding).
* *
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.store; package org.h2.store;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.engine.Session;
/** /**
* A data page of a stream. The format is: * A data page of a stream. The format is:
...@@ -160,4 +161,23 @@ public class PageStreamData extends Page { ...@@ -160,4 +161,23 @@ public class PageStreamData extends Page {
remaining = length; remaining = length;
} }
public void moveTo(Session session, int newPos) throws SQLException {
// PageStreamData d2 = new PageStreamData(store, newPos, trunk);
// d2.initWrite();
// initRead();
// byte[] buff = new byte[remaining];
// read(buff, 0, remaining);
// d2.write(buff, 0, remaining);
// store.updateRecord(d2, false, null);
// PageStreamTrunk t = (PageStreamTrunk) store.getPage(trunk);
// t.moveChild(getPos(), newPos);
// store.freePage(getPos(), true, data);
}
void setTrunkPage(int newTrunk) throws SQLException {
this.trunk = newTrunk;
data.setInt(0, trunk);
store.updateRecord(this, true, data);
}
} }
\ No newline at end of file
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.store; package org.h2.store;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.engine.Session;
/** /**
* A trunk page of a stream. It contains the page numbers of the stream, and * A trunk page of a stream. It contains the page numbers of the stream, and
...@@ -180,4 +181,37 @@ public class PageStreamTrunk extends Page { ...@@ -180,4 +181,37 @@ public class PageStreamTrunk extends Page {
return store.getPageSize() >> 2; return store.getPageSize() >> 2;
} }
/**
* One of the children has moved to another place.
*
* @param oldPos the old position
* @param newPos the new position
*/
void moveChild(int oldPos, int newPos) throws SQLException {
for (int i = 0; i < pageIds.length; i++) {
if (pageIds[i] == oldPos) {
pageIds[i] = newPos;
break;
}
}
store.updateRecord(this, true, data);
}
public void moveTo(Session session, int newPos) throws SQLException {
// PageStreamTrunk p2 = new PageStreamTrunk(store, parent, newPos, nextTrunk, pageIds);
// store.updateRecord(p2, false, null);
// for (int i = 0; i < pageCount; i++) {
// int p = pageIds[i];
// PageStreamData d = (PageStreamData) store.getPage(p);
// if (d != null) {
// d.setTrunkPage(newPos);
// }
// }
// if (store.getLogFirstTrunkPage() == getPos()) {
// int dataPageId = store.getLogFirstDataPage();
// store.setLogFirstPage(newPos, dataPageId);
// }
// store.freePage(getPos(), true, data);
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论