sqlite源码分析之路(二) 数据库文件格式探索(7) 索引B树叶子节点分析

26 篇文章 2 订阅
9 篇文章 1 订阅

引子

书接上回,前面分析了三种B树节点的结构,现在还剩下最后一种。说实话,我是宁愿写代码也懒得写文档的人。因为写代码有编译器帮你检查错误 ,写文档就只有自已检查错误。而我又经常犯一些超低级错误,写在文档里让人看见,真是很没有面子。可是现在能坐在电脑前的时间越来越少,再不抓紧时间写点东西。以后就是想写,也是有心无力了。树欲静而风不止,人欲睡而电不停,奈何!奈何!

正式开始

上一篇文章说到只要在数据库中建立了索引,就会产生索引B树节点,上一次先通过数据库的第一页找到索引对象的根页号,然后检查这个根页号,发现这一页果然就是索引B树内部节点。
咱们将这一部分结果再看一下:

PageNo -> 5
0x0000 -> Flags : 2[0x0002][IndexBTreeInterior]
0x0001 -> offseFirstFreeblock : 0
0x0003 -> numberOfCells : 2
0x0005 -> firstByteOfCellContent : 966[0x03c6]
0x0007 -> numberOfFragmentedFreeBytes : 0
0x0008 -> RightChildPageNo : 10

cellPointArrayOffset->12[0x000c]
cellCount->2

leafPageNo->8[0x0008]
col1 type:text     size:20     -> 43240219900103600066
col2 type:i8       size:1      -> 66

leafPageNo->9[0x0009]
col1 type:text     size:20     -> 43240219900103800040
col2 type:i8       size:1      -> 40

从上面最后三行可以看出9号页是5号页的孩子,我们怀疑这个9号就是索引B树叶子节点。其实它不是叶子节点也没有关系,咱们就一直这样追踪下去,一定会找到叶子节点。它毕竟是一个深度有限的B树,又不是一个无底洞。

下面就是对9号页的分析结果

PageNo -> 9
0x0000 -> Flags : 10[0x000a][IndexBTreeLeaf]
0x0001 -> offseFirstFreeblock : 0
0x0003 -> numberOfCells : 36
0x0005 -> firstByteOfCellContent : 125[0x007d]
0x0007 -> numberOfFragmentedFreeBytes : 0
0x0008 -> RightChildPageNo : 0

cellPointArrayOffset->8[0x0008]
cellCount->36

col1 type:text     size:20     -> 43240219900103600068
col2 type:i8       size:1      -> 68

col1 type:text     size:20     -> 43240219900103600073
col2 type:i8       size:1      -> 73

col1 type:text     size:20     -> 43240219900103600076
col2 type:i8       size:1      -> 76

col1 type:text     size:20     -> 43240219900103600079
col2 type:i8       size:1      -> 79

col1 type:text     size:20     -> 43240219900103600082
col2 type:i8       size:1      -> 82

col1 type:text     size:20     -> 43240219900103600087
col2 type:i8       size:1      -> 87

col1 type:text     size:20     -> 43240219900103600088
col2 type:i8       size:1      -> 88

col1 type:text     size:19     -> 4324021990010360009
col2 type:i8       size:1      -> 9

col1 type:text     size:20     -> 43240219900103600090
col2 type:i8       size:1      -> 90

col1 type:text     size:20     -> 43240219900103600092
col2 type:i8       size:1      -> 92

col1 type:text     size:20     -> 43240219900103600094
col2 type:i8       size:1      -> 94

col1 type:text     size:20     -> 43240219900103700016
col2 type:i8       size:1      -> 16

col1 type:text     size:20     -> 43240219900103700020
col2 type:i8       size:1      -> 20

col1 type:text     size:20     -> 43240219900103700022
col2 type:i8       size:1      -> 22

col1 type:text     size:20     -> 43240219900103700025
col2 type:i8       size:1      -> 25

col1 type:text     size:20     -> 43240219900103700026
col2 type:i8       size:1      -> 26

