类图: org.h2.util.CacheObject (此类中的pos字段就是PageBtreeLeaf的pageId) org.h2.store.Page org.h2.index.PageBtree org.h2.index.PageBtreeLeaf CacheObject的直接子类只有org.h2.util.CacheHead和org.h2.store.Page org.h2.store.Page类定义了8种页面类型,分别对应8个子类: 页面类型id 页面名称 对应的类 ------------------------------------------------------------------ 0 TYPE_EMPTY 有没类,主要用于异常或其他情况 1 TYPE_DATA_LEAF org.h2.index.PageDataLeaf 2 TYPE_DATA_NODE org.h2.index.PageDataNode 3 TYPE_DATA_OVERFLOW org.h2.index.PageDataOverflow 4 TYPE_BTREE_LEAF org.h2.index.PageBtreeLeaf 5 TYPE_BTREE_NODE org.h2.index.PageBtreeNode 6 TYPE_FREE_LIST org.h2.store.PageFreeList 7 TYPE_STREAM_TRUNK org.h2.store.PageStreamTrunk 8 TYPE_STREAM_DATA org.h2.store.PageStreamData ------------------------------------------------------------------ PageDataLeaf、PageBtreeLeaf、PageBtreeNode这三者可以在页面类型字段中加上FLAG_LAST FLAG_LAST表示此页是最后一页。 org.h2.util.CacheObject的字段有: public CacheObject cachePrevious public CacheObject cacheNext public CacheObject cacheChained private int pos private boolean changed org.h2.store.Page的字段有: protected int changeCount; 两个抽象方法: moveTo(Session, int) //移动当前page到新的位置 write() //写当前页面的数据到硬盘 提供了三类static方法,add、insert、remove,用于从数据中给原有元素加上一个(可能是负值)、增加一个新元素、删除一个元素 这类方法多用于在rows数组和offsets、keys数组中,rows用于放记录,offsets用于放记录在page中的相对位置,keys用于放记录的key。 org.h2.index.PageBtree的字段有: protected final PageBtreeIndex index protected int parentPageId protected final Data data protected int[] offsets protected int entryCount protected SearchRow[] rows protected int start protected boolean onlyPosition protected boolean written protected int memoryEstimated org.h2.index.PageBtreeLeaf的字段有: private final boolean optimizeUpdate; private boolean writtenData; 以下是格式分析 ------------------------------------------------------------------ 字节数 代表什么 头 ======================= 1 type 有两值(Page.TYPE_BTREE_LEAF | Page.FLAG_LAST(最后一页)) 或 Page.TYPE_BTREE_LEAF 2 checksum 预先写0,在写完page后回填(见org.h2.store.PageStore.writePage(int, Data)) 4 parentPageId VarInt index对象id(注意,不是表对象id,PageDataLeaf才是表对象id) 2 entryCount (行数) 体: ======================= entryCount个 { 2 offset } entryCount个 { (从offset开始写) columnCount个 { VarLong key Value 索引列值 (如果onlyPosition为true,那么不包含这一部分,只有前面的VarLong key) } } 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] [Console output redirected to file:E:\H2\tmp\myout.java] TCP server running at tcp://169.254.252.117:9092 (only local connections) PageBtreeNode { pageId = 8 parentPageId = 0 childPageIds = 81, 80, 92, 105 childPageIds.length = 4 entryCount = 3 rows = { ( /* key:16 */ 16, '1000000016', null) ( /* key:32 */ 32, '1000000032', null) ( /* key:48 */ 48, '1000000048', null) } PageBtreeNode { pageId = 81 parentPageId = 8 childPageIds = 55, 54 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:8 */ 8, '1000000008', null) } PageBtreeNode { pageId = 55 parentPageId = 81 childPageIds = 45, 44 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:4 */ 4, '1000000004', null) } PageBtreeLeaf { indexId = 15 parentPageId = 55 pageId = 45 start = 18 offsets = 115, 102, 89, 76 entryCount = 4 rows = { ( /* key:1 */ 1, '1000000001', null) ( /* key:2 */ 2, '1000000002', null) ( /* key:3 */ 3, '1000000003', null) ( /* key:4 */ 4, '1000000004', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 55 pageId = 44 start = 18 offsets = 115, 102, 89, 76 entryCount = 4 rows = { ( /* key:5 */ 5, '1000000005', null) ( /* key:6 */ 6, '1000000006', null) ( /* key:7 */ 7, '1000000007', null) ( /* key:8 */ 8, '1000000008', null) } } } PageBtreeNode { pageId = 54 parentPageId = 81 childPageIds = 47, 48 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:12 */ 12, '1000000012', null) } PageBtreeLeaf { indexId = 15 parentPageId = 54 pageId = 47 start = 18 offsets = 115, 102, 89, 76 entryCount = 4 rows = { ( /* key:9 */ 9, '1000000009', null) ( /* key:10 */ 10, '1000000010', null) ( /* key:11 */ 11, '1000000011', null) ( /* key:12 */ 12, '1000000012', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 54 pageId = 48 start = 18 offsets = 115, 102, 89, 75 entryCount = 4 rows = { ( /* key:13 */ 13, '1000000013', null) ( /* key:14 */ 14, '1000000014', null) ( /* key:15 */ 15, '1000000015', null) ( /* key:16 */ 16, '1000000016', null) } } } } PageBtreeNode { pageId = 80 parentPageId = 8 childPageIds = 60, 65 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:24 */ 24, '1000000024', null) } PageBtreeNode { pageId = 60 parentPageId = 80 childPageIds = 50, 52 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:20 */ 20, '1000000020', null) } PageBtreeLeaf { indexId = 15 parentPageId = 60 pageId = 50 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:17 */ 17, '1000000017', null) ( /* key:18 */ 18, '1000000018', null) ( /* key:19 */ 19, '1000000019', null) ( /* key:20 */ 20, '1000000020', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 60 pageId = 52 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:21 */ 21, '1000000021', null) ( /* key:22 */ 22, '1000000022', null) ( /* key:23 */ 23, '1000000023', null) ( /* key:24 */ 24, '1000000024', null) } } } PageBtreeNode { pageId = 65 parentPageId = 80 childPageIds = 56, 58 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:28 */ 28, '1000000028', null) } PageBtreeLeaf { indexId = 15 parentPageId = 65 pageId = 56 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:25 */ 25, '1000000025', null) ( /* key:26 */ 26, '1000000026', null) ( /* key:27 */ 27, '1000000027', null) ( /* key:28 */ 28, '1000000028', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 65 pageId = 58 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:29 */ 29, '1000000029', null) ( /* key:30 */ 30, '1000000030', null) ( /* key:31 */ 31, '1000000031', null) ( /* key:32 */ 32, '1000000032', null) } } } } PageBtreeNode { pageId = 92 parentPageId = 8 childPageIds = 70, 75 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:40 */ 40, '1000000040', null) } PageBtreeNode { pageId = 70 parentPageId = 92 childPageIds = 61, 63 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:36 */ 36, '1000000036', null) } PageBtreeLeaf { indexId = 15 parentPageId = 70 pageId = 61 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:33 */ 33, '1000000033', null) ( /* key:34 */ 34, '1000000034', null) ( /* key:35 */ 35, '1000000035', null) ( /* key:36 */ 36, '1000000036', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 70 pageId = 63 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:37 */ 37, '1000000037', null) ( /* key:38 */ 38, '1000000038', null) ( /* key:39 */ 39, '1000000039', null) ( /* key:40 */ 40, '1000000040', null) } } } PageBtreeNode { pageId = 75 parentPageId = 92 childPageIds = 66, 68 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:44 */ 44, '1000000044', null) } PageBtreeLeaf { indexId = 15 parentPageId = 75 pageId = 66 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:41 */ 41, '1000000041', null) ( /* key:42 */ 42, '1000000042', null) ( /* key:43 */ 43, '1000000043', null) ( /* key:44 */ 44, '1000000044', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 75 pageId = 68 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:45 */ 45, '1000000045', null) ( /* key:46 */ 46, '1000000046', null) ( /* key:47 */ 47, '1000000047', null) ( /* key:48 */ 48, '1000000048', null) } } } } PageBtreeNode { pageId = 105 parentPageId = 8 childPageIds = 82, 87, 93, 98, 106 childPageIds.length = 5 entryCount = 4 rows = { ( /* key:56 */ 56, '1000000056', null) ( /* key:64 */ 64, '1000000064', null) ( /* key:72 */ 72, '1000000072', null) ( /* key:80 */ 80, '1000000080', null) } PageBtreeNode { pageId = 82 parentPageId = 105 childPageIds = 71, 73 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:52 */ 52, '1000000052', null) } PageBtreeLeaf { indexId = 15 parentPageId = 82 pageId = 71 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:49 */ 49, '1000000049', null) ( /* key:50 */ 50, '1000000050', null) ( /* key:51 */ 51, '1000000051', null) ( /* key:52 */ 52, '1000000052', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 82 pageId = 73 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:53 */ 53, '1000000053', null) ( /* key:54 */ 54, '1000000054', null) ( /* key:55 */ 55, '1000000055', null) ( /* key:56 */ 56, '1000000056', null) } } } PageBtreeNode { pageId = 87 parentPageId = 105 childPageIds = 76, 78 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:60 */ 60, '1000000060', null) } PageBtreeLeaf { indexId = 15 parentPageId = 87 pageId = 76 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:57 */ 57, '1000000057', null) ( /* key:58 */ 58, '1000000058', null) ( /* key:59 */ 59, '1000000059', null) ( /* key:60 */ 60, '1000000060', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 87 pageId = 78 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:61 */ 61, '1000000061', null) ( /* key:62 */ 62, '1000000062', null) ( /* key:63 */ 63, '1000000063', null) ( /* key:64 */ 64, '1000000064', null) } } } PageBtreeNode { pageId = 93 parentPageId = 105 childPageIds = 83, 85 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:68 */ 68, '1000000068', null) } PageBtreeLeaf { indexId = 15 parentPageId = 93 pageId = 83 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:65 */ 65, '1000000065', null) ( /* key:66 */ 66, '1000000066', null) ( /* key:67 */ 67, '1000000067', null) ( /* key:68 */ 68, '1000000068', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 93 pageId = 85 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:69 */ 69, '1000000069', null) ( /* key:70 */ 70, '1000000070', null) ( /* key:71 */ 71, '1000000071', null) ( /* key:72 */ 72, '1000000072', null) } } } PageBtreeNode { pageId = 98 parentPageId = 105 childPageIds = 88, 90 childPageIds.length = 2 entryCount = 1 rows = { ( /* key:76 */ 76, '1000000076', null) } PageBtreeLeaf { indexId = 15 parentPageId = 98 pageId = 88 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:73 */ 73, '1000000073', null) ( /* key:74 */ 74, '1000000074', null) ( /* key:75 */ 75, '1000000075', null) ( /* key:76 */ 76, '1000000076', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 98 pageId = 90 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:77 */ 77, '1000000077', null) ( /* key:78 */ 78, '1000000078', null) ( /* key:79 */ 79, '1000000079', null) ( /* key:80 */ 80, '1000000080', null) } } } PageBtreeNode { pageId = 106 parentPageId = 105 childPageIds = 94, 96, 99, 101, 107 childPageIds.length = 5 entryCount = 4 rows = { ( /* key:84 */ 84, '1000000084', null) ( /* key:88 */ 88, '1000000088', null) ( /* key:92 */ 92, '1000000092', null) ( /* key:96 */ 96, '1000000096', null) } PageBtreeLeaf { indexId = 15 parentPageId = 106 pageId = 94 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:81 */ 81, '1000000081', null) ( /* key:82 */ 82, '1000000082', null) ( /* key:83 */ 83, '1000000083', null) ( /* key:84 */ 84, '1000000084', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 106 pageId = 96 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:85 */ 85, '1000000085', null) ( /* key:86 */ 86, '1000000086', null) ( /* key:87 */ 87, '1000000087', null) ( /* key:88 */ 88, '1000000088', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 106 pageId = 99 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:89 */ 89, '1000000089', null) ( /* key:90 */ 90, '1000000090', null) ( /* key:91 */ 91, '1000000091', null) ( /* key:92 */ 92, '1000000092', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 106 pageId = 101 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:93 */ 93, '1000000093', null) ( /* key:94 */ 94, '1000000094', null) ( /* key:95 */ 95, '1000000095', null) ( /* key:96 */ 96, '1000000096', null) } } PageBtreeLeaf { indexId = 15 parentPageId = 106 pageId = 107 start = 18 offsets = 114, 100, 86, 72 entryCount = 4 rows = { ( /* key:97 */ 97, '1000000097', null) ( /* key:98 */ 98, '1000000098', null) ( /* key:99 */ 99, '1000000099', null) ( /* key:100 */ 100, '1000000100', null) } } } } } ---------------------