一种hashtable 实现的使用介绍

阅读代码上瘾了么?又看到一份代码,觉得很符合自己的风格,就贴上来。

 
  
/* implementation of a simple hash table
* -- thread safe functions as *_safe()
* -- resolve collisions by chaining
* Direct comments, concerns, questions, bugs to:
* kulesh [squiggly] isis.poly.edu
*/
该实现考虑到了线程安排,与STL的hashtable思想一致,都是基于resolve collisions by chaining(用开链解决冲突)。

hash节点定义

 
  
struct hash_entry {
struct list_head list;
unsigned
char * key;
unsigned
int keylen;
};
 
  
/* a hash_table contains buckets full of hash_entries (See above).
* keycmp() is used to compare the keys of hash_entries
*/
struct hash_table {
struct hash_entry * table; // 竖向的vector 容量为b

unsigned
int buckets;
pthread_mutex_t
* bucket_locks; // 锁 容量为b

pthread_mutex_t
lock ;
keycmp_ptr keycmp;

/* private variables */
unsigned
int __ht_i;
struct list_head * pos;
};

private域的作用是遍历用的。

锁对外界是不可见的,对于要上锁的话,库提供了__safe()函数来实现。例如insert函数

ContractedBlock.gif ExpandedBlockStart.gif hash_table_insert
 
   
/* insert_hash_table()
* @h: &struct hash_table hash table to insert hash_entry into
* @e: &struct hash_entry
* Description: inserts @e into @h using @e->key as key. not thread-safe.
*/
void hash_table_insert( struct hash_table * h,
struct hash_entry * e,
const unsigned char * key, unsigned int len);


/* insert_hash_table_safe()
* @h: &struct hash_table hash table to insert hash_entry into
* @e: &struct hash_entry
* @key: use key to insert the hash_entry
* @len: length of the key
* Description: inserts @e into @h using @e->key as key. thread-safe.
*/
void hash_table_insert_safe( struct hash_table * h,
struct hash_entry * e,
const unsigned char * key, unsigned int len);

请参看注释。下面代码不给出注释了。

重要接口函数如下

 
  
int hash_table_init( struct hash_table * h,
            unsigned
int b,
keycmp_ptr keycmp);
void hash_table_finit( struct hash_table * h);

int hash_entry_init( struct hash_entry * e,
const unsigned char * str,
            unsigned
int len);
void hash_entry_finit( struct hash_entry * e);

void hash_table_insert( struct hash_table * h,
             
struct hash_entry * e,
              
const unsigned char * key,
              unsigned
int len);

struct hash_entry * hash_table_lookup_key( const struct hash_table * h,
                        
const unsigned char * str,
                        unsigned
int len);

struct hash_entry * hash_table_del_key( struct hash_table * h,
                      
const char * str,
                      unsigned
int len);

类似于linux list实现的宏接口

ContractedBlock.gif for_each
 
   
/* *
* hash_entry - get the user data for this entry
* @ptr: the &struct hash_entry pointer
* @type: the type of the user data (e.g. struct my_data) embedded in this entry
* @member: the name of the hash_entry within the struct (e.g. entry)
*/
hash_entry(ptr, type, member);

/*
* @hentry: &struct hash_entry
* @htable: &struct hash_table
*/
#define hash_table_for_each(hentry, htable)

/*
* @hentry: &struct hash_entry
* @htable: &struct hash_table
* @pos: &struct list_head
* @hti: unsigned int
*/
hash_table_for_each_safe(hentry, htable, pos, hti)

个人觉得,还可以开放的接口(其实现添加了static inline),这个注释里面提到了,传递来的struct hash_entry,而不是str类型。当然传递的应该是一个有hash_entry_init生成的合法struct hash_entry。

 
  
/* same as hash_table_lookup_key() but this function takes a valid hash_entry as input.
* a valid hash_entry is the one that has key, len set appropriately. in other words, a
* hash_entry that is the output of hash_entry_init()
*/
struct hash_entry * hash_table_lookup_hash_entry( const struct hash_table * h,
        const struct hash_entry * e)

源代码中给出了示例。与list实现数据域与节点域分离的原则,要引用hashtable,直接包含其即可,实现数据域与指针域的结合。

定义如下

 
  
struct myitem {
struct hash_entry entry;
unsigned
char foo[ 32 ];
unsigned
int bar;
};

注意作者这里为了方便,用foo保存了hash_entry中的key信息。

初始化hash_table

 
  
struct hash_table mytable;
/* initialize the hash table with 10 buckets */
hash_table_init(
& mytable, 10 , NULL);
插入hash_entry
 
  
tmp = ( struct myitem * )malloc( sizeof ( struct myitem));
/* *一些初始化 */
hash_table_insert(
& mytable, & tmp -> entry, str, len);

遍历节点

 
  
hash_table_for_each(hentry, & mytable) {
tmp
= hash_entry(hentry, struct myitem, entry);
fprintf(stdout,
" key: %s[%d] (%d)\n " , tmp -> foo, tmp -> bar,
hash_table_hash_code(
& mytable, tmp -> foo,
strlen(tmp
-> foo)));
}

别忘记了释放空间——其内部元素的分配都是malloc机制的。

 
  
/* finitialze the hash table */
hash_table_finit(
& mytable);

下载代码 hashtable

转载于:https://www.cnblogs.com/westfly/archive/2011/04/07/2007839.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值