字节数 代表什么
头
=======================
1 type 有两值(Page.TYPE_DATA_LEAF | Page.FLAG_LAST(最后一页)) 或 Page.TYPE_DATA_LEAF
2 checksum 预先写0,在写完page后回填(见org.h2.store.PageStore.writePage(int, Data))
4 parentPageId
VarInt index对象id(实际是表对象id)
VarInt columnCount
2 entryCount (行数)
体:
=======================
4 with overflow: the first overflow page id(如果firstOverflowPageId !=0)
entryCount个
{
VarLong key
2 offset
}
entryCount个
{ (从offset开始写)
columnCount个
{
column value
}
}
page size = 128
rowLength = 12
0 1 2 3 4 5 6 7 ... 116 117 118 119 120 121 122 123 124 125 126 127
( /* key:1 */ 1, 'abcdef1234')
116 117 118 119 120 121 122 123 124 125 126 127
1 10 a b c d e f 1 2 3 4
104 ... 115
( /* key:2 */ 2, 'abcdef1234')
92 ... 103
( /* key:3 */ 3, 'abcdef1234')
80 ... 91
( /* key:4 */ 4, 'abcdef1234')
68 ... 79
( /* key:5 */ 5, 'abcdef1234')
56 ... 67
( /* key:6 */ 6, 'abcdef1234')
44 ... 55
( /* key:7 */ 7, 'abcdef1234')
keys = [1, 2, 3, 4, 5, 6, 7, 0, 0, 0]
rows = [( /* key:1 */ 1, 'abcdef1234'), ( /* key:2 */ 2, 'abcdef1234'), ( /* key:3 */ 3, 'abcdef1234'), ( /* key:4 */ 4, 'abcdef1234'), ( /* key:5 */ 5, 'abcdef1234'), ( /* key:6 */ 6, 'abcdef1234'), ( /* key:7 */ 7, 'abcdef1234'), null, null, null]
offsets = [116, 104, 92, 80, 68, 56, 44, 0, 0, 0]
entryCount = 7
last = 44
rowLength = 12
start = 32
keyOffsetPairLen = 3
last - rowLength = 44 - 12 = 32
start + keyOffsetPairLen = 32 + 3 = 35
当前行: ( /* key:8 */ 8, 'abcdef1234')
也就是说先看看当前page(128字节)如果要存当前行的话是否有足够空间存keyOffsetPair,
因为当前行的长度是12,page中只剩下44个字节了(0到43),再存12个就只剩32个可用,
而start当前已经到32了,再存当前行的keyOffsetPair的话要多加3,则start位置移到35,超过剩余可用的32个字节了。
所以此时要对当前的PageDataLeaf进行切割。
if (entryCount > 0 && last - rowLength < start + keyOffsetPairLen) {
int x = findInsertionPoint(row.getKey()); //x = 7
if (entryCount > 1) {
if (entryCount < 5) {
// required, otherwise the index doesn't work correctly
return entryCount / 2;
}
if (index.isSortedInsertMode()) {
return x < 2 ? 1 : x > entryCount - 1 ? entryCount - 1 : x;
}
// split near the insertion point to better fill pages
// split in half would be:
// return entryCount / 2;
int third = entryCount / 3;
return x < third ? third : x >= 2 * third ? 2 * third : x; //返回4 (从rows[4]=( /* key:5 */ 5, 'abcdef1234')开始切割)
}
return x;
}
新的PageDataLeaf的
rows = [( /* key:5 */ 5, 'abcdef1234'), ( /* key:6 */ 6, 'abcdef1234'), ( /* key:7 */ 7, 'abcdef1234'), null, null, null]