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

Page store: better memory usage calculation.

上级 4980f2e3
...@@ -253,8 +253,8 @@ public abstract class PageBtree extends Page { ...@@ -253,8 +253,8 @@ public abstract class PageBtree extends Page {
* @return number of double words (4 bytes) * @return number of double words (4 bytes)
*/ */
public int getMemorySize() { public int getMemorySize() {
// double the byte array size // four times the byte array size
return index.getPageStore().getPageSize() >> 1; return index.getPageStore().getPageSize();
} }
} }
...@@ -205,8 +205,8 @@ abstract class PageData extends Page { ...@@ -205,8 +205,8 @@ abstract class PageData extends Page {
* @return number of double words (4 bytes) * @return number of double words (4 bytes)
*/ */
public int getMemorySize() { public int getMemorySize() {
// double the byte array size // four times the byte array size
return index.getPageStore().getPageSize() >> 1; return index.getPageStore().getPageSize();
} }
int getParentPageId() { int getParentPageId() {
......
...@@ -65,6 +65,8 @@ public class PageDataLeaf extends PageData { ...@@ -65,6 +65,8 @@ public class PageDataLeaf extends PageData {
private int columnCount; private int columnCount;
private int memorySize;
private PageDataLeaf(PageScanIndex index, int pageId, Data data) { private PageDataLeaf(PageScanIndex index, int pageId, Data data) {
super(index, pageId, data); super(index, pageId, data);
} }
...@@ -185,6 +187,7 @@ public class PageDataLeaf extends PageData { ...@@ -185,6 +187,7 @@ public class PageDataLeaf extends PageData {
newOffsets[x] = offset; newOffsets[x] = offset;
newKeys[x] = row.getPos(); newKeys[x] = row.getPos();
newRows[x] = row; newRows[x] = row;
memorySize += row.getMemorySize();
offsets = newOffsets; offsets = newOffsets;
keys = newKeys; keys = newKeys;
rows = newRows; rows = newRows;
...@@ -237,6 +240,10 @@ public class PageDataLeaf extends PageData { ...@@ -237,6 +240,10 @@ public class PageDataLeaf extends PageData {
private void removeRow(int i) throws SQLException { private void removeRow(int i) throws SQLException {
written = false; written = false;
readAllRows(); readAllRows();
Row r = rows[i];
if (r != null) {
memorySize += r.getMemorySize();
}
entryCount--; entryCount--;
if (entryCount < 0) { if (entryCount < 0) {
Message.throwInternalError(); Message.throwInternalError();
...@@ -305,6 +312,7 @@ int checkRequired; ...@@ -305,6 +312,7 @@ int checkRequired;
rowRef = new SoftReference<Row>(r); rowRef = new SoftReference<Row>(r);
} else { } else {
rows[at] = r; rows[at] = r;
memorySize += r.getMemorySize();
} }
} }
return r; return r;
...@@ -484,4 +492,8 @@ int checkRequired; ...@@ -484,4 +492,8 @@ int checkRequired;
index.getPageStore().updateRecord(this, true, data); index.getPageStore().updateRecord(this, true, data);
} }
public int getMemorySize() {
return index.getMemorySizePerPage();
}
} }
...@@ -45,6 +45,7 @@ public class PageScanIndex extends PageIndex implements RowIndex { ...@@ -45,6 +45,7 @@ public class PageScanIndex extends PageIndex implements RowIndex {
private HashMap<Integer, Integer> sessionRowCount; private HashMap<Integer, Integer> sessionRowCount;
private int mainIndexColumn = -1; private int mainIndexColumn = -1;
private SQLException fastDuplicateKeyException; private SQLException fastDuplicateKeyException;
private int memorySizePerPage;
public PageScanIndex(TableData table, int id, IndexColumn[] columns, IndexType indexType, int headPos, Session session) throws SQLException { public PageScanIndex(TableData table, int id, IndexColumn[] columns, IndexType indexType, int headPos, Session session) throws SQLException {
initBaseIndex(table, id, table.getName() + "_TABLE_SCAN", columns, indexType); initBaseIndex(table, id, table.getName() + "_TABLE_SCAN", columns, indexType);
...@@ -81,6 +82,11 @@ public class PageScanIndex extends PageIndex implements RowIndex { ...@@ -81,6 +82,11 @@ public class PageScanIndex extends PageIndex implements RowIndex {
} }
table.setRowCount(rowCount); table.setRowCount(rowCount);
fastDuplicateKeyException = super.getDuplicateKeyException(); fastDuplicateKeyException = super.getDuplicateKeyException();
// estimate the memory usage as follows:
// the less column, the more memory is required, because the more rows fit on a page
memorySizePerPage = store.getPageSize();
int estimatedRowsPerPage = store.getPageSize() / ((1 + columns.length) * 8);
memorySizePerPage += estimatedRowsPerPage * 64;
} }
public SQLException getDuplicateKeyException() { public SQLException getDuplicateKeyException() {
...@@ -480,4 +486,8 @@ public class PageScanIndex extends PageIndex implements RowIndex { ...@@ -480,4 +486,8 @@ public class PageScanIndex extends PageIndex implements RowIndex {
return mainIndexColumn; return mainIndexColumn;
} }
int getMemorySizePerPage() {
return memorySizePerPage;
}
} }
...@@ -148,4 +148,8 @@ public class PageInputStream extends InputStream { ...@@ -148,4 +148,8 @@ public class PageInputStream extends InputStream {
return data.getPos(); return data.getPos();
} }
public void close() {
// nothing to do
}
} }
...@@ -8,6 +8,7 @@ package org.h2.store; ...@@ -8,6 +8,7 @@ package org.h2.store;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import org.h2.compress.CompressLZF; import org.h2.compress.CompressLZF;
...@@ -120,6 +121,7 @@ public class PageLog { ...@@ -120,6 +121,7 @@ public class PageLog {
private Data outBuffer; private Data outBuffer;
private PageInputStream pageIn; private PageInputStream pageIn;
private OutputStream pageBuffer;
private PageOutputStream pageOut; private PageOutputStream pageOut;
private DataReader in; private DataReader in;
private int firstTrunkPage; private int firstTrunkPage;
...@@ -180,6 +182,9 @@ public class PageLog { ...@@ -180,6 +182,9 @@ public class PageLog {
this.firstTrunkPage = firstTrunkPage; this.firstTrunkPage = firstTrunkPage;
pageOut = new PageOutputStream(store, firstTrunkPage, undoAll, atEnd); pageOut = new PageOutputStream(store, firstTrunkPage, undoAll, atEnd);
pageOut.reserve(1); pageOut.reserve(1);
// TODO maybe buffer to improve speed
pageBuffer = pageOut;
// pageBuffer = new BufferedOutputStream(pageOut, 8 * 1024);
store.setLogFirstPage(firstTrunkPage, pageOut.getCurrentDataPageId()); store.setLogFirstPage(firstTrunkPage, pageOut.getCurrentDataPageId());
outBuffer = store.createData(); outBuffer = store.createData();
} }
...@@ -226,6 +231,7 @@ public class PageLog { ...@@ -226,6 +231,7 @@ public class PageLog {
if (stage == RECOVERY_STAGE_ALLOCATE) { if (stage == RECOVERY_STAGE_ALLOCATE) {
PageInputStream in = new PageInputStream(store, firstTrunkPage, firstDataPage); PageInputStream in = new PageInputStream(store, firstTrunkPage, firstDataPage);
usedLogPages = in.allocateAllPages(); usedLogPages = in.allocateAllPages();
in.close();
return; return;
} }
pageIn = new PageInputStream(store, firstTrunkPage, firstDataPage); pageIn = new PageInputStream(store, firstTrunkPage, firstDataPage);
...@@ -465,7 +471,7 @@ public class PageLog { ...@@ -465,7 +471,7 @@ public class PageLog {
} }
private void flushOut() throws IOException { private void flushOut() throws IOException {
pageOut.write(outBuffer.getBytes(), 0, outBuffer.length()); pageBuffer.write(outBuffer.getBytes(), 0, outBuffer.length());
outBuffer.reset(); outBuffer.reset();
} }
...@@ -513,6 +519,7 @@ public class PageLog { ...@@ -513,6 +519,7 @@ public class PageLog {
} }
// store it on a separate log page // store it on a separate log page
int pageSize = store.getPageSize(); int pageSize = store.getPageSize();
flushBuffer();
pageOut.fillPage(); pageOut.fillPage();
outBuffer.writeByte((byte) PREPARE_COMMIT); outBuffer.writeByte((byte) PREPARE_COMMIT);
outBuffer.writeVarInt(session.getId()); outBuffer.writeVarInt(session.getId());
...@@ -522,6 +529,7 @@ public class PageLog { ...@@ -522,6 +529,7 @@ public class PageLog {
} }
flushOut(); flushOut();
// store it on a separate log page // store it on a separate log page
flushBuffer();
pageOut.fillPage(); pageOut.fillPage();
if (log.getFlushOnEachCommit()) { if (log.getFlushOnEachCommit()) {
flush(); flush();
...@@ -600,6 +608,7 @@ public class PageLog { ...@@ -600,6 +608,7 @@ public class PageLog {
*/ */
void flush() throws SQLException { void flush() throws SQLException {
try { try {
flushBuffer();
pageOut.flush(); pageOut.flush();
} catch (IOException e) { } catch (IOException e) {
throw Message.convertIOException(e, null); throw Message.convertIOException(e, null);
...@@ -619,6 +628,7 @@ public class PageLog { ...@@ -619,6 +628,7 @@ public class PageLog {
undo = new BitField(); undo = new BitField();
logSectionId++; logSectionId++;
logPos = 0; logPos = 0;
flushBuffer();
pageOut.fillPage(); pageOut.fillPage();
int currentDataPage = pageOut.getCurrentDataPageId(); int currentDataPage = pageOut.getCurrentDataPageId();
logSectionPageMap.put(logSectionId, currentDataPage); logSectionPageMap.put(logSectionId, currentDataPage);
...@@ -785,4 +795,12 @@ public class PageLog { ...@@ -785,4 +795,12 @@ public class PageLog {
sessionStates = New.hashMap(); sessionStates = New.hashMap();
} }
private void flushBuffer() throws SQLException {
try {
pageBuffer.flush();
} catch (IOException e) {
throw Message.convertIOException(e, null);
}
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论