- 论坛徽章:
- 0
|
本帖最后由 wangzhen11aaa 于 2011-10-30 07:33 编辑
这是个比较初级的hash,因为一个cell只能存储一个key.如果是个链表就能存储相同的。。。。
- c = NEXT_CELL (c, cells, size);
- FOREACH_OCCUPIED_ADJACENT (c, cells, size)
- {
- const void *key2 = c->key;
- struct cell *c_new;
- /* Find the new location for the key. */
- c_new = cells + HASH_POSITION (key2, hasher, size);
- FOREACH_OCCUPIED_ADJACENT (c_new, cells, size)
- if (key2 == c_new->key)
- /* The cell C (key2) is already where we want it (in
- C_NEW's "chain" of keys.) */
- goto next_rehash;
- *c_new = *c;
- CLEAR_CELL (c);
- next_rehash:
- ;
- }
复制代码
- 首先,这个hashtable 的构造是
- 156 struct hash_table {
- 157 hashfun_t hash_function;
- 158 testfun_t test_function;
- 159
- 160 struct cell *cells; /*这个指针,用来分配一些空间来连续存储 value和key.(key就是要被hashfunction处理的那个值,value是要存储的那个地址*/
- 161 int size; /*这个size一开始被初始化为1 + items / HASH_MAX_FULLNESS;*/
- 162
- 163 int count; /*这个是计算这些数组中被占据的单元个数*/
- 164 int resize_threshold; /*如果占据的个数和总个数的比超过0.75,为了保证命中就grow或者resize hashtable*/
- 166 int prime_offset; /*这个是根据需要来扩展hash 中的cell数目,具体见prime_size()函数和 里面的那个数组是写死的,用来扩展数组。*/
- 168 };
复制代码
- 还有在首次创建hast_table中的hash_table_new()函数中。空项被设置为:
- 299 memset (ht->cells, INVALID_PTR_CHAR, size * sizeof (struct cell)); /*将所有的空项都设置成了0xff。*/
- 原因是key 值为0时可用,为-1表示为空。297 /* Mark cells as empty. We use 0xff rather than 0 to mark empty
- 298 keys because it allows us to use NULL/0 as keys. */
复制代码
- 199 #define FOREACH_OCCUPIED_ADJACENT(c, cells, size) \
- /*这里的意思是,它认为如果遇到空项(0xfffffffff)就代表后面没有可用的cell了,
- 后面所做的调整也是这个意思,就是如果从“中间”的某个位置删去了一个cell->key,那么得从新hash后面的值,原因如上。. */
- 200 for (; CELL_OCCUPIED (c); c = NEXT_CELL (c, cells, size)) /*这是一个for循环的头部*/
- 195 #define NEXT_CELL(c, cells, size) (c != cells + (size - 1) ? c + 1 : cells)
- /*这个定义,就是说,如果搜寻到最后仍然没有要找的那个cell,就接着从头开始找,你认为这里可能有个bug,就是如果满的话:这里没有可能的,如果你插入的话,就会检查那个
- 在hash_table_put()中,会更新这个array的值。
- 439 if (ht->count >= ht->resize_threshold)
- 440 {
- 441 grow_hash_table (ht);
- 442 c = find_cell (ht, key);
- 443 }
- 。
- */
复制代码
说完这些,应该就明白了吧。
具体的hash_function就是一些死的东西,没什么新奇的。:wink: |
|