Glustefs里面有一个很有意思的数据结构叫做rbthash, 全称是red black tree hash, 顾名思义就是使用红黑树做的哈希, 这个数据结构在io-cache xlator的实现中用到。
首先,有红黑树数据结构(contirb/rbtree), 它是从libavl库中偷过来的。虽然红黑树有点复杂,但是是相当经典的数据结构,有很多资料可以参考,这里就不展开了。
然后,在rbthash_table里面有很多buckets,在算法中称为桶(比如桶排序), 每一个桶里面都长着一棵红黑树。(让我想到植物大战僵尸屋顶那关)。
插入时,先使用哈希函数获得某个entry的哈希值,然后通过一个模运算将entry投入对应桶内, 然后再插入到红黑树上。
nbucket = entry->keyhash % tbl->numbuckets
函数rbthash_comparator会被传给红黑树,它用于比较entry。
比较过程如下:先比较长度,如果长度相同,则使用memcmp来比较大小。
if (e1->keylen != e2->keylen) { if (e1->keylen < e2->keylen) ret = -1; else if (e1->keylen > e2->keylen) ret = 1; } else ret = memcmp (e1->key, e2->key, e1->keylen);
查找时,同样先用哈希值找到桶,然后再在桶里面的红黑树中查找。
此外, iocache 在使用rbthash时候,哈希函数是一个十分简单的函数,如下:
inline uint32_t ioc_hashfn (void *data, int len) { off_t offset; offset = *(off_t *) data; return (offset >> ioc_log2_page_size); }
最后一行是一个求页号(Page Frame)的运算。所以,页号做为hash值使用。