现在解剖hash.c和findkey.c的源码。
(1)hash.c中的哈希函数int _gdm_hash(key)。返回一个31比特的值。这个值的前n比特用来对散列目录表进行索引。它也会用于在一个散列桶中查找桶元素的位置(通过与桶的散列表长度做模运算)。不要对函数中的计算过程有迷惑,它只是为了计算哈希值而设计的一个简单算法,主要用到了移位运算的模运算。
findkey.c中有两个函数_gdbm_read_entry和_gdbm_findkey。前者用于文件中读取需要的关键字,后者用于查找给定的关键字。
(2)char* _gdbm_read_entry(dbf,elem_loc)函数。在文件dbf中读取的实际的关键/数据项(注意数据是紧跟在关键字后面存储的,故一般把两者放在一起,返回其起始地址和大小),返回指向它的指针。数据项的大小、对应关键字等信息由桶的索引elem_loc处的缓存项给出,读取后也会把数据缓顾虑到这个缓存项中去。如果关键字/数据在当前缓存项中,则直接返回。否则,释放缓存中原先的存放数据、重新设置好缓存的参数、为要读取的数据分配空间、把数据读入到缓存中,返回指向数据的指针。
(3)int _gdm_findkey(dbf,key,dptr,new_hash_val)函数。在文件中查找关键字key,并准备读取其关联的数据。返回值为关键字在当前桶中所处的位置,而用dptr来返回关键字/数据的起始地址,用new_hash_val来返回关键字的哈希值。如果找到,则指向这个关键字和数据的指针返回给dptr。如果没有找到,返回-1。在查找时要计算关键字的hash值。程序先判断,如果key在当前缓存项,则直接返回它的地址和桶中位置。如果不在当前缓存项,则要搜索整个桶,对桶中的每个元素,比较桶元素的哈希值、关键字大小、关键字内容,若不相等则到下一个桶元素中去找;若相等,则根据桶元素中给出的位置信息调用_gdbm_read_entry从文件读取相应关键字,与key比较,相等则找到,返回,不相等则同样到下一个桶中去找。