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

new experimental page store

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