有了前面的基礎(chǔ),本節(jié)講解插入數(shù)據(jù)的流程.
插入數(shù)據(jù)的實(shí)現(xiàn)代碼,在函數(shù)tchdbputimpl中,首先這個(gè)函數(shù)會(huì)查找要插入記錄的key是否已經(jīng)存在,如果存在了,有很多case需要處理,在這里就不一一關(guān)注了,僅關(guān)注缺省的行為:如果key已經(jīng)存在,那么覆蓋原來(lái)的記錄.否則,就插入新的記錄.
所以,這里僅關(guān)注最簡(jiǎn)單的兩種情況:如果存在就覆蓋,如果不存在則插入新的記錄.
1) 覆蓋原記錄
這里又區(qū)分兩種情況:
a) 原有記錄的尺寸不夠插入新的記錄,比如原有的記錄是10個(gè)字節(jié),但是新的記錄需要20字節(jié).這時(shí)候,首先會(huì)去調(diào)用上一節(jié)提到的tchdbfbpsplice
函數(shù)去嘗試著合并該記錄鄰近的空閑記錄形成一個(gè)更大尺寸的記錄塊,上一節(jié)中沒(méi)有仔細(xì)說(shuō)明這個(gè)函數(shù).tchdbfbpsplice
的偽碼大致如下:
當(dāng)還有空閑塊可以合并
繼續(xù)合并空閑塊
如果合并之后的尺寸仍然不能滿足要求,返回false
如果合并之后的尺寸大于所要求尺寸的兩倍
將多余的部分寫(xiě)入合適的freepool中
返回true,表示找到合適的塊
所以,假如合并成功有足夠的尺寸,那么就直接將新的記錄寫(xiě)入就好了.
否則,如果不能夠滿足又合并不到更大的塊,則會(huì)將原先的記錄塊首先寫(xiě)入到freepool中(tchdbwritefb函數(shù)
),接著直接在當(dāng)前的freepool中查找合適的塊(tchdbfbpsearch函數(shù)),如果找到合適的塊,那么也寫(xiě)入新的記錄即可.否則,上面的合并和查找空閑塊的操作都失敗了,則需要增加數(shù)據(jù)庫(kù)文件的尺寸插入新的記錄了.
b) 原有記錄足夠插入新的記錄
這種情況下,還要判斷舊的尺寸對(duì)于新的記錄是不是過(guò)大了,過(guò)大的話也需要調(diào)整.
2) 新增新的記錄
這種情況的處理很簡(jiǎn)單了,可以看作是上面的情況a)的一種情況,即接著直接在當(dāng)前的freepool中查找合適的塊(tchdbfbpsearch函數(shù)),如果找到合適的塊,那么也寫(xiě)入新的記錄即可.否則,則需要增加數(shù)據(jù)庫(kù)文件的尺寸插入新的記錄了.
注意,在上面的查找freepool過(guò)程中,如果失敗的話,將增加一個(gè)計(jì)數(shù),當(dāng)這個(gè)計(jì)數(shù)大于一個(gè)值時(shí),將對(duì)整個(gè)freepool做一個(gè)調(diào)整,調(diào)整算法前一節(jié)已經(jīng)提及.
以上,就是插入新紀(jì)錄的兩種最簡(jiǎn)單情況的流程,如果對(duì)之前的freepool管理很清楚的話,理解起來(lái)不是難事,因?yàn)椴迦胄碌挠涗浿饕€是考慮如何回收利用原有的空閑塊罷了.