有了前面的基础,本节讲解插入数据的流程.
插入数据的实现代码,在函数tchdbputimpl中,首先这个函数会查找要插入记录的key是否已经存在,如果存在了,有很多case需要处理,在这里就不一一关注了,仅关注缺省的行为:如果key已经存在,那么覆盖原来的记录.否则,就插入新的记录.
所以,这里仅关注最简单的两种情况:如果存在就覆盖,如果不存在则插入新的记录.
1) 覆盖原记录
这里又区分两种情况:
a) 原有记录的尺寸不够插入新的记录,比如原有的记录是10个字节,但是新的记录需要20字节.这时候,首先会去调用上一节提到的tchdbfbpsplice
函数去尝试着合并该记录邻近的空闲记录形成一个更大尺寸的记录块,上一节中没有仔细说明这个函数.tchdbfbpsplice
的伪码大致如下:
当还有空闲块可以合并
继续合并空闲块
如果合并之后的尺寸仍然不能满足要求,返回false
如果合并之后的尺寸大于所要求尺寸的两倍
将多余的部分写入合适的freepool中
返回true,表示找到合适的块
所以,假如合并成功有足够的尺寸,那么就直接将新的记录写入就好了.
否则,如果不能够满足又合并不到更大的块,则会将原先的记录块首先写入到freepool中(tchdbwritefb函数
),接着直接在当前的freepool中查找合适的块(tchdbfbpsearch函数),如果找到合适的块,那么也写入新的记录即可.否则,上面的合并和查找空闲块的操作都失败了,则需要增加数据库文件的尺寸插入新的记录了.
b) 原有记录足够插入新的记录
这种情况下,还要判断旧的尺寸对于新的记录是不是过大了,过大的话也需要调整.
2) 新增新的记录
这种情况的处理很简单了,可以看作是上面的情况a)的一种情况,即接着直接在当前的freepool中查找合适的块(tchdbfbpsearch函数),如果找到合适的块,那么也写入新的记录即可.否则,则需要增加数据库文件的尺寸插入新的记录了.
注意,在上面的查找freepool过程中,如果失败的话,将增加一个计数,当这个计数大于一个值时,将对整个freepool做一个调整,调整算法前一节已经提及.
以上,就是插入新纪录的两种最简单情况的流程,如果对之前的freepool管理很清楚的话,理解起来不是难事,因为插入新的记录主要还是考虑如何回收利用原有的空闲块罢了.