提交 1ee1d5a5 authored 作者: Thomas Mueller's avatar Thomas Mueller

new experimental page store

上级 1bf063e5
...@@ -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.engine.Session;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.store.DataPageBinary; import org.h2.store.DataPageBinary;
...@@ -152,9 +153,15 @@ abstract class PageData { ...@@ -152,9 +153,15 @@ abstract class PageData {
* *
* @param id the new parent page id * @param id the new parent page id
*/ */
void setParentPageId(int id) { void setParentPageId(int id) throws SQLException {
this.parentPageId = id; this.parentPageId = id;
remapChildren();
} }
/**
* Update the parent id of all children.
*/
abstract void remapChildren() throws SQLException;
/** /**
* Remove a row. * Remove a row.
...@@ -163,5 +170,13 @@ abstract class PageData { ...@@ -163,5 +170,13 @@ abstract class PageData {
* @return true if this page is now empty * @return true if this page is now empty
*/ */
abstract boolean remove(int key) throws SQLException; abstract boolean remove(int key) throws SQLException;
/**
* Get the row for the given key.
*
* @param key the key
* @return the row
*/
abstract Row getRow(Session session, int key) throws SQLException;
} }
...@@ -9,12 +9,9 @@ package org.h2.index; ...@@ -9,12 +9,9 @@ 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.engine.Session;
import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.store.DataPageBinary; import org.h2.store.DataPageBinary;
/** /**
...@@ -79,7 +76,7 @@ class PageDataLeaf extends PageData { ...@@ -79,7 +76,7 @@ class PageDataLeaf extends PageData {
void write() throws SQLException { void write() throws SQLException {
// make sure rows are read // make sure rows are read
for (int i = 0; i < entryCount; i++) { for (int i = 0; i < entryCount; i++) {
getRow(i); getRowAt(i);
} }
data.reset(); data.reset();
data.writeInt(parentPageId); data.writeInt(parentPageId);
...@@ -194,7 +191,7 @@ class PageDataLeaf extends PageData { ...@@ -194,7 +191,7 @@ class PageDataLeaf extends PageData {
* @param index the index * @param index the index
* @return the row * @return the row
*/ */
Row getRow(int index) throws SQLException { Row getRowAt(int index) throws SQLException {
Row r = rows[index]; Row r = rows[index];
if (r == null) { if (r == null) {
data.setPos(offsets[index]); data.setPos(offsets[index]);
...@@ -213,7 +210,7 @@ class PageDataLeaf extends PageData { ...@@ -213,7 +210,7 @@ class PageDataLeaf extends PageData {
int newPageId = index.getPageStore().allocatePage(); int newPageId = index.getPageStore().allocatePage();
PageDataLeaf p2 = new PageDataLeaf(index, newPageId, parentPageId, index.getPageStore().createDataPage()); PageDataLeaf p2 = new PageDataLeaf(index, newPageId, parentPageId, index.getPageStore().createDataPage());
for (int i = splitPoint; i < entryCount;) { for (int i = splitPoint; i < entryCount;) {
p2.addRow(getRow(splitPoint)); p2.addRow(getRowAt(splitPoint));
removeRow(splitPoint); removeRow(splitPoint);
} }
return p2; return p2;
...@@ -221,7 +218,7 @@ class PageDataLeaf extends PageData { ...@@ -221,7 +218,7 @@ class PageDataLeaf extends PageData {
int getLastKey() throws SQLException { int getLastKey() throws SQLException {
int todoRemove; int todoRemove;
return getRow(entryCount - 1).getPos(); return getRowAt(entryCount - 1).getPos();
} }
public PageDataLeaf getNextPage() throws SQLException { public PageDataLeaf getNextPage() throws SQLException {
...@@ -235,6 +232,10 @@ class PageDataLeaf extends PageData { ...@@ -235,6 +232,10 @@ class PageDataLeaf extends PageData {
PageDataLeaf getFirstLeaf() { PageDataLeaf getFirstLeaf() {
return this; return this;
} }
protected void remapChildren() throws SQLException {
int todoUpdateOverflowPages;
}
boolean remove(int key) throws SQLException { boolean remove(int key) throws SQLException {
int i = find(key); int i = find(key);
...@@ -244,29 +245,17 @@ class PageDataLeaf extends PageData { ...@@ -244,29 +245,17 @@ class PageDataLeaf extends PageData {
if (entryCount == 1) { if (entryCount == 1) {
return true; return true;
} }
// if (pageData.size() == 1 && !root) { removeRow(i);
// // the last row has been deleted write();
// return oldRow; return false;
// } }
// pageData.remove(i);
// updateRealByteCount(false, row); Row getRow(Session session, int key) throws SQLException {
// index.updatePage(session, this); int index = find(key);
// if (i > 0) { if(index >= keys.length) {
// // the first row didn't change System.out.println("stop");
// return null; }
// } return getRowAt(index);
// if (pageData.size() == 0) {
// return null;
// }
// return getData(0);
// }
// if (comp > 0) {
// r = i;
// } else {
// l = i + 1;
// }
// }
throw Message.getSQLException(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, index.getSQL());
} }
} }
...@@ -8,11 +8,9 @@ package org.h2.index; ...@@ -8,11 +8,9 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.engine.Session;
import org.h2.engine.Constants;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.store.DataPageBinary; import org.h2.store.DataPageBinary;
/** /**
...@@ -61,6 +59,24 @@ class PageDataNode extends PageData { ...@@ -61,6 +59,24 @@ class PageDataNode extends PageData {
} }
index.getPageStore().writePage(pageId, data); index.getPageStore().writePage(pageId, data);
} }
void addChild(int x, int childPageId, int key) {
int[] newKeys = new int[entryCount + 1];
int[] newChildPageIds = new int[entryCount + 2];
if (entryCount > 0) {
System.arraycopy(keys, 0, newKeys, 0, x);
System.arraycopy(childPageIds, 0, newChildPageIds, 0, x + 1);
if (x < entryCount) {
System.arraycopy(keys, x, newKeys, x + 1, entryCount - x);
System.arraycopy(childPageIds, x, newChildPageIds, x + 1, entryCount - x + 1);
}
}
newKeys[x] = key;
newChildPageIds[x + 1] = childPageId;
keys = newKeys;
childPageIds = newChildPageIds;
entryCount++;
}
int addRow(Row row) throws SQLException { int addRow(Row row) throws SQLException {
int x = find(row.getPos()); int x = find(row.getPos());
...@@ -71,19 +87,9 @@ class PageDataNode extends PageData { ...@@ -71,19 +87,9 @@ class PageDataNode extends PageData {
} }
int pivot = page.getKey(splitPoint); int pivot = page.getKey(splitPoint);
PageData page2 = page.split(splitPoint); PageData page2 = page.split(splitPoint);
int[] newKeys = new int[entryCount + 1]; page.write();
int[] newChildPageIds = new int[entryCount + 2]; page2.write();
System.arraycopy(keys, 0, newKeys, 0, x); addChild(x, page2.getPageId(), pivot);
System.arraycopy(childPageIds, 0, newChildPageIds, 0, x);
if (x < entryCount) {
System.arraycopy(keys, x, newKeys, x + 1, entryCount - x);
System.arraycopy(childPageIds, x, newChildPageIds, x + 1, entryCount - x + 1);
}
newKeys[x] = pivot;
newChildPageIds[x] = page2.getPageId();
keys = newKeys;
childPageIds = newChildPageIds;
entryCount++;
int maxEntries = (index.getPageStore().getPageSize() - 11) / 8; int maxEntries = (index.getPageStore().getPageSize() - 11) / 8;
if (entryCount >= maxEntries) { if (entryCount >= maxEntries) {
int todoSplitAtLastInsertionPoint; int todoSplitAtLastInsertionPoint;
...@@ -99,8 +105,43 @@ class PageDataNode extends PageData { ...@@ -99,8 +105,43 @@ class PageDataNode extends PageData {
} }
PageData split(int splitPoint) throws SQLException { PageData split(int splitPoint) throws SQLException {
int todo; int newPageId = index.getPageStore().allocatePage();
return null; PageDataNode p2 = new PageDataNode(index, newPageId, parentPageId, index.getPageStore().createDataPage());
splitPoint++;
int firstChild = childPageIds[splitPoint];
for (int i = splitPoint; i < entryCount;) {
p2.addChild(p2.entryCount, childPageIds[splitPoint + 1], keys[splitPoint]);
removeChild(splitPoint);
}
int lastChild = childPageIds[splitPoint - 1];
removeChild(splitPoint - 1);
childPageIds[splitPoint - 1] = lastChild;
p2.childPageIds[0] = firstChild;
p2.remapChildren();
return p2;
}
protected void remapChildren() throws SQLException {
for (int i = 0; i < childPageIds.length; i++) {
int child = childPageIds[i];
PageData p = index.getPage(child);
p.setParentPageId(pageId);
p.write();
}
}
private void removeChild(int x) {
int[] newKeys = new int[entryCount - 1];
int[] newChildPageIds = new int[entryCount];
System.arraycopy(keys, 0, newKeys, 0, x);
System.arraycopy(childPageIds, 0, newChildPageIds, 0, x + 1);
if (x < entryCount) {
System.arraycopy(keys, x + 1, newKeys, x, entryCount - x - 1);
System.arraycopy(childPageIds, x + 1, newChildPageIds, x, entryCount - x);
}
keys = newKeys;
childPageIds = newChildPageIds;
entryCount--;
} }
/** /**
...@@ -172,7 +213,8 @@ class PageDataNode extends PageData { ...@@ -172,7 +213,8 @@ class PageDataNode extends PageData {
return false; return false;
} }
// this child is now empty // this child is now empty
if (entryCount == 1) { index.getPageStore().freePage(page.getPageId());
if (entryCount == 0) {
// no more children - this page is empty as well // no more children - this page is empty as well
// it can't be the root otherwise the index would have been // it can't be the root otherwise the index would have been
// truncated // truncated
...@@ -186,7 +228,14 @@ class PageDataNode extends PageData { ...@@ -186,7 +228,14 @@ class PageDataNode extends PageData {
// otherwise the first row didn't change // otherwise the first row didn't change
removeRow(at - 1); removeRow(at - 1);
} }
write();
return false; return false;
} }
Row getRow(Session session, int key) throws SQLException {
int at = find(key);
PageData page = index.getPage(childPageIds[at]);
return page.getRow(session, key);
}
} }
...@@ -45,7 +45,7 @@ class PageScanCursor implements Cursor { ...@@ -45,7 +45,7 @@ class PageScanCursor implements Cursor {
return false; return false;
} }
} }
row = current.getRow(index); row = current.getRowAt(index);
index++; index++;
return true; return true;
} }
......
...@@ -62,7 +62,6 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -62,7 +62,6 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
table.setRowCount(rowCount); table.setRowCount(rowCount);
} }
public void add(Session session, Row row) throws SQLException { public void add(Session session, Row row) throws SQLException {
row.setPos((int) rowCount); row.setPos((int) rowCount);
PageData root = getPage(headPos); PageData root = getPage(headPos);
...@@ -75,6 +74,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -75,6 +74,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
int id = store.allocatePage(); int id = store.allocatePage();
page1.setPageId(id); page1.setPageId(id);
page1.setParentPageId(headPos); page1.setParentPageId(headPos);
page2.setParentPageId(headPos);
PageDataNode newRoot = new PageDataNode(this, rootPageId, Page.ROOT, store.createDataPage()); PageDataNode newRoot = new PageDataNode(this, rootPageId, Page.ROOT, store.createDataPage());
newRoot.init(page1, pivot, page2); newRoot.init(page1, pivot, page2);
page1.write(); page1.write();
...@@ -106,7 +106,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -106,7 +106,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
result = new PageDataNode(this, id, parentPageId, data); result = new PageDataNode(this, id, parentPageId, data);
break; break;
default: default:
throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1, "type=" + type); throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1, "page=" + id + " type=" + type);
} }
result.read(); result.read();
return result; return result;
...@@ -159,7 +159,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -159,7 +159,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
public void truncate(Session session) throws SQLException { public void truncate(Session session) throws SQLException {
int invalidateRowCount; int invalidateRowCount;
int todo; PageDataLeaf root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage());
root.write();
rowCount = 0; rowCount = 0;
} }
...@@ -168,8 +169,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex { ...@@ -168,8 +169,8 @@ 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 {
int todo; PageData root = getPage(headPos);
return null; return root.getRow(session, key);
} }
PageStore getPageStore() { PageStore getPageStore() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论