提交 b3ef328e authored 作者: Thomas Mueller's avatar Thomas Mueller

New experimental page store.

上级 490ce676
...@@ -572,17 +572,17 @@ public class Database implements DataHandler { ...@@ -572,17 +572,17 @@ public class Database implements DataHandler {
while (!beforeWriting()) { while (!beforeWriting()) {
// until we can write (file are not open - no need to re-connect) // until we can write (file are not open - no need to re-connect)
} }
if (SysProperties.PAGE_STORE) {
starting = true;
getPageStore();
starting = false;
}
if (exists) { if (exists) {
lobFilesInDirectories &= !ValueLob.existsLobFile(getDatabasePath()); lobFilesInDirectories &= !ValueLob.existsLobFile(getDatabasePath());
lobFilesInDirectories |= FileUtils.exists(databaseName + Constants.SUFFIX_LOBS_DIRECTORY); lobFilesInDirectories |= FileUtils.exists(databaseName + Constants.SUFFIX_LOBS_DIRECTORY);
} }
dummy = DataPage.create(this, 0); dummy = DataPage.create(this, 0);
deleteOldTempFiles(); deleteOldTempFiles();
if (SysProperties.PAGE_STORE) {
starting = true;
getPageStore();
starting = false;
}
log = new LogSystem(this, databaseName, readOnly, accessModeLog, pageStore); log = new LogSystem(this, databaseName, readOnly, accessModeLog, pageStore);
if (pageStore == null) { if (pageStore == null) {
openFileData(); openFileData();
......
...@@ -101,7 +101,7 @@ public class Session extends SessionWithState { ...@@ -101,7 +101,7 @@ public class Session extends SessionWithState {
private int modificationIdState; private int modificationIdState;
private int objectId; private int objectId;
Session(Database database, User user, int id) { public Session(Database database, User user, int id) {
this.database = database; this.database = database;
this.undoLog = new UndoLog(this); this.undoLog = new UndoLog(this);
this.user = user; this.user = user;
......
...@@ -62,7 +62,7 @@ abstract class PageBtree extends Record { ...@@ -62,7 +62,7 @@ abstract class PageBtree extends Record {
protected boolean onlyPosition; protected boolean onlyPosition;
/** /**
* If the page was already written to the buffer. * Whether the data page is up-to-date.
*/ */
protected boolean written; protected boolean written;
...@@ -181,6 +181,7 @@ abstract class PageBtree extends Record { ...@@ -181,6 +181,7 @@ abstract class PageBtree extends Record {
* @param id the new page id * @param id the new page id
*/ */
void setPageId(int id) throws SQLException { void setPageId(int id) throws SQLException {
written = false;
index.getPageStore().removeRecord(getPos()); index.getPageStore().removeRecord(getPos());
setPos(id); setPos(id);
remapChildren(); remapChildren();
...@@ -210,7 +211,8 @@ abstract class PageBtree extends Record { ...@@ -210,7 +211,8 @@ abstract class PageBtree extends Record {
* @param id the new parent page id * @param id the new parent page id
*/ */
void setParentPageId(int id) { void setParentPageId(int id) {
this.parentPageId = id; written = false;
parentPageId = id;
} }
/** /**
......
...@@ -80,7 +80,7 @@ public class PageBtreeCursor implements Cursor { ...@@ -80,7 +80,7 @@ public class PageBtreeCursor implements Cursor {
if (current == null) { if (current == null) {
return false; return false;
} }
if (i <= 0) { if (i < 0) {
current.previousPage(this); current.previousPage(this);
if (current == null) { if (current == null) {
return false; return false;
......
...@@ -31,7 +31,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -31,7 +31,7 @@ public class PageBtreeIndex extends BaseIndex {
private PageStore store; private PageStore store;
private TableData tableData; private TableData tableData;
private int headPos; private final int headPos;
private long rowCount; private long rowCount;
private boolean needRebuild; private boolean needRebuild;
...@@ -46,6 +46,7 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -46,6 +46,7 @@ public class PageBtreeIndex extends BaseIndex {
tableData = table; tableData = table;
if (!database.isPersistent() || id < 0) { if (!database.isPersistent() || id < 0) {
int todo; int todo;
this.headPos = 0;
return; return;
} }
this.store = database.getPageStore(); this.store = database.getPageStore();
...@@ -53,13 +54,19 @@ public class PageBtreeIndex extends BaseIndex { ...@@ -53,13 +54,19 @@ public class PageBtreeIndex extends BaseIndex {
// new index // new index
needRebuild = true; needRebuild = true;
this.headPos = headPos = store.allocatePage(); this.headPos = headPos = store.allocatePage();
// TODO currently the head position is stored in the log
// it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things
store.addMeta(this, session, headPos);
PageBtreeLeaf root = new PageBtreeLeaf(this, headPos, Page.ROOT, store.createDataPage()); PageBtreeLeaf root = new PageBtreeLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.updateRecord(root, true, root.data); store.updateRecord(root, true, root.data);
store.addMeta(this, session);
} else { } else {
this.headPos = headPos; this.headPos = headPos;
PageBtree root = getPage(headPos); PageBtree root = getPage(headPos);
rowCount = root.getRowCount(); rowCount = root.getRowCount();
if (rowCount == 0 && store.isRecoveryRunning()) {
needRebuild = true;
}
if (!database.isReadOnly()) { if (!database.isReadOnly()) {
// could have been created before, but never committed // could have been created before, but never committed
// TODO test if really required // TODO test if really required
......
...@@ -48,6 +48,11 @@ abstract class PageData extends Record { ...@@ -48,6 +48,11 @@ abstract class PageData extends Record {
*/ */
protected int[] keys; protected int[] keys;
/**
* Whether the data page is up-to-date.
*/
protected boolean written;
PageData(PageScanIndex index, int pageId, int parentPageId, DataPage data) { PageData(PageScanIndex index, int pageId, int parentPageId, DataPage data) {
this.index = index; this.index = index;
this.parentPageId = parentPageId; this.parentPageId = parentPageId;
...@@ -137,6 +142,7 @@ abstract class PageData extends Record { ...@@ -137,6 +142,7 @@ abstract class PageData extends Record {
* @param id the new page id * @param id the new page id
*/ */
void setPageId(int id) throws SQLException { void setPageId(int id) throws SQLException {
written = false;
index.getPageStore().removeRecord(getPos()); index.getPageStore().removeRecord(getPos());
setPos(id); setPos(id);
remapChildren(); remapChildren();
...@@ -166,7 +172,8 @@ abstract class PageData extends Record { ...@@ -166,7 +172,8 @@ abstract class PageData extends Record {
* @param id the new parent page id * @param id the new parent page id
*/ */
void setParentPageId(int id) { void setParentPageId(int id) {
this.parentPageId = id; written = false;
parentPageId = id;
} }
/** /**
...@@ -204,4 +211,8 @@ abstract class PageData extends Record { ...@@ -204,4 +211,8 @@ abstract class PageData extends Record {
return index.getPageStore().getPageSize() >> 2; return index.getPageStore().getPageSize() >> 2;
} }
int getParentPageId() {
return parentPageId;
}
} }
...@@ -52,8 +52,6 @@ class PageDataLeaf extends PageData { ...@@ -52,8 +52,6 @@ class PageDataLeaf extends PageData {
*/ */
int start; int start;
private boolean written;
PageDataLeaf(PageScanIndex index, int pageId, int parentPageId, DataPage data) { PageDataLeaf(PageScanIndex index, int pageId, int parentPageId, DataPage data) {
super(index, pageId, parentPageId, data); super(index, pageId, parentPageId, data);
start = KEY_OFFSET_PAIR_START; start = KEY_OFFSET_PAIR_START;
...@@ -263,7 +261,7 @@ class PageDataLeaf extends PageData { ...@@ -263,7 +261,7 @@ class PageDataLeaf extends PageData {
if (parentPageId == Page.ROOT) { if (parentPageId == Page.ROOT) {
return null; return null;
} }
PageDataNode next = (PageDataNode) index.getPage(parentPageId); PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1);
return next.getNextPage(keys[entryCount - 1]); return next.getNextPage(keys[entryCount - 1]);
} }
......
...@@ -80,7 +80,7 @@ class PageDataNode extends PageData { ...@@ -80,7 +80,7 @@ class PageDataNode extends PageData {
int addRowTry(Row row) throws SQLException { int addRowTry(Row row) throws SQLException {
while (true) { while (true) {
int x = find(row.getPos()); int x = find(row.getPos());
PageData page = index.getPage(childPageIds[x]); PageData page = index.getPage(childPageIds[x], getPos());
int splitPoint = page.addRowTry(row); int splitPoint = page.addRowTry(row);
if (splitPoint == 0) { if (splitPoint == 0) {
break; break;
...@@ -113,7 +113,7 @@ class PageDataNode extends PageData { ...@@ -113,7 +113,7 @@ class PageDataNode extends PageData {
Cursor find(Session session) throws SQLException { Cursor find(Session session) throws SQLException {
int child = childPageIds[0]; int child = childPageIds[0];
return index.getPage(child).find(session); return index.getPage(child, getPos()).find(session);
} }
PageData split(int splitPoint) throws SQLException { PageData split(int splitPoint) throws SQLException {
...@@ -134,7 +134,7 @@ class PageDataNode extends PageData { ...@@ -134,7 +134,7 @@ class PageDataNode extends PageData {
protected void remapChildren() throws SQLException { protected void remapChildren() throws SQLException {
for (int child : childPageIds) { for (int child : childPageIds) {
PageData p = index.getPage(child); PageData p = index.getPage(child, -1);
p.setParentPageId(getPos()); p.setParentPageId(getPos());
index.getPageStore().updateRecord(p, true, p.data); index.getPageStore().updateRecord(p, true, p.data);
} }
...@@ -156,7 +156,7 @@ class PageDataNode extends PageData { ...@@ -156,7 +156,7 @@ class PageDataNode extends PageData {
int getLastKey() throws SQLException { int getLastKey() throws SQLException {
int todoRemove; int todoRemove;
return index.getPage(childPageIds[entryCount]).getLastKey(); return index.getPage(childPageIds[entryCount], getPos()).getLastKey();
} }
/** /**
...@@ -171,23 +171,23 @@ class PageDataNode extends PageData { ...@@ -171,23 +171,23 @@ class PageDataNode extends PageData {
if (parentPageId == Page.ROOT) { if (parentPageId == Page.ROOT) {
return null; return null;
} }
PageDataNode next = (PageDataNode) index.getPage(parentPageId); PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1);
return next.getNextPage(key); return next.getNextPage(key);
} }
PageData page = index.getPage(childPageIds[i]); PageData page = index.getPage(childPageIds[i], getPos());
return page.getFirstLeaf(); return page.getFirstLeaf();
} }
PageDataLeaf getFirstLeaf() throws SQLException { PageDataLeaf getFirstLeaf() throws SQLException {
int child = childPageIds[0]; int child = childPageIds[0];
return index.getPage(child).getFirstLeaf(); return index.getPage(child, getPos()).getFirstLeaf();
} }
boolean remove(int key) throws SQLException { boolean remove(int key) throws SQLException {
int at = find(key); int at = find(key);
// merge is not implemented to allow concurrent usage of btrees // merge is not implemented to allow concurrent usage of btrees
// TODO maybe implement merge // TODO maybe implement merge
PageData page = index.getPage(childPageIds[at]); PageData page = index.getPage(childPageIds[at], getPos());
boolean empty = page.remove(key); boolean empty = page.remove(key);
updateRowCount(-1); updateRowCount(-1);
if (!empty) { if (!empty) {
...@@ -208,7 +208,7 @@ class PageDataNode extends PageData { ...@@ -208,7 +208,7 @@ class PageDataNode extends PageData {
void freeChildren() throws SQLException { void freeChildren() throws SQLException {
for (int i = 0; i <= entryCount; i++) { for (int i = 0; i <= entryCount; i++) {
int childPageId = childPageIds[i]; int childPageId = childPageIds[i];
PageData child = index.getPage(childPageId); PageData child = index.getPage(childPageId, getPos());
index.getPageStore().freePage(childPageId, false, null); index.getPageStore().freePage(childPageId, false, null);
child.freeChildren(); child.freeChildren();
} }
...@@ -216,7 +216,7 @@ class PageDataNode extends PageData { ...@@ -216,7 +216,7 @@ class PageDataNode extends PageData {
Row getRow(int key) throws SQLException { Row getRow(int key) throws SQLException {
int at = find(key); int at = find(key);
PageData page = index.getPage(childPageIds[at]); PageData page = index.getPage(childPageIds[at], getPos());
return page.getRow(key); return page.getRow(key);
} }
...@@ -224,7 +224,7 @@ class PageDataNode extends PageData { ...@@ -224,7 +224,7 @@ class PageDataNode extends PageData {
if (rowCount == UNKNOWN_ROWCOUNT) { if (rowCount == UNKNOWN_ROWCOUNT) {
int count = 0; int count = 0;
for (int child : childPageIds) { for (int child : childPageIds) {
PageData page = index.getPage(child); PageData page = index.getPage(child, getPos());
if (getPos() == page.getPos()) { if (getPos() == page.getPos()) {
throw Message.throwInternalError("Page it its own child: " + getPageId()); throw Message.throwInternalError("Page it its own child: " + getPageId());
} }
......
...@@ -65,7 +65,10 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -65,7 +65,10 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
if (headPos == Index.EMPTY_HEAD) { if (headPos == Index.EMPTY_HEAD) {
// new table // new table
this.headPos = headPos = store.allocatePage(); this.headPos = headPos = store.allocatePage();
store.addMeta(this, session); // TODO currently the head position is stored in the log
// it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things
store.addMeta(this, session, headPos);
PageDataLeaf root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage()); PageDataLeaf root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.updateRecord(root, true, root.data); store.updateRecord(root, true, root.data);
...@@ -76,7 +79,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -76,7 +79,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
// store.updateRecord(root, true, root.data); // store.updateRecord(root, true, root.data);
} else { } else {
this.headPos = headPos; this.headPos = headPos;
PageData root = getPage(headPos); PageData root = getPage(headPos, 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
...@@ -118,7 +121,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -118,7 +121,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
} }
while (true) { while (true) {
PageData root = getPage(headPos); PageData root = getPage(headPos, 0);
int splitPoint = root.addRowTry(row); int splitPoint = root.addRowTry(row);
if (splitPoint == 0) { if (splitPoint == 0) {
break; break;
...@@ -159,9 +162,10 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -159,9 +162,10 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
* Read the given page. * Read the given page.
* *
* @param id the page id * @param id the page id
* @param parent the parent, or -1 if unknown
* @return the page * @return the page
*/ */
PageData getPage(int id) throws SQLException { PageData getPage(int id, int parent) throws SQLException {
Record rec = store.getRecord(id); Record rec = store.getRecord(id);
if (rec != null) { if (rec != null) {
return (PageData) rec; return (PageData) rec;
...@@ -185,6 +189,11 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -185,6 +189,11 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1, "page=" + id + " type=" + type); throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1, "page=" + id + " type=" + type);
} }
result.read(); result.read();
if (parent != -1) {
if (result.getParentPageId() != parent) {
throw Message.throwInternalError(result.getParentPageId() + " " + parent + " " + result);
}
}
return result; return result;
} }
...@@ -193,7 +202,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -193,7 +202,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); PageData root = getPage(headPos, 0);
return root.find(session); return root.find(session);
} }
...@@ -229,7 +238,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -229,7 +238,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
removeAllRows(); removeAllRows();
} else { } else {
int key = row.getPos(); int key = row.getPos();
PageData root = getPage(headPos); PageData root = getPage(headPos, 0);
root.remove(key); root.remove(key);
rowCount--; rowCount--;
int todoReuseKeys; int todoReuseKeys;
...@@ -276,7 +285,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -276,7 +285,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
} }
private void removeAllRows() throws SQLException { private void removeAllRows() throws SQLException {
PageData root = getPage(headPos); PageData root = getPage(headPos, 0);
root.freeChildren(); root.freeChildren();
root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage()); root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.removeRecord(headPos); store.removeRecord(headPos);
...@@ -290,7 +299,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -290,7 +299,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); PageData root = getPage(headPos, 0);
return root.getRow(key); return root.getRow(key);
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论