提交 9658fe81 authored 作者: Thomas Mueller's avatar Thomas Mueller

New experimental page store.

上级 455c15cb
......@@ -18,7 +18,12 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Bugfixes in the new storage mechanism (page store).
<ul><li>The Recover tool did not work with .data.db files of the wrong size.
</li><li>Triggers: if there was an exception when initializing a trigger, this exception could be hidden,
and in some cases (specially when using the Lucene fulltext index mechanism) a NullPointerException was
thrown later on. Now the exception that occurred on init is thrown when changing data.
</li><li>The soft-references cache (CACHE_TYPE=SOFT_LRU) could throw a NullPointerException.
</li><li>Bugfixes in the new storage mechanism (page store).
</li></ul>
<h2>Version 1.1.115 (2009-06-21)</h2>
......
......@@ -226,6 +226,11 @@ abstract class PageBtree extends Record {
*/
abstract boolean remove(SearchRow row) throws SQLException;
/**
* Free up all child pages.
*/
abstract void freeChildren() throws SQLException;
/**
* Ensure all rows are read in memory.
*/
......
......@@ -242,6 +242,8 @@ public class PageBtreeIndex extends BaseIndex {
if (trace.isDebugEnabled()) {
trace.debug("remove");
}
removeAllRows();
store.freePage(headPos, false, null);
store.removeMeta(this, session);
}
......@@ -257,10 +259,10 @@ public class PageBtreeIndex extends BaseIndex {
}
private void removeAllRows() throws SQLException {
PageBtree root = getPage(headPos);
root.freeChildren();
root = new PageBtreeLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.removeRecord(headPos);
int todoLogOldData;
int freePages;
PageBtreeLeaf root = new PageBtreeLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.updateRecord(root, true, null);
rowCount = 0;
}
......
......@@ -159,6 +159,10 @@ class PageBtreeLeaf extends PageBtree {
return false;
}
void freeChildren() {
// nothing to do
}
int getRowCount() {
return entryCount;
}
......
......@@ -311,6 +311,15 @@ class PageBtreeNode extends PageBtree {
written = true;
}
void freeChildren() throws SQLException {
for (int i = 0; i <= entryCount; i++) {
int childPageId = childPageIds[i];
PageBtree child = index.getPage(childPageId);
index.getPageStore().freePage(childPageId, false, null);
child.freeChildren();
}
}
private void removeChild(int i) throws SQLException {
readAllRows();
entryCount--;
......
......@@ -182,6 +182,11 @@ abstract class PageData extends Record {
*/
abstract boolean remove(int key) throws SQLException;
/**
* Free up all child pages.
*/
abstract void freeChildren() throws SQLException;
/**
* Get the row for the given key.
*
......
......@@ -297,6 +297,28 @@ class PageDataLeaf extends PageData {
return false;
}
void freeChildren() throws SQLException {
if (firstOverflowPageId != 0) {
PageStore store = index.getPageStore();
int next = firstOverflowPageId;
do {
Record record = store.getRecord(next);
PageDataLeafOverflow page;
if (record == null) {
DataPage data = store.readPage(next);
page = new PageDataLeafOverflow(this, next, data, 0);
} else {
if (!(record instanceof PageDataLeafOverflow)) {
throw Message.getInternalError("page:"+ next + " " + record, null);
}
page = (PageDataLeafOverflow) record;
}
store.freePage(next, false, null);
next = page.getNextOverflow();
} while (next != 0);
}
}
Row getRow(int key) throws SQLException {
int index = find(key);
return getRowAt(index);
......
......@@ -109,6 +109,10 @@ public class PageDataLeafOverflow extends Record {
return nextPage;
}
int getNextOverflow() {
return nextPage;
}
public int getByteCount(DataPage dummy) {
return leaf.getByteCount(dummy);
}
......
......@@ -205,6 +205,15 @@ class PageDataNode extends PageData {
return false;
}
void freeChildren() throws SQLException {
for (int i = 0; i <= entryCount; i++) {
int childPageId = childPageIds[i];
PageData child = index.getPage(childPageId);
index.getPageStore().freePage(childPageId, false, null);
child.freeChildren();
}
}
Row getRow(int key) throws SQLException {
int at = find(key);
PageData page = index.getPage(childPageIds[at]);
......
......@@ -256,6 +256,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
if (trace.isDebugEnabled()) {
trace.debug("remove");
}
removeAllRows();
store.freePage(headPos, false, null);
store.removeMeta(this, session);
}
......@@ -274,10 +276,10 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
}
private void removeAllRows() throws SQLException {
PageData root = getPage(headPos);
root.freeChildren();
root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.removeRecord(headPos);
int todoLogOldData;
int freePages;
PageDataLeaf root = new PageDataLeaf(this, headPos, Page.ROOT, store.createDataPage());
store.updateRecord(root, true, null);
rowCount = 0;
lastKey = 0;
......
......@@ -129,7 +129,7 @@ public class PageFreeList extends Record {
* @param pageSize the page size
* @return the number of pages
*/
static int getPagesAddressed(int pageSize) {
public static int getPagesAddressed(int pageSize) {
return (pageSize - DATA_START) * 8;
}
......@@ -142,4 +142,8 @@ public class PageFreeList extends Record {
return store.getPageSize() >> 2;
}
boolean isUsed(int pageId) {
return used.get(pageId - getPos());
}
}
......@@ -93,6 +93,10 @@ public class PageOutputStream extends OutputStream {
}
int len = PageStreamTrunk.getPagesAddressed(store.getPageSize());
int[] pageIds = new int[len];
if (reservedPages.size() < len) {
int test;
System.out.println("stop");
}
for (int i = 0; i < len; i++) {
pageIds[i] = reservedPages.get(i);
}
......@@ -172,6 +176,7 @@ public class PageOutputStream extends OutputStream {
if (trace.isDebugEnabled()) {
trace.debug("pageOut.storePage fill " + data.getPos());
}
reserve(data.getRemaining() + 1);
reserved -= data.getRemaining();
data.write(null);
initNextData();
......
......@@ -309,6 +309,14 @@ public class PageStore implements CacheWriter {
}
log.checkpoint();
switchLog();
byte[] empty = new byte[pageSize];
// TODO avoid to write empty pages
for (int i = PAGE_ID_FREE_LIST_ROOT; i < pageCount; i++) {
if (!isUsed(i)) {
file.seek(i * pageSize);
file.write(empty, 0, pageSize);
}
}
// TODO shrink file if required here
// int pageCount = getFreeList().getLastUsed() + 1;
// trace.debug("pageCount:" + pageCount);
......@@ -505,6 +513,10 @@ public class PageStore implements CacheWriter {
}
}
private PageFreeList getFreeListForPage(int pageId) throws SQLException {
return getFreeList((pageId - PAGE_ID_FREE_LIST_ROOT) / freeListPagesPerList);
}
private PageFreeList getFreeList(int i) throws SQLException {
int p = PAGE_ID_FREE_LIST_ROOT + i * freeListPagesPerList;
while (p >= pageCount) {
......@@ -522,8 +534,7 @@ public class PageStore implements CacheWriter {
}
private void freePage(int pageId) throws SQLException {
int i = (pageId - PAGE_ID_FREE_LIST_ROOT) / freeListPagesPerList;
PageFreeList list = getFreeList(i);
PageFreeList list = getFreeListForPage(pageId);
list.free(pageId);
}
......@@ -533,10 +544,14 @@ public class PageStore implements CacheWriter {
* @param pageId the page to allocate
*/
void allocatePage(int pageId) throws SQLException {
PageFreeList list = getFreeList(pageId / freeListPagesPerList);
PageFreeList list = getFreeListForPage(pageId);
list.allocate(pageId);
}
private boolean isUsed(int pageId) throws SQLException {
return getFreeListForPage(pageId).isUsed(pageId);
}
/**
* Allocate a page.
*
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论