ITPub博客

首页 > 数据治理 > 数据治理 > 一个私有协议文件DB 的解析.

一个私有协议文件DB 的解析.

原创 数据治理 作者:babyyellow 时间:2019-11-21 09:56:19 0 删除 编辑

ip 地址库,  现在手机/web/app 的基础部件. 

LBS 应用的基础. 
在网络上找到了一个简单的私有协议的ip地址库部件. 
对ip地址的定位, 基本在 0.0x 毫秒 的效率. 
根据 项目介绍以及对应的代码 做了一个分析. 
项目地址:  https://github.com/lionsoul2014/ip2region/ 
里面有提到对应的文件协议的定义.
然后就根据这个协议直接读取了这个文件的二进制文件. 然后绕过了. 软件支持, 直接把数据读出来了. 
* 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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
oracle MySQL Postgresql 专职数据库dba。 系统架构师。 mysql 官方认知dba 。 15年专职dba 经验。

注册时间:2010-12-02

  • 博文量
    255
  • 访问量
    1499288