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

Page store: only store the key when deleting, not the whole row.

上级 b5f1d973
......@@ -66,8 +66,8 @@ public class PageBtreeNode extends PageBtree {
* Create a new b-tree node page.
*
* @param index the index
* @param data the data
* @param pageId the page id
* @param parentPageId the parent page id
* @return the page
*/
public static PageBtreeNode create(PageBtreeIndex index, int pageId, int parentPageId) {
......
......@@ -356,6 +356,16 @@ public class PageScanIndex extends PageIndex implements RowIndex {
}
public Row getRow(Session session, int key) throws SQLException {
return getRow(key);
}
/**
* Get the row with the given key.
*
* @param key the key
* @return the row
*/
public Row getRow(long key) throws SQLException {
PageData root = getPage(rootPageId, 0);
return root.getRow(key);
}
......
......@@ -251,21 +251,37 @@ public class PageLog {
undoAll.set(pageId);
}
}
} else if (x == ADD || x == REMOVE) {
} else if (x == ADD) {
int sessionId = in.readInt();
int tableId = in.readInt();
Row row = readRow(in, data);
if (stage == RECOVERY_STAGE_UNDO && x == ADD) {
if (stage == RECOVERY_STAGE_UNDO) {
store.allocateIfIndexRoot(pos, tableId, row);
} else if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) {
trace.debug("log redo " + (x == ADD ? "+" : "-") + " table:" + tableId + " " + row);
trace.debug("log redo + table:" + tableId + " " + row);
}
store.redo(pos, tableId, row, x == ADD);
store.redo(pos, tableId, row, true);
} else {
if (trace.isDebugEnabled()) {
trace.debug("log ignore s:" + sessionId + " " + (x == ADD ? "+" : "-") + " table:" + tableId + " " + row);
trace.debug("log ignore s:" + sessionId + " + table:" + tableId + " " + row);
}
}
}
} else if (x == REMOVE) {
int sessionId = in.readInt();
int tableId = in.readInt();
long key = in.readLong();
if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) {
trace.debug("log redo - table:" + tableId + " key:" + key);
}
store.redoDelete(pos, tableId, key);
} else {
if (trace.isDebugEnabled()) {
trace.debug("log ignore s:" + sessionId + " - table:" + tableId + " key:" + key);
}
}
}
......@@ -523,9 +539,13 @@ public class PageLog {
out.write(add ? ADD : REMOVE);
out.writeInt(session.getId());
out.writeInt(tableId);
out.writeInt(row.getPos());
out.writeInt(data.length());
out.write(data.getBytes(), 0, data.length());
if (add) {
out.writeInt(row.getPos());
out.writeInt(data.length());
out.write(data.getBytes(), 0, data.length());
} else {
out.writeLong(row.getPos());
}
flushOut();
} catch (IOException e) {
throw Message.convertIOException(e, null);
......
......@@ -79,25 +79,24 @@ import org.h2.value.ValueString;
*/
public class PageStore implements CacheWriter {
// TODO delete: only log the key
// TODO update: only log the key and changed values
// TODO fix page format of data overflow and so on
// TODO implement checksum; 0 for empty pages
// TODO in log, don't store empty space between page head and page data
// TODO undo log: fully compress empty pages
// TODO undo log: don't store empty space between head and data
// TODO undo log: lzf compression
// TODO long primary keys don't use delegating index yet (setPos(): int)
// TODO replace CRC32
// TODO maybe remove parent pointer
// TODO index creation: use less space (ordered, split at insertion point)
// TODO test running out of disk space (using a special file system)
// TODO utf-x: test if it's faster
// TODO after opening the database, delay writing until required
// TODO maybe remove parent pointer
// TODO replace CRC32
// TODO optimization: try to avoid allocating a byte array per page
// TODO optimization: check if calling Data.getValueLen slows things down
// TODO undo pages: don't store the middle zeroes
// TODO undo pages compression: try http://en.wikipedia.org/wiki/LZJB
// TODO order pages so that searching for a key only seeks forward
// TODO completely re-use keys of deleted rows; maybe
// remember last page with deleted keys (in the root page?),
// and chain such pages
// TODO delete: only log the key
// TODO update: only log the key and changed values
// TODO detect circles in linked lists
// (input stream, free list, extend pages...)
......@@ -105,16 +104,12 @@ public class PageStore implements CacheWriter {
// synchronized correctly (on the index?)
// TODO remove trace or use isDebugEnabled
// TODO recover tool: don't re-do uncommitted operations
// TODO no need to log old page if it was always empty
// TODO don't store default values (store a special value)
// TODO split files (1 GB max size)
// TODO add a setting (that can be changed at runtime) to call fsync
// and delay on each commit
// TODO PageData and PageBtree addRowTry: try to simplify
// TODO test running out of disk space (using a special file system)
// TODO check for file size (exception if not exact size expected)
// TODO implement missing code for STORE_BTREE_ROWCOUNT (maybe enable)
// TODO store dates differently in Data; test moving db to another timezone
// TODO online backup using bsdiff
// TODO when removing DiskFile:
......@@ -1047,6 +1042,20 @@ public class PageStore implements CacheWriter {
}
}
/**
* Redo a delete in a table.
*
* @param logPos the redo log position
* @param tableId the object id of the table
* @param key the key of the row to delete
*/
void redoDelete(int logPos, int tableId, long key) throws SQLException {
Index index = metaObjects.get(tableId);
PageScanIndex scan = (PageScanIndex) index;
Row row = scan.getRow(key);
redo(logPos, tableId, row, false);
}
/**
* Redo a change in a table.
*
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论