提交 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 { ...@@ -66,8 +66,8 @@ public class PageBtreeNode extends PageBtree {
* Create a new b-tree node page. * Create a new b-tree node page.
* *
* @param index the index * @param index the index
* @param data the data
* @param pageId the page id * @param pageId the page id
* @param parentPageId the parent page id
* @return the page * @return the page
*/ */
public static PageBtreeNode create(PageBtreeIndex index, int pageId, int parentPageId) { public static PageBtreeNode create(PageBtreeIndex index, int pageId, int parentPageId) {
......
...@@ -356,6 +356,16 @@ public class PageScanIndex extends PageIndex implements RowIndex { ...@@ -356,6 +356,16 @@ public class PageScanIndex extends PageIndex implements RowIndex {
} }
public Row getRow(Session session, int key) throws SQLException { 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); PageData root = getPage(rootPageId, 0);
return root.getRow(key); return root.getRow(key);
} }
......
...@@ -251,21 +251,37 @@ public class PageLog { ...@@ -251,21 +251,37 @@ public class PageLog {
undoAll.set(pageId); undoAll.set(pageId);
} }
} }
} else if (x == ADD || x == REMOVE) { } else if (x == ADD) {
int sessionId = in.readInt(); int sessionId = in.readInt();
int tableId = in.readInt(); int tableId = in.readInt();
Row row = readRow(in, data); Row row = readRow(in, data);
if (stage == RECOVERY_STAGE_UNDO && x == ADD) { if (stage == RECOVERY_STAGE_UNDO) {
store.allocateIfIndexRoot(pos, tableId, row); store.allocateIfIndexRoot(pos, tableId, row);
} else if (stage == RECOVERY_STAGE_REDO) { } else if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) { if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) { 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 { } else {
if (trace.isDebugEnabled()) { 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 { ...@@ -523,9 +539,13 @@ public class PageLog {
out.write(add ? ADD : REMOVE); out.write(add ? ADD : REMOVE);
out.writeInt(session.getId()); out.writeInt(session.getId());
out.writeInt(tableId); out.writeInt(tableId);
out.writeInt(row.getPos()); if (add) {
out.writeInt(data.length()); out.writeInt(row.getPos());
out.write(data.getBytes(), 0, data.length()); out.writeInt(data.length());
out.write(data.getBytes(), 0, data.length());
} else {
out.writeLong(row.getPos());
}
flushOut(); flushOut();
} catch (IOException e) { } catch (IOException e) {
throw Message.convertIOException(e, null); throw Message.convertIOException(e, null);
......
...@@ -79,25 +79,24 @@ import org.h2.value.ValueString; ...@@ -79,25 +79,24 @@ import org.h2.value.ValueString;
*/ */
public class PageStore implements CacheWriter { 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 fix page format of data overflow and so on
// TODO implement checksum; 0 for empty pages // 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 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 utf-x: test if it's faster
// TODO after opening the database, delay writing until required // 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: try to avoid allocating a byte array per page
// TODO optimization: check if calling Data.getValueLen slows things down // 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 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 // TODO detect circles in linked lists
// (input stream, free list, extend pages...) // (input stream, free list, extend pages...)
...@@ -105,16 +104,12 @@ public class PageStore implements CacheWriter { ...@@ -105,16 +104,12 @@ public class PageStore implements CacheWriter {
// synchronized correctly (on the index?) // synchronized correctly (on the index?)
// TODO remove trace or use isDebugEnabled // TODO remove trace or use isDebugEnabled
// TODO recover tool: don't re-do uncommitted operations // 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 don't store default values (store a special value)
// TODO split files (1 GB max size) // TODO split files (1 GB max size)
// TODO add a setting (that can be changed at runtime) to call fsync // TODO add a setting (that can be changed at runtime) to call fsync
// and delay on each commit // 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 check for file size (exception if not exact size expected)
// TODO implement missing code for STORE_BTREE_ROWCOUNT (maybe enable) // 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 online backup using bsdiff
// TODO when removing DiskFile: // TODO when removing DiskFile:
...@@ -1047,6 +1042,20 @@ public class PageStore implements CacheWriter { ...@@ -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. * Redo a change in a table.
* *
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论