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

New experimental page store.

上级 7398ebec
...@@ -35,10 +35,17 @@ public class PageLog { ...@@ -35,10 +35,17 @@ public class PageLog {
this.firstPage = firstPage; this.firstPage = firstPage;
} }
/**
* Open the log file for writing. For an existing database, the recovery
* must be run first.
*/
void openForWriting() { void openForWriting() {
out = new DataOutputStream(new PageOutputStream(store, 0, firstPage, Page.TYPE_LOG)); out = new DataOutputStream(new PageOutputStream(store, 0, firstPage, Page.TYPE_LOG));
} }
/**
* Run the recovery process. Uncommitted transactions are rolled back.
*/
public void recover() throws SQLException { public void recover() throws SQLException {
DataInputStream in = new DataInputStream(new PageInputStream(store, 0, firstPage, Page.TYPE_LOG)); DataInputStream in = new DataInputStream(new PageInputStream(store, 0, firstPage, Page.TYPE_LOG));
DataPage data = store.createDataPage(); DataPage data = store.createDataPage();
...@@ -59,6 +66,13 @@ public class PageLog { ...@@ -59,6 +66,13 @@ public class PageLog {
} }
} }
/**
* Add an undo entry to the log. The page data is only written once until
* the next checkpoint.
*
* @param pageId the page id
* @param page the old page data
*/
public void addUndo(int pageId, DataPage page) throws SQLException { public void addUndo(int pageId, DataPage page) throws SQLException {
try { try {
if (undo.get(pageId)) { if (undo.get(pageId)) {
......
...@@ -33,6 +33,7 @@ import org.h2.util.ObjectArray; ...@@ -33,6 +33,7 @@ import org.h2.util.ObjectArray;
* </li><li>58-61: page number of the first free list page * </li><li>58-61: page number of the first free list page
* </li><li>62-65: number of free pages * </li><li>62-65: number of free pages
* </li><li>66-69: log head page number * </li><li>66-69: log head page number
* </li><li>70-73: last used page number
* </li></ul> * </li></ul>
*/ */
public class PageStore implements CacheWriter { public class PageStore implements CacheWriter {
...@@ -59,6 +60,7 @@ public class PageStore implements CacheWriter { ...@@ -59,6 +60,7 @@ public class PageStore implements CacheWriter {
private int freePageCount; private int freePageCount;
private int logRootPageId; private int logRootPageId;
private PageLog log; private PageLog log;
private int lastUsedPage;
/** /**
* Number of pages (including free pages). * Number of pages (including free pages).
...@@ -104,16 +106,21 @@ public class PageStore implements CacheWriter { ...@@ -104,16 +106,21 @@ public class PageStore implements CacheWriter {
file = database.openFile(fileName, accessMode, true); file = database.openFile(fileName, accessMode, true);
readHeader(); readHeader();
} else { } else {
isNew = true;
setPageSize(PAGE_SIZE_DEFAULT); setPageSize(PAGE_SIZE_DEFAULT);
file = database.openFile(fileName, accessMode, false); file = database.openFile(fileName, accessMode, false);
// page 0 is the file header
// page 1 is the root of the system table
pageCount = 2;
logRootPageId = allocatePage(); logRootPageId = allocatePage();
writeHeader(); writeHeader();
isNew = true;
} }
log = new PageLog(this, logRootPageId); log = new PageLog(this, logRootPageId);
fileLength = file.length(); fileLength = file.length();
pageCount = (int) (fileLength / pageSize); pageCount = (int) (fileLength / pageSize);
if (!isNew) {
log.recover(); log.recover();
}
log.openForWriting(); log.openForWriting();
} catch (SQLException e) { } catch (SQLException e) {
close(); close();
...@@ -127,6 +134,7 @@ public class PageStore implements CacheWriter { ...@@ -127,6 +134,7 @@ public class PageStore implements CacheWriter {
public void flush() throws SQLException { public void flush() throws SQLException {
synchronized (database) { synchronized (database) {
database.checkPowerOff(); database.checkPowerOff();
writeHeader();
ObjectArray list = cache.getAllChanged(); ObjectArray list = cache.getAllChanged();
CacheObject.sort(list); CacheObject.sort(list);
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
...@@ -165,6 +173,7 @@ public class PageStore implements CacheWriter { ...@@ -165,6 +173,7 @@ public class PageStore implements CacheWriter {
freeListRootPageId = fileHeader.readInt(); freeListRootPageId = fileHeader.readInt();
freePageCount = fileHeader.readInt(); freePageCount = fileHeader.readInt();
logRootPageId = fileHeader.readInt(); logRootPageId = fileHeader.readInt();
lastUsedPage = fileHeader.readInt();
} }
/** /**
...@@ -212,6 +221,7 @@ public class PageStore implements CacheWriter { ...@@ -212,6 +221,7 @@ public class PageStore implements CacheWriter {
fileHeader.writeInt(freeListRootPageId); fileHeader.writeInt(freeListRootPageId);
fileHeader.writeInt(freePageCount); fileHeader.writeInt(freePageCount);
fileHeader.writeInt(logRootPageId); fileHeader.writeInt(logRootPageId);
fileHeader.writeInt(lastUsedPage);
file.seek(FileStore.HEADER_LENGTH); file.seek(FileStore.HEADER_LENGTH);
file.write(fileHeader.getBytes(), 0, FILE_HEADER_SIZE - FileStore.HEADER_LENGTH); file.write(fileHeader.getBytes(), 0, FILE_HEADER_SIZE - FileStore.HEADER_LENGTH);
byte[] filler = new byte[pageSize - FILE_HEADER_SIZE]; byte[] filler = new byte[pageSize - FILE_HEADER_SIZE];
...@@ -254,8 +264,10 @@ public class PageStore implements CacheWriter { ...@@ -254,8 +264,10 @@ public class PageStore implements CacheWriter {
* Update a record. * Update a record.
* *
* @param record the record * @param record the record
* @param old the old data
*/ */
public void updateRecord(Record record, DataPage old) throws SQLException { public void updateRecord(Record record, DataPage old) throws SQLException {
int todoLogHeaderPageAsWell;
synchronized (database) { synchronized (database) {
record.setChanged(true); record.setChanged(true);
int pos = record.getPos(); int pos = record.getPos();
...@@ -280,9 +292,13 @@ public class PageStore implements CacheWriter { ...@@ -280,9 +292,13 @@ public class PageStore implements CacheWriter {
long newLength = (pageCount + INCREMENT_PAGES) * pageSize; long newLength = (pageCount + INCREMENT_PAGES) * pageSize;
file.setLength(newLength); file.setLength(newLength);
fileLength = newLength; fileLength = newLength;
freePageCount = INCREMENT_PAGES;
} }
return pageCount++; return pageCount++;
} }
if (lastUsedPage < pageCount) {
return lastUsedPage++;
}
if (freeListRootPageId == 0) { if (freeListRootPageId == 0) {
Message.throwInternalError(); Message.throwInternalError();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论