#define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)\
do {\
hash_cell_t* cell3333;\//实际上就是void*
TYPE* struct3333;\ //lock_t* struct3333;
\
HASH_ASSERT_OWN(TABLE, FOLD)\//断言不考虑
\
(DATA)->NAME = NULL;\//lock->hash = NULL;
\
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\
\
if (cell3333->node == NULL) {\ //如果为NULL没有元素挂载到这个cell下
cell3333->node = DATA;\ //则我们挂载到这个cell下
} else {\
struct3333 = (TYPE*) cell3333->node;\ //否则说明有元素了取到这个元素的指针 lock_t* struct3333 = (lock_t*)cell3333->node;
\
while (struct3333->NAME != NULL) {\ //如果struct3333->hash 不等于NULL 说明他下面有元素了
\
struct3333 = (TYPE*) struct3333->NAME;\ //那么我们需要做的是指针像链表下一个元素移动
}\
\
struct3333->NAME = DATA;\ //最后找到链表末尾 将数据节点挂载到下面 struct3333->hash = lock(lock是lock_t*)
}\
} while (0)
六、删除一个元素
这部分也是通过宏定义来做的如下,我写了详细的解释
/*******************************************************************//**
Deletes a struct from a hash table. */
/*
有了上面基础也就比较简单了,这里直接在代码进行注释
HASH_DELETE(lock_t, hash, lock_sys->rec_hash,lock_rec_fold(space, page_no), in_lock);
*/
#define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)\
do {\
hash_cell_t* cell3333;\//实际上就是void*
TYPE* struct3333;\ //lock_t* struct3333;
\
HASH_ASSERT_OWN(TABLE, FOLD)\//断言不考虑
\
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\//通过函数hash_get_nth_cell计算这个值在哪个cell也就是hash 桶中
\
if (cell3333->node == DATA) {\ //地址比较,如果地址相同其地址必然相同
HASH_ASSERT_VALID(DATA->NAME);\//断言不考虑
cell3333->node = DATA->NAME;\//如果找到 将指针移动到下一个元素 言外之意这里去掉了一个内存单元就是找到的那个
} else {\
struct3333 = (TYPE*) cell3333->node;\ //链表循环找
\
while (struct3333->NAME != DATA) {\
\
struct3333 = (TYPE*) struct3333->NAME;\
ut_a(struct3333);\
}\
\
struct3333->NAME = DATA->NAME;\ //最终找到 就做 链表去掉这个内存元素动作
}\
//最终这里涉及到一个问题就是释放问题,但是注意虽然这个数据的指针在链表中去掉了,但是指针本身还在,可以拿到做free即可
HASH_INVALIDATE(DATA, NAME);\ //debug版本使用不考虑
} while (0)
七、其他
其他函数还包含:
HASH_SEARCH_ALL:宏实现在整个hash表中查找一个元素,相当于真个cell个链表查找
HASH_SEARCH:宏实现在有建值的情况下查找一个元素、言外之意cell(桶)确定了,相当于链表查找
hash_table_clear: 清空一个hash表
就不详细解释了,当然我只是对基本实现和常用的方法进行了描述,其他方面遇到再说吧。