写入记录相对读取来说就复杂多了
Tchdbput 接口来写入记录,首先对整个DB进行读锁定,调用tchdbbidx 来获取hash bucket index 和hash,然后对index对应的树进行写锁定,接着调用tchdbputimpl 进行记录写入。
Tchdbputimpl 首先tchdbgetbucket获取首个节点的偏移,随后也是和读取记录相同的查找记录。
如果能找到记录,根据处置方式处理记录,有如下几种节点处理方式:
HDBPDOVER, // overwrite an existing value
HDBPDKEEP, // keep the existing value
HDBPDCAT, // concatenate values
HDBPDADDINT, // add an integer
HDBPDADDDBL, // add a real number
HDBPDPROC // process by a callback function
如果找不到节点,则先调用tchdbfbpsearch 找一个空闲块,如果找到的空闲块过大(超过需要空间的2倍)则会把余下部分重新加入空闲池。也算是节约点空间吧,呵呵。
找到合适的空闲节点后调用tchdbwriterec把记录写入数据库文件。
tchdbwriterec写入记录的时候如果发现原先记录块的大小过大(超过UINT16_MAX )就会把多余部分加入空闲池,如果原先记录块的大小不够就比较麻烦了。
大小不够的时先调用tchdbfbpsplice 合并空闲块,如果能成功合并相邻块(估计成功机会很小),就重新调用tchdbwriterec写入记录。如果合并失败就回收当前记录块,从空闲池重新查找空闲块,重新调用tchdbwriterec写入记录。