tokyo cabinet HDB – 读取&查找记录
tchdbget 首先对数据库读锁定,调用tchdbbidx 获取hash和bucket的index,这个算法分布是否均匀呢,没验证。看看代码吧:
static uint64_t tchdbbidx(TCHDB *hdb, const char *kbuf, int ksiz, uint8_t *hp){
assert(hdb && kbuf && ksiz >= 0 && hp);
uint64_t idx = 19780211;
uint32_t hash = 751;
const char *rp = kbuf + ksiz;
while(ksiz--){
idx = idx * 37 + *(uint8_t *)kbuf++;
hash = (hash * 31) ^ *(uint8_t *)--rp;
}
*hp = hash;
return idx % hdb->bnum;
}
随后对hash bucket下面index对应树进行读锁定,调用tchdbgetimpl读取记录。
Tchdbgetimpl 首先检查是否启用内存cache,如果启用就直接从内存cache取记录返回。从测试情况看内存cache不能提高性能,此外还要消耗额外内存,用的时候要谨慎。
调用tchdbgetbucket获取对应index的偏移,也是首条记录的偏移。使用二叉树来管理记录,如下所示来查找数据:
先比较节点的hash,然后在比较节点的key。这样树深度可能会比较大,之所以没做平衡树之类估计也是考虑复杂性方面的问题,无论怎样比链表要好些吧。所以用的时候最好hash bucket数目和总节点数比率不要太大,使树的深度不要太深,1:10估计问题不大。
记录的结构如下:
|
magic用来表示这个节点是否空闲
这里left,right视32位还是64位来定,使用8字节对齐。ksize,vsize使用7bit编码。
Hash
|
magic用来表示这个节点是否空闲
这里left,right视32位还是64位来定,使用8字节对齐。ksize,vsize使用7bit编码。