tokyocabinet1.4.19阅读笔记(一)hash数据库概述


开始正式的研究key-value形式的持久化存储方案了,第一个阅读的项目是tokyo cabinet,版本号是1.4.19.

tokyo cabinet支持几种数据库形式,包括hash数据库,B+树数据库,fix-length数据库,table数据库。目前我仅看了第一种hash数据库的实现。之所以选择这个,是因为第一这种类型的数据库似乎是TC中使用的最多的一种,其次它的算法比之B+树又更简单一些而效率上的表现也丝毫不差。

看看TC中代码的组织。关于上面几个分类的数据库实现,实际上在TC项目的代码组织中各自以单个文件的形式出现,比如hash数据库的代码全都集中在 tchdb.c/h中,也只不过4000多行罢了。除去这几种数据库的实现文件,其余的代码文件功能可以大体上分为两类,一类是辅助性质的代码,给项目中各个部分使用上的,另一部分就是单独的管理数据库的CLI程序的代码,比如tchmgr.c/h就是用于管理HASH数据库的CLI程序的代码。之所以要交代一下项目中代码的组织,无非是为了说明,其实如果将问题集中在HASH数据库或者其他形式的数据库实现上,起码在TC中,所要关注的代码是不多的。

首先来看数据库文件是如何组织的。

从图中可以看到,hash数据库文件大致分为四个部分:数据库文件头,bucket 数组,free pool数组,最后的是真正存放record的部分。下面对这几部分做一个说明。

1)数据库文件头
数据库文件头部分存放的是关于该数据库的一些总体信息,包括这些内容:
nameoffsetlengthfeature
magic number032identification of the database. Begins with "ToKyO CaBiNeT"
database type321hash (0x01) / B+ tree (0x02) / fixed-length (0x03) / table (0x04)
additional flags331logical union of open (1<<0) and fatal (1<<1)
alignment power341the alignment size, by power of 2
free block pool power351the number of elements in the free block pool, by power of 2
options361logical union of large (1<<0), Deflate (1<<1), BZIP2 (1<<2), TCBS (1<<3), extra codec (1<<4)
bucket number408the number of elements of the bucket array
record number488the number of records in the database
file size568the file size of the database
first record648the offset of the first record
opaque region128128users can use this region arbitrarily

需要说明的是,上面这个表格来自tokyocabinet的官方文档说明,在 这里。同时,数据库文件中需要存放数据的地方,使用的都是小端方式存放的,以下就不再就这点做说明了。从上面的表格可以看出,数据库文件头的尺寸为256 bytes。
在操作hash数据库的所有API中,都会用到一个对象类型为TCHDB的指针,该结构体中存放的信息就包括了所有数据库文件头的内容,所以每次在打开或者创建一个hash数据库的时候,都会将数据库文件头信息读入到这个指针中(函数tchdbloadmeta)。

2)bucket 数组
bucket array中的每个元素都是一个整数,按照使用的是32位还是64位系统,存放的也就是32位或者64位的整数。这个数组存放的这个整数值,就是每次对 key 进行hash之后得到的hash值所对应的第一个元素在数据库文件中的偏移量。

3)free pool数组
free pool数组中的每个元素定义结构体如下:
typedef  struct  {                          //  type of structure for a free block
  uint64_t off;                           //  offset of the block
  uint32_t rsiz;                          //  size of the block
} HDBFB; 

很明显,仅有两个成员,一个存放的是在数据库文件中的偏移量,一个则是该free block的尺寸。free pool数组用于保存那些被删除的记录信息,以便于回收利用这些数据区,后续会针对free pool相关的操作,API做一个详细的分析。

4)record数据区
每个record数据区的结构如下表:
nameoffsetlengthfeature
magic number01identification of record block. always 0xC8
hash value11the hash value to decide the path of the hash chain
left chain24the alignment quotient of the destination of the left chain
right chain64the alignment quotient of the destination of the right chain
padding size102the size of the padding
key size12varythe size of the key
value sizevaryvarythe size of the value
keyvaryvarythe data of the key
valuevaryvarythe data of the value
paddingvaryvaryuseless data

当然,上面这个结构只是该record被使用时的结构图,当某一项record被删除时,它的结构就变为:
nameoffsetlengthfeature
magic number01identification of record block. always 0xB0
block size14size of the block
   
对比两种情况,首先是最开始的magic number是不同的,当magic number是0XB0也就是该record是已经被删除的free record时,那么紧跟着的4个字节存放的就是这个free record的尺寸,而record后面的部分可以忽略不计了。

分析完了hash数据库文件的几个组成部分,从最开始的数据库文件示意图中还看到,从文件头到bucket array这一部分将通过mmap映射到系统的共享内存中,当然,可以映射的内容可能不止到这里,但是,数据库文件头+bucket array这两部分是一定要映射到共享内存中的,也就是说,hash数据库中映射到共享内存中的内容上限没有限制,但是下限是文件头+bucket array部分。

同时,free pool也会通过malloc分配一个堆上的内存,存放到TCHDB的fbpool指针中。

这几部分(除了record zone),通过不同的方式都分别的读取到内存中,目的就是为了加快查找的速度,后面会详细的进行说明。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值