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

Page store: simplify overflow format

上级 2bd33848
...@@ -52,8 +52,7 @@ public class PageBtreeIndex extends PageIndex { ...@@ -52,8 +52,7 @@ public class PageBtreeIndex extends PageIndex {
// it should not for new tables, otherwise redo of other operations // it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things // must ensure this page is not used for other things
store.addMeta(this, session); store.addMeta(this, session);
PageBtreeLeaf root = new PageBtreeLeaf(this, rootPageId, store.createData()); PageBtreeLeaf root = PageBtreeLeaf.create(this, rootPageId, PageBtree.ROOT);
root.parentPageId = PageBtree.ROOT;
store.updateRecord(root, true, root.data); store.updateRecord(root, true, root.data);
} else { } else {
rootPageId = store.getRootPageId(id); rootPageId = store.getRootPageId(id);
...@@ -131,8 +130,7 @@ public class PageBtreeIndex extends PageIndex { ...@@ -131,8 +130,7 @@ public class PageBtreeIndex extends PageIndex {
PageBtree getPage(int id) throws SQLException { PageBtree getPage(int id) throws SQLException {
PageBtree p = (PageBtree) store.getPage(id); PageBtree p = (PageBtree) store.getPage(id);
if (p == null) { if (p == null) {
Data data = store.createData(); PageBtreeLeaf empty = PageBtreeLeaf.create(this, id, PageBtree.ROOT);
PageBtreeLeaf empty = new PageBtreeLeaf(this, id, data);
return empty; return empty;
} }
return p; return p;
...@@ -245,8 +243,7 @@ public class PageBtreeIndex extends PageIndex { ...@@ -245,8 +243,7 @@ public class PageBtreeIndex extends PageIndex {
private void removeAllRows() throws SQLException { private void removeAllRows() throws SQLException {
PageBtree root = getPage(rootPageId); PageBtree root = getPage(rootPageId);
root.freeChildren(); root.freeChildren();
root = new PageBtreeLeaf(this, rootPageId, store.createData()); root = PageBtreeLeaf.create(this, rootPageId, PageBtree.ROOT);
root.parentPageId = PageBtree.ROOT;
store.removeRecord(rootPageId); store.removeRecord(rootPageId);
store.updateRecord(root, true, null); store.updateRecord(root, true, null);
rowCount = 0; rowCount = 0;
......
...@@ -18,21 +18,21 @@ import org.h2.store.Page; ...@@ -18,21 +18,21 @@ import org.h2.store.Page;
import org.h2.store.PageStore; import org.h2.store.PageStore;
/** /**
* A b-tree leaf page that contains index data. * A b-tree leaf page that contains index data. Format:
* Format: * <ul>
* <ul><li>parent page id (0 for root): int * <li>parent page id (0 for root): int</li>
* </li><li>page type: byte * <li>page type: byte</li>
* </li><li>index id: varInt * <li>index id: varInt</li>
* </li><li>entry count: short * <li>entry count: short</li>
* </li><li>list of offsets: short * <li>list of offsets: short</li>
* </li><li>data (key: varLong, value,...) * <li>data (key: varLong, value,...)</li>
* </li></ul> * </ul>
*/ */
public class PageBtreeLeaf extends PageBtree { public class PageBtreeLeaf extends PageBtree {
private static final int OFFSET_LENGTH = 2; private static final int OFFSET_LENGTH = 2;
PageBtreeLeaf(PageBtreeIndex index, int pageId, Data data) { private PageBtreeLeaf(PageBtreeIndex index, int pageId, Data data) {
super(index, pageId, data); super(index, pageId, data);
} }
......
...@@ -19,17 +19,17 @@ import org.h2.store.PageStore; ...@@ -19,17 +19,17 @@ import org.h2.store.PageStore;
import org.h2.util.MemoryUtils; import org.h2.util.MemoryUtils;
/** /**
* A b-tree node page that contains index data. * A b-tree node page that contains index data. Format:
* Format: * <ul>
* <ul><li>parent page id (0 for root): int * <li>parent page id (0 for root): int</li>
* </li><li>page type: byte * <li>page type: byte</li>
* </li><li>index id: varInt * <li>index id: varInt</li>
* </li><li>count of all children (-1 if not known): int * <li>count of all children (-1 if not known): int</li>
* </li><li>entry count: short * <li>entry count: short</li>
* </li><li>rightmost child page id: int * <li>rightmost child page id: int</li>
* </li><li>entries (child page id: int, offset: short) * <li>entries (child page id: int, offset: short) The row contains the largest
* The row contains the largest key of the respective child, meaning * key of the respective child, meaning row[0] contains the largest key of
* row[0] contains the largest key of child[0]. * child[0].
*/ */
public class PageBtreeNode extends PageBtree { public class PageBtreeNode extends PageBtree {
...@@ -70,7 +70,7 @@ public class PageBtreeNode extends PageBtree { ...@@ -70,7 +70,7 @@ public class PageBtreeNode extends PageBtree {
* @param parentPageId the parent page id * @param parentPageId the parent page id
* @return the page * @return the page
*/ */
public static PageBtreeNode create(PageBtreeIndex index, int pageId, int parentPageId) { static PageBtreeNode create(PageBtreeIndex index, int pageId, int parentPageId) {
PageBtreeNode p = new PageBtreeNode(index, pageId, index.getPageStore().createData()); PageBtreeNode p = new PageBtreeNode(index, pageId, index.getPageStore().createData());
p.parentPageId = parentPageId; p.parentPageId = parentPageId;
p.writeHead(); p.writeHead();
......
...@@ -19,17 +19,17 @@ import org.h2.store.Page; ...@@ -19,17 +19,17 @@ import org.h2.store.Page;
import org.h2.store.PageStore; import org.h2.store.PageStore;
/** /**
* A leaf page that contains data of one or multiple rows. * A leaf page that contains data of one or multiple rows. Format:
* Format: * <ul>
* <ul><li>parent page id (0 for root): int * <li>parent page id (0 for root): int</li>
* </li><li>page type: byte * <li>page type: byte</li>
* </li><li>table id: varInt * <li>table id: varInt</li>
* </li><li>column count: varInt * <li>column count: varInt</li>
* </li><li>entry count: short * <li>entry count: short</li>
* </li><li>with overflow: the first overflow page id: int * <li>with overflow: the first overflow page id: int</li>
* </li><li>list of key / offset pairs (key: varLong, offset: shortInt) * <li>list of key / offset pairs (key: varLong, offset: shortInt)</li>
* </li><li>data * <li>data</li>
* </li></ul> * </ul>
*/ */
public class PageDataLeaf extends PageData { public class PageDataLeaf extends PageData {
...@@ -223,7 +223,7 @@ public class PageDataLeaf extends PageData { ...@@ -223,7 +223,7 @@ public class PageDataLeaf extends PageData {
size = pageSize - PageDataOverflow.START_MORE; size = pageSize - PageDataOverflow.START_MORE;
next = index.getPageStore().allocatePage(); next = index.getPageStore().allocatePage();
} }
PageDataOverflow overflow = new PageDataOverflow(index, page, type, previous, next, all, dataOffset, size); PageDataOverflow overflow = PageDataOverflow.create(index.getPageStore(), page, type, previous, next, all, dataOffset, size);
index.getPageStore().updateRecord(overflow, true, null); index.getPageStore().updateRecord(overflow, true, null);
dataOffset += size; dataOffset += size;
remaining -= size; remaining -= size;
...@@ -295,6 +295,7 @@ public class PageDataLeaf extends PageData { ...@@ -295,6 +295,7 @@ public class PageDataLeaf extends PageData {
PageDataOverflow page = index.getPageOverflow(next); PageDataOverflow page = index.getPageOverflow(next);
next = page.readInto(buff); next = page.readInto(buff);
} while (next != 0); } while (next != 0);
int checkRequired;
overflowRowSize = pageSize + buff.length(); overflowRowSize = pageSize + buff.length();
buff.setPos(0); buff.setPos(0);
r = index.readRow(buff, columnCount); r = index.readRow(buff, columnCount);
......
...@@ -19,18 +19,18 @@ import org.h2.store.PageStore; ...@@ -19,18 +19,18 @@ import org.h2.store.PageStore;
import org.h2.util.MemoryUtils; import org.h2.util.MemoryUtils;
/** /**
* A leaf page that contains data of one or multiple rows. * A leaf page that contains data of one or multiple rows. Format:
* Format: * <ul>
* <ul><li>parent page id (0 for root): int * <li>parent page id (0 for root): int</li>
* </li><li>page type: byte * <li>page type: byte</li>
* </li><li>table id: varInt * <li>table id: varInt</li>
* </li><li>count of all children (-1 if not known): int * <li>count of all children (-1 if not known): int</li>
* </li><li>entry count: short * <li>entry count: short</li>
* </li><li>rightmost child page id: int * <li>rightmost child page id: int</li>
* </li><li>entries (key: varLong, child page id: int) * <li>entries (key: varLong, child page id: int)</li>
* </li></ul> * </ul>
* The key is the largest key of the respective child, meaning * The key is the largest key of the respective child, meaning key[0] is the
* key[0] is the largest key of child[0]. * largest key of child[0].
*/ */
public class PageDataNode extends PageData { public class PageDataNode extends PageData {
......
...@@ -16,34 +16,33 @@ import org.h2.store.Page; ...@@ -16,34 +16,33 @@ import org.h2.store.Page;
import org.h2.store.PageStore; import org.h2.store.PageStore;
/** /**
* Overflow data for a leaf page. * Overflow data for a leaf page. Format:
* Format: * <ul>
* <ul><li>0-3: parent page id (0 for root): int * <li>parent page id (0 for root): int (0-3)</li>
* </li><li>4-4: page type: byte * <li>page type: byte (4)</li>
* </li><li>5-8: table id: int * <li>more data: next overflow page id: int (5-8)</li>
* </li><li>9-12: if more data: next overflow page id: int * <li>last remaining size: short (5-6)</li>
* </li><li>9-10: else remaining size: short * <li>data (9-/7-)</li>
* </li><li>data * </ul>
* </li></ul>
*/ */
public class PageDataOverflow extends Page { public class PageDataOverflow extends Page {
/** /**
* The start of the data in the last overflow page. * The start of the data in the last overflow page.
*/ */
static final int START_LAST = 11; static final int START_LAST = 7;
/** /**
* The start of the data in a overflow page that is not the last one. * The start of the data in a overflow page that is not the last one.
*/ */
static final int START_MORE = 13; static final int START_MORE = 9;
private static final int START_NEXT_OVERFLOW = 9; private static final int START_NEXT_OVERFLOW = 5;
/** /**
* The index. * The page store.
*/ */
private final PageScanIndex index; private final PageStore store;
/** /**
* The page type. * The page type.
...@@ -53,38 +52,17 @@ public class PageDataOverflow extends Page { ...@@ -53,38 +52,17 @@ public class PageDataOverflow extends Page {
/** /**
* The parent page (overflow or leaf). * The parent page (overflow or leaf).
*/ */
private int parentPage; private int parentPageId;
/** /**
* The next overflow page, or 0. * The next overflow page, or 0.
*/ */
private int nextPage; private int nextPage;
/**
* The number of content bytes.
*/
private int size;
private Data data; private Data data;
PageDataOverflow(PageScanIndex index, int pageId, int type, int previous, int next, Data allData, int offset, int size) { private int start;
this.index = index; private int size;
setPos(pageId);
this.type = type;
this.parentPage = previous;
this.nextPage = next;
this.size = size;
data = index.getPageStore().createData();
data.writeInt(parentPage);
data.writeByte((byte) type);
data.writeInt(index.getId());
if (type == Page.TYPE_DATA_OVERFLOW) {
data.writeInt(nextPage);
} else {
data.writeShortInt(size);
}
data.write(allData.getBytes(), offset, size);
}
/** /**
* Create an object from the given data page. * Create an object from the given data page.
...@@ -94,8 +72,8 @@ public class PageDataOverflow extends Page { ...@@ -94,8 +72,8 @@ public class PageDataOverflow extends Page {
* @param data the data page * @param data the data page
* @param offset the offset * @param offset the offset
*/ */
PageDataOverflow(PageScanIndex index, int pageId, Data data) { private PageDataOverflow(PageStore store, int pageId, Data data) {
this.index = index; this.store = store;
setPos(pageId); setPos(pageId);
this.data = data; this.data = data;
} }
...@@ -103,39 +81,66 @@ public class PageDataOverflow extends Page { ...@@ -103,39 +81,66 @@ public class PageDataOverflow extends Page {
/** /**
* Read an overflow page. * Read an overflow page.
* *
* @param index the index * @param store the page store
* @param data the data * @param data the data
* @param pageId the page id * @param pageId the page id
* @return the page * @return the page
*/ */
public static Page read(PageScanIndex index, Data data, int pageId) throws SQLException { public static Page read(PageStore store, Data data, int pageId) throws SQLException {
PageDataOverflow p = new PageDataOverflow(index, pageId, data); PageDataOverflow p = new PageDataOverflow(store, pageId, data);
p.read(); p.read();
return p; return p;
} }
/**
* Create a new overflow page.
*
* @param store the page store
* @param page the page id
* @param type the page type
* @param parentPageId the parent page id
* @param next the next page or 0
* @param all the data
* @param offset the offset within the data
* @param size the number of bytes
* @return the page
*/
static PageDataOverflow create(PageStore store, int page, int type, int parentPageId, int next, Data all, int offset, int size) {
Data data = store.createData();
PageDataOverflow p = new PageDataOverflow(store, page, data);
data.writeInt(parentPageId);
data.writeByte((byte) type);
if (type == Page.TYPE_DATA_OVERFLOW) {
data.writeInt(next);
} else {
data.writeShortInt(size);
}
p.start = data.length();
data.write(all.getBytes(), offset, size);
p.type = type;
p.parentPageId = parentPageId;
p.nextPage = next;
p.size = size;
return p;
}
/** /**
* Read the page. * Read the page.
*/ */
private void read() throws SQLException { private void read() throws SQLException {
data.reset(); data.reset();
parentPage = data.readInt(); parentPageId = data.readInt();
type = data.readByte(); type = data.readByte();
int indexId = data.readInt();
if (indexId != index.getId()) {
throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1,
"page:" + getPos() + " expected index:" + index.getId() +
" got:" + indexId + " type:" + type);
}
if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) { if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) {
size = data.readShortInt(); size = data.readShortInt();
nextPage = 0; nextPage = 0;
} else if (type == Page.TYPE_DATA_OVERFLOW) { } else if (type == Page.TYPE_DATA_OVERFLOW) {
size = index.getPageStore().getPageSize() - START_MORE;
nextPage = data.readInt(); nextPage = data.readInt();
size = store.getPageSize() - data.length();
} else { } else {
throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1, "page:" + getPos() + " type:" + type); throw Message.getSQLException(ErrorCode.FILE_CORRUPTED_1, "page:" + getPos() + " type:" + type);
} }
start = data.length();
} }
/** /**
...@@ -159,15 +164,33 @@ public class PageDataOverflow extends Page { ...@@ -159,15 +164,33 @@ public class PageDataOverflow extends Page {
} }
public int getByteCount(DataPage dummy) { public int getByteCount(DataPage dummy) {
return index.getPageStore().getPageSize(); return store.getPageSize();
}
private void writeHead() {
data.writeInt(parentPageId);
data.writeByte((byte) type);
} }
public void write(DataPage buff) throws SQLException { public void write(DataPage buff) throws SQLException {
index.getPageStore().writePage(getPos(), data); write();
store.writePage(getPos(), data);
}
private void write() {
data.reset();
writeHead();
if (type == Page.TYPE_DATA_OVERFLOW) {
data.writeInt(nextPage);
} else {
data.writeShortInt(size);
}
} }
public String toString() { public String toString() {
return "page[" + getPos() + "] data leaf overflow parent:" + parentPage + " next:" + nextPage; return "page[" + getPos() + "] data leaf overflow parent:" + parentPageId + " next:" + nextPage;
} }
/** /**
...@@ -177,29 +200,27 @@ public class PageDataOverflow extends Page { ...@@ -177,29 +200,27 @@ public class PageDataOverflow extends Page {
*/ */
public int getMemorySize() { public int getMemorySize() {
// double the byte array size // double the byte array size
return index.getPageStore().getPageSize() >> 1; return store.getPageSize() >> 1;
} }
void setParentPageId(int parent) { void setParentPageId(int parent) {
this.parentPage = parent; this.parentPageId = parent;
} }
public void moveTo(Session session, int newPos) throws SQLException { public void moveTo(Session session, int newPos) throws SQLException {
PageStore store = index.getPageStore(); PageDataOverflow p2 = PageDataOverflow.create(store, newPos, type, parentPageId, nextPage, data, start, size);
int start = type == Page.TYPE_DATA_OVERFLOW ? START_MORE : START_LAST;
PageDataOverflow p2 = new PageDataOverflow(index, newPos, type, parentPage, nextPage, data, start, size);
store.updateRecord(p2, false, null); store.updateRecord(p2, false, null);
if (nextPage != 0) { if (nextPage != 0) {
PageDataOverflow p3 = (PageDataOverflow) store.getPage(nextPage); PageDataOverflow p3 = (PageDataOverflow) store.getPage(nextPage);
p3.setParentPageId(newPos); p3.setParentPageId(newPos);
} }
Page p = store.getPage(parentPage); Page p = store.getPage(parentPageId);
if (p == null) { if (p == null) {
throw Message.throwInternalError(); throw Message.throwInternalError();
} }
if (p instanceof PageDataOverflow) { if (p instanceof PageDataOverflow) {
PageDataOverflow p1 = (PageDataOverflow) p; PageDataOverflow p1 = (PageDataOverflow) p;
p1.setOverflow(newPos); p1.setNext(newPos);
} else { } else {
PageDataLeaf p1 = (PageDataLeaf) p; PageDataLeaf p1 = (PageDataLeaf) p;
p1.setOverflow(newPos); p1.setOverflow(newPos);
...@@ -207,10 +228,10 @@ public class PageDataOverflow extends Page { ...@@ -207,10 +228,10 @@ public class PageDataOverflow extends Page {
store.freePage(getPos(), true, data); store.freePage(getPos(), true, data);
} }
private void setOverflow(int nextPage) throws SQLException { private void setNext(int nextPage) throws SQLException {
this.nextPage = nextPage; this.nextPage = nextPage;
data.setInt(START_NEXT_OVERFLOW, nextPage); data.setInt(START_NEXT_OVERFLOW, nextPage);
index.getPageStore().updateRecord(this, true, data); store.updateRecord(this, true, data);
} }
} }
...@@ -15,9 +15,9 @@ import org.h2.util.BitField; ...@@ -15,9 +15,9 @@ import org.h2.util.BitField;
* The list of free pages of a page store. The format of a free list trunk page * The list of free pages of a page store. The format of a free list trunk page
* is: * is:
* <ul> * <ul>
* <li>0-3: parent page id (always 0)</li> * <li>parent page id (always 0): int</li>
* <li>4-4: page type</li> * <li>page type: byte</li>
* <li>5-remainder: data</li> * <li>data (5-)</li>
* </ul> * </ul>
*/ */
public class PageFreeList extends Page { public class PageFreeList extends Page {
......
...@@ -79,15 +79,15 @@ import org.h2.value.ValueString; ...@@ -79,15 +79,15 @@ import org.h2.value.ValueString;
*/ */
public class PageStore implements CacheWriter { public class PageStore implements CacheWriter {
// TODO delete: only log the key // TODO fix page format of ..
// TODO log: use varInt / varLong
// TODO update: only log the key and changed values // 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 implement checksum; 0 for empty pages
// TODO undo log: fully compress empty pages // TODO undo log: (option) fully compress empty pages
// TODO undo log: don't store empty space between head and data // TODO undo log: don't store empty space between head and data
// TODO undo log: lzf compression // 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 maybe remove parent pointer
// TODO index creation: use less space (ordered, split at insertion point) // TODO index creation: use less space (ordered, split at insertion point)
// TODO test running out of disk space (using a special file system) // TODO test running out of disk space (using a special file system)
...@@ -467,12 +467,7 @@ public class PageStore implements CacheWriter { ...@@ -467,12 +467,7 @@ public class PageStore implements CacheWriter {
break; break;
} }
case Page.TYPE_DATA_OVERFLOW: { case Page.TYPE_DATA_OVERFLOW: {
int indexId = data.readInt(); p = PageDataOverflow.read(this, data, pageId);
PageScanIndex index = (PageScanIndex) metaObjects.get(indexId);
if (index == null) {
Message.throwInternalError("index not found " + indexId);
}
p = PageDataOverflow.read(index, data, pageId);
break; break;
} }
case Page.TYPE_BTREE_LEAF: { case Page.TYPE_BTREE_LEAF: {
......
...@@ -12,10 +12,10 @@ import org.h2.engine.Session; ...@@ -12,10 +12,10 @@ import org.h2.engine.Session;
/** /**
* A data page of a stream. The format is: * A data page of a stream. The format is:
* <ul> * <ul>
* <li>0-3: the trunk page id</li> * <li>the trunk page id: int (0-3)</li>
* <li>4-4: page type</li> * <li>page type: byte (4)</li>
* <li>5-8: the number of bytes used</li> * <li>the number of bytes used: short (5-6)</li>
* <li>9-remainder: data</li> * <li>data (9-)</li>
* </ul> * </ul>
*/ */
public class PageStreamData extends Page { public class PageStreamData extends Page {
......
...@@ -10,19 +10,19 @@ import java.sql.SQLException; ...@@ -10,19 +10,19 @@ import java.sql.SQLException;
import org.h2.engine.Session; import org.h2.engine.Session;
/** /**
* A trunk page of a stream. It contains the page numbers of the stream, and * A trunk page of a stream. It contains the page numbers of the stream, and the
* the page number of the next trunk. The format is: * page number of the next trunk. The format is:
* <ul> * <ul>
* <li>0-3: the last trunk page, or 0 if none</li> * <li>previous trunk page, or 0 if none: int (0-3)</li>
* <li>4-4: page type</li> * <li>page type: byte (4)</li>
* <li>5-8: the next trunk page</li> * <li>next trunk page: int (5-8)</li>
* <li>9-12: the number of pages</li> * <li>number of pages (9-10)</li>
* <li>13-remainder: page ids</li> * <li>remainder: page ids (11-)</li>
* </ul> * </ul>
*/ */
public class PageStreamTrunk extends Page { public class PageStreamTrunk extends Page {
private static final int DATA_START = 13; private static final int DATA_START = 11;
private final PageStore store; private final PageStore store;
private int parent; private int parent;
...@@ -83,7 +83,7 @@ public class PageStreamTrunk extends Page { ...@@ -83,7 +83,7 @@ public class PageStreamTrunk extends Page {
parent = data.readInt(); parent = data.readInt();
data.readByte(); data.readByte();
nextTrunk = data.readInt(); nextTrunk = data.readInt();
pageCount = data.readInt(); pageCount = data.readShortInt();
pageIds = new int[pageCount]; pageIds = new int[pageCount];
for (int i = 0; i < pageCount; i++) { for (int i = 0; i < pageCount; i++) {
pageIds[i] = data.readInt(); pageIds[i] = data.readInt();
...@@ -121,7 +121,7 @@ public class PageStreamTrunk extends Page { ...@@ -121,7 +121,7 @@ public class PageStreamTrunk extends Page {
data.writeInt(parent); data.writeInt(parent);
data.writeByte((byte) Page.TYPE_STREAM_TRUNK); data.writeByte((byte) Page.TYPE_STREAM_TRUNK);
data.writeInt(nextTrunk); data.writeInt(nextTrunk);
data.writeInt(pageCount); data.writeShortInt(pageCount);
for (int i = 0; i < pageCount; i++) { for (int i = 0; i < pageCount; i++) {
data.writeInt(pageIds[i]); data.writeInt(pageIds[i]);
} }
......
...@@ -1201,7 +1201,6 @@ public class Recover extends Tool implements DataHandler { ...@@ -1201,7 +1201,6 @@ public class Recover extends Tool implements DataHandler {
store.readFully(s2.getBytes(), 0, pageSize); store.readFully(s2.getBytes(), 0, pageSize);
s2.setPos(4); s2.setPos(4);
int type = s2.readByte(); int type = s2.readByte();
int indexId = s2.readInt();
if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) { if (type == (Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST)) {
int size = s2.readShortInt(); int size = s2.readShortInt();
writer.println("-- chain: " + next + " type: " + type + " size: " + size); writer.println("-- chain: " + next + " type: " + type + " size: " + size);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论