目录

一、概述

二、 symOpen 创建

1.返回值

2.输入值

3.示例:

三、symEnter 插入

四、symLookup查找

五、symClose 释放


一、概述

哈希表,又叫散列表。在用GoAhead 实现WebServer时,其中的哈希工具可以实现对大量数据的快速检索,如查重等。

主要用到的函数有4个:

extern sym_fd_t    symOpen(int hash_size);
 extern void        symClose(sym_fd_t sd);
 extern sym_t    *symLookup(sym_fd_t sd, char_t *name);
 extern sym_t    *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg);主要访问数据有2个:
static sym_tabent_t    **sym;                /* List of symbol tables */
 static int            symMax;                /* One past the max symbol table */

下面分别介绍其功能和用法,示例都是GoAhead 原码。

二、 symOpen 创建

每创建一个哈希表就要调用一次symOpen,并给symMax加1。

1.返回值

类型是sym_fd_t ,实际上是一个整型数。创建的哈希表的指针会放在数组sym里,对应数组sym中的索引即symOpen返回的值,从0开始排序。失败则返回-1。

如果创建了多个表,它们会被依次放到数组sym中。symMax即创建的哈希表总个数。如果创建的哈希表被symClose释放了,索引也会被释放给下一个创建的哈希表。

GoAhead  启动后会依次注册以下哈希表:

MimeList,对应索引 websMime=0;
PageList 的 aspList,对应索引websAspFunctions=1;
PageList 的 formList,对应索引formSymtab=2;
.......

2.输入值

hash_size用于指定表的大小,基于效率的考虑,这个大小最好不要小于原表的二分之一。symOpen内部实际会调整为一个小于等于hash_size的质数。所以我会选择原表大小的四分之三作为输入值,这样即使调整到一个较小的质数也不会小于原值的二分之一。

3.示例:

formSymtab = symOpen(WEBS_SYM_INIT);

三、symEnter 插入

这里不是顺序插入,而是根据传入的name和 哈希表大小计算出索引,以便于后面查找时能根据name 快速定位。name重复的,后来会覆盖先来的。如果不想覆盖,可以先调用symLookup 检查是否name 已经创建过了。

返回值 是创建的这一条目的指针。

输入值 sd即创建时返回的索引。

输入值 name 是个字符串,可以理解为是表项的key。

输入值  v 要特别注意,可以通过valueInteger 、valueString指定类型。

如:
        symEnter(formSymtab, name, valueInteger((int) fn), (int) NULL);
或
         symEnter(lanSymtab, buf, valueString(val, VALUE_ALLOCATE), (int)NULL);

         其中valueString 还需要明确字符串是否需要创建,通常是需要的。

输入值  arg 通常是NULL.

四、symLookup查找

根据指定的哈希表索引sd 和 条目索引 name可以查找对应的哈希条目,远比逐个对比原表快得多。

找不到就返回NULL, 找到了就返回对应条目的指针。

示例:sp = symLookup(formSymtab, formName);

五、symClose 释放

如果哈希表不用了,就需要尽快释放,以免占用内存。上文中提到了索引0-2的哈希表由于一直要用,所以会在webs被关闭时才close(见 websCloseServer)。

对于需要多次覆盖的哈希表,需要在每次创建前判断,如果存在就先close再open。

示例:

void websLanguageUnload(void)
{
    if(lanSymtab != -1)
    {
        symClose(lanSymtab);
        lanSymtab = -1;
    }
}


int websLanguageLoad(char_t *path)
{

...

    if(lanSymtab == -1)
    {
        lanSymtab = symOpen(LANGUAGE_HASHSIZE);
    }
    else
    {
        websLanguageUnload();
        lanSymtab = symOpen(LANGUAGE_HASHSIZE);
    }

...

}