ever
# need more, and you will still get good results with a smaller table.
hash table size : 7001
注释中(以#开头的语句),说明hash table size必须为质数(prime),然而源代 码中却需要保证这个值为2的指数。我想出现前后矛盾的原因大概和MudOS版 本差异有关:比较早的版本使用的是hashstr 函数 ,这个函数在后续的寻址操作中用的是“%” 求模运算,而使用质数作为hash table的大小在解决碰撞的效率上要好些(猜测如此,未经求证),因此这些mudlib的config文件就一直沿用这些传统;目前比较新的MudOS版本采用的是whashstr 函数,其后续的寻址操作——正如之前介绍的,用的是“&”按位与运算,这 必然要求hash table的大小必须为2的指数。 散列表的实现
有了前面分析的散列函数和宏,本文将以object table为 例,来实现一个hash table,object table实 现的源码参见最新发布的MudOS源码 (v22.2b14)中的otable.c。下面这些代码与源码有差异,这么做的 原因是为了不牵涉到具体应用,而仅仅是单纯的实现一个hash table。
/* hashtable.h */
#if !defined(_HASH_TABLE_H_)
#define _HASH_TABLE_H_
#define STRING_SIZE 64
typedef struct object_s {
char name[STRING_SIZE];
struct object_s *next_hash;
char value[STRING_SIZE];
} object_t;
void init_otable();
void clear_otable();
void enter_object_hash(object_t *);
void remove_object_hash(object_t *);
object_t *lookup_object_hash(char *);
void dump();
#endif // _HASH_TABLE_H_
/* hashtable.c */
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "hashtable.h"
#define BUCKET_SIZE 256
static int otable_size;
static int otable_size_minus_one;
int whashstr(char *, int);
#define ObjHash(s) whashstr((char *)s, 40) & otable_size_minus_one
/*
* hash table - list of pointers to heads of object chains.
* Each object in chain has a pointer, next_hash, to the next object.
*/
static object_t **obj_table = 0;
void init_otable()
{
int y;
/* ensure that otable_size is a power of 2 */
y = BUCKET_SIZE;
for (otable_size = 1; otable_size < y; otable_size *= 2)
;
otable_size_minus_one = otable_size - 1;
/* by using calloc, each element in obj_table is initialized to 0 */
obj_table = (object_t **)calloc(otable_size, sizeof(object_t *));
}
void clear_otable()
{
int i;
free(obj_table);
for (i = 0; i < BUCKET_SIZE; ++i) {
obj_table[i] = 0;
}
}
/* A global. */
static int h;
/*
* Looks for obj in table, moves it to head.
*/
object_t *find_obj_n(char * s)
{
object_t *curr, *prev;
h = ObjHash(s);
curr = obj_table[h];
prev = 0;
while (curr) {
if (!strcmp(curr->name, s)) { /* found it */
if (prev) { /* not at head of list */
prev->next_hash = curr->next_hash;
curr->next_hash = obj_table[h];
obj_table[h] = curr;
}
return (curr); /* p
下一页 上一页
返回列表
返回首页
©2024 MUD游戏网_文字mud 电脑版
Powered by iwms