leveldb源代碼分析系列1.3:變長編碼實現

leveldb中記錄user_key和user_value的相關結構使用「varint」編碼記錄其長度並置於首部,例如skiplist存儲的項entry,以及Put時WriteBatch存儲的批寫入數據格式,對user_key和user_value的長度都採用變長編碼。數據庫

這樣作的目的是節省存儲空間,若是採用固定字節的長度記錄,若是固定字節太大而大部分的key和value的長度只用一個或兩個字節的整形就能夠記錄,那麼就會形成不少浪費,反之若是固定字節過小則限制了數據庫存儲key和value的長度,因此採用變長編碼的方式能夠適合於各類狀況。app

leveldb中關於變長編碼和對應的解碼函數在文件util/coding.h和util/coding.cc中。主要有定長編碼/解碼和變長編碼/解碼系列函數,關於leveldb中的編碼策略,首先來看這個函數:函數

image.png

編碼後的格式,每一個字節分爲兩部分:最高位和其他位,最高位用來指示下一個字節是否仍是編碼存儲字節,若是是則爲1,不然爲0,剩餘的七位用來存儲具體數據。ui

將一個32位數字v編碼位可變長度,並存入以dst開頭的地址中,返回結果爲末尾存儲位的下一位地址。數據由高位到低位存儲。因爲最高位不用來存儲數據,因此一個uint32_t類型的數據最多會被編碼爲5個字節,固然,若是大部分數據編碼後都小於4個字節,仍是很賺的。編碼

這個函數還有一個64位版本,原理是一摸同樣的,你們本身去分析。spa

固定編碼很是簡單,只須要判斷系統是大端存儲仍是小端存儲,而後簡單的copy一下就能夠,此處略過。blog

對應的解碼函數:ip

image.png

從p開始解碼出數據並放入value中,首先判斷最高位是否爲1,若是是1意味着下一個字節中依然有數據存儲,經過|操做得到底七位數據,循環繼續。get

這兩個函數屬於底層函數,其之上有以下函數:input

image.png

put系列的函數將value編碼而後append進dst中,get系列函數從input中讀取數據解碼放入value中,低層都是調用了上面介紹的函數。

總的來講leveldb中的變長存儲這部分很清晰,不須要過多介紹。

相關文章
相關標籤/搜索