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