一個私有協議檔案DB 的解析.

babyyellow發表於2019-11-21

ip 地址庫,  現在手機/web/app 的基礎部件. 

LBS 應用的基礎. 
在網路上找到了一個簡單的私有協議的ip地址庫部件. 
對ip地址的定位, 基本在 0.0x 毫秒 的效率. 
根據 專案介紹以及對應的程式碼 做了一個分析. 
專案地址:  
裡面有提到對應的檔案協議的定義.
然後就根據這個協議直接讀取了這個檔案的二進位制檔案. 然後繞過了. 軟體支援, 直接把資料讀出來了. 
* db struct:
 * 1. header part
 * 1): super part:
 * +------------+-----------+
 * | 4 bytes | 4 bytes   |
 * +------------+-----------+
 *  start index ptr, end index ptr
 * 
 * 2): b-tree index part
 * +------------+-----------+-----------+-----------+
 * | 4bytes       | 4bytes | 4bytes | 4bytes | ...
 * +------------+-----------+-----------+-----------+
 *  start ip ptr  index ptr
 *  
 * 2. data part:
 * +------------+-----------------------+
 * | 2bytes | dynamic length |
 * +------------+-----------------------+
 *  data length   city_id|Country|Province|Area|City|ISP
 *  
 * 3. index part: (ip range)
 * +------------+-----------+---------------+
 * | 4bytes | 4bytes | 4bytes |
 * +------------+-----------+---------------+
 *  start ip    end ip   3 byte data ptr & 1 byte data length
結構就比較簡單. 
跟pg / oracle 的資料塊協議有相似之處. 
檔案開頭,   定義了一個了一個超級塊 ( supper  block )  兩個 4 位元組的  欄位. 
8個位元組,  儲存了 索引快 ( index block) 開始地址,  跟結束地址. 
為了支援btree 索引, 對index block 又構建另一個二級索引.   head -- index- block. 
對 索引塊,(index block) 按照 4K  分割槽, 抽取了ip地址的最小值 ,以及對應的 位置指標. 
具體的ip地址索引,  索引塊 ( index block)   12位元組  
start ip   :  4 bytes ;
end ip    :  4 bytes ;
 
dataptr   :  4 bytes  : { 
             datalenth    1 byte , 
             dataptr  :    3 bytes 
       } 
dataptr   儲存了對應IP地址段 的地區名稱,  以及 對應的 文字的儲存長度. 
對二進位制檔案的直接讀取,  到這裡, 就基本可以開工了. 
根據  supper block 的 定位到   start- index- block   以及last-index-block
然後構建一個迴圈.  
然後直接按照格式讀出來, 生成文字資料就可以了. 
i ( , (blkcnt) + ) :
     file.seek(sidx + i * idxblklen  )
     row = file.read(idxblklen )
     sip,eip,ptr,datlen =  getrow(row)
     fip, lip,cityid,city     = getdata(file,sip,eip,ptr,datlen )
     
     (%(L2ip(sip),L2ip(lip),city))

經過抽取, 發現 實際檔案儲存, 與java 版本的maker 的對吧.
檔案裡多了2筆記錄.  即 超級塊的位置定義上應該還是有一個bug.
實際上最後多出來的兩個 index-block  的內容是錯誤的.  是不能合在一個ip段裡面的.
程式碼部分提供的3種 搜尋方法. 
memory  search  /  binary search /btree - search   基本還是基於二分法的查詢.
還有一個問題. 這個maker 程式碼目前沒有實現 merge 功能, 每次都是隻能重建db 檔案.
如果要實現merge 功能, 即  增量資料的入庫.

需要考慮 . 索引分裂, 以及 head-index block 的重寫.  以及位置移動.

由此引發的一點小思考.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/133735/viewspace-2665083/,如需轉載,請註明出處,否則將追究法律責任。

相關文章