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