col1 type:text     size:20     -> 43240219900103700032
col2 type:i8       size:1      -> 32

col1 type:text     size:20     -> 43240219900103700051
col2 type:i8       size:1      -> 51

col1 type:text     size:20     -> 43240219900103700059
col2 type:i8       size:1      -> 59

col1 type:text     size:20     -> 43240219900103700064
col2 type:i8       size:1      -> 64

col1 type:text     size:20     -> 43240219900103700069
col2 type:i8       size:1      -> 69

col1 type:text     size:20     -> 43240219900103700075
col2 type:i8       size:1      -> 75

col1 type:text     size:20     -> 43240219900103700078
col2 type:i8       size:1      -> 78

col1 type:text     size:20     -> 43240219900103700081
col2 type:i8       size:1      -> 81

col1 type:text     size:20     -> 43240219900103700086
col2 type:i8       size:1      -> 86

col1 type:text     size:20     -> 43240219900103700089
col2 type:i8       size:1      -> 89

col1 type:text     size:20     -> 43240219900103700096
col2 type:i8       size:1      -> 96

col1 type:text     size:20     -> 43240219900103700097
col2 type:i8       size:1      -> 97

col1 type:text     size:20     -> 43240219900103800010
col2 type:i8       size:1      -> 10

col1 type:text     size:20     -> 43240219900103800012
col2 type:i8       size:1      -> 12

col1 type:text     size:20     -> 43240219900103800017
col2 type:i8       size:1      -> 17

col1 type:text     size:20     -> 43240219900103800023
col2 type:i8       size:1      -> 23

col1 type:text     size:20     -> 43240219900103800033
col2 type:i8       size:1      -> 33

col1 type:text     size:20     -> 43240219900103800034
col2 type:i8       size:1      -> 34

col1 type:text     size:20     -> 43240219900103800038
col2 type:i8       size:1      -> 38

col1 type:text     size:20     -> 43240219900103800039
col2 type:i8       size:1      -> 39

哈哈,内容还真不少,从结果的第二行可以看出,这真是一个索引B树叶子节点。看来这个B树的深度只有2,也就是说只要搜索两个以上的节点就能找到想要的内容。索引真是一个好东西。
从结果上看, 索引B树叶子节点与 索引B树内部节点很像,只是少了一个孩子指针,因为它不需要,已经到底了。game over了。

上索引B树叶子节点的分析代码吧

//解包表索引B树(B树)叶子节点的单元内容
function unpackIndexBTreeLeafCell($workBench){

//参数区开始------------------------------------
	$fin = $workBench['fin'];
	$pageNo = $workBench['pageNo'];
	$cellNo = $workBench['cellNo'];
	$cellOffset = $workBench['cellOffset'];
	$outputPath = $workBench['outputPath'];
//参数区结束------------------------------------

	fseek($fin, $cellOffset,SEEK_SET);
	//找到cell入口后,第一部分是变长整数,代表payload的大小

	$PayloadOffset = 0;
	$PayloadSize = readValueFromFile($fin, 'var','varInt',$info);

	//echo 'PayloadSize->',intWithHexStr($PayloadSize),"\n";
	
	$PayloadOffset +=$info['size'];	
	//echo 'PayloadOffset(in cell)->',intWithHexStr($PayloadOffset),"\n";

	//设置输出结果的文件名
	$resultFileName = $outputPath .'/page'.$pageNo.'-cell'.$cellNo.'-payload.json';

	//--------------------------------------------------------------------------
	//设置工作区参数
	$newWorkBench['fin'] = $fin;
	$newWorkBench['PayloadOffset'] = $cellOffset + $PayloadOffset;		
	$newWorkBench['resultFileName'] = $resultFileName;

	//解包B树节点的payload内容(payload结构与页类型无关)
	unpackBTreePayLoad($newWorkBench);
}

到目前为止,sqlite B树的4种类型的页节点都已经分析完成,就此收工。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值