C语言中的哈希表插入/搜索

3

你好,我有一个哈希表的问题,它的实现方式如下:

#define HT_SIZE 10 
typedef struct _list_t_ {
    char key[20];
    char string[20];
    char prevValue[20];
    struct _list_t_ *next;
} list_t;

typedef struct _hash_table_t_ {
    int size;       /* the size of the table */
    list_t ***table; /* first */
    sem_t lock;
} hash_table_t;

我有一个带有3个指针的链表,因为我想要一个具有多个分区(shards)的哈希表,这是我的哈希表的初始化:

hash_table_t *create_hash_table(int NUM_SERVER_THREADS, int num_shards){
    hash_table_t *new_table;    
    int j,i;
    if (HT_SIZE<1) return NULL; /* invalid size for table */
    /* Attempt to allocate memory for the hashtable structure */
    new_table = (hash_table_t*)malloc(sizeof(hash_table_t)*HT_SIZE);
    /* Attempt to allocate memory for the table itself */
    new_table->table = (list_t ***)calloc(1,sizeof(list_t **));
    /* Initialize the elements of the table */
    for(j=0; j<num_shards; j++){
        new_table->table[j] = (list_t **)calloc(1,sizeof(list_t *));
        for(i=0; i<HT_SIZE; i++){
            new_table->table[j][i] = (list_t *)calloc(1,sizeof(list_t ));
        }
    }
    /* Set the table's size */
    new_table->size = HT_SIZE;
    sem_init(&new_table->lock, 0, 1);
    return new_table;
}

这是我的搜索函数,用于在哈希表中进行搜索。
list_t *lookup_string(hash_table_t *hashtable, char *key, int shardId){

    list_t *list ;

    int hashval = hash(key);
    /* Go to the correct list based on the hash value and see if key is
     * in the list.  If it is, return return a pointer to the list element.
     * If it isn't, the item isn't in the table, so return NULL.
     */
    sem_wait(&hashtable->lock);

    for(list = hashtable->table[shardId][hashval]; list != NULL; list =list->next) {
        if (strcmp(key, list->key) == 0){
                sem_post(&hashtable->lock);
                return list;
        }
    }
    sem_post(&hashtable->lock);

    return NULL;
}

我的插入函数:

char *add_string(hash_table_t *hashtable, char *str,char *key, int shardId){
    list_t *new_list;
    list_t *current_list;
    unsigned int hashval = hash(key);
    /*printf("|%d|%d|%s|\n",hashval,shardId,key);*/
    /* Lock for concurrency */
    sem_wait(&hashtable->lock);
    /* Attempt to allocate memory for list */
    new_list = (list_t*)malloc(sizeof(list_t));

    /* Does item already exist? */
    sem_post(&hashtable->lock);
    current_list = lookup_string(hashtable, key,shardId);
    sem_wait(&hashtable->lock);
        /* item already exists, don't insert it again. */
    if (current_list != NULL){
        strcpy(new_list->prevValue,current_list->string);
        strcpy(new_list->string,str);
        strcpy(new_list->key,key);
        new_list->next = hashtable->table[shardId][hashval];
        hashtable->table[shardId][hashval] = new_list;
        sem_post(&hashtable->lock);
        return new_list->prevValue;
    }
    /* Insert into list */
    strcpy(new_list->string,str);
    strcpy(new_list->key,key);
    new_list->next = hashtable->table[shardId][hashval];
    hashtable->table[shardId][hashval] = new_list;
    /* Unlock */
    sem_post(&hashtable->lock);
    return new_list->prevValue;
}

我的主类通过执行哈希表元素的插入/读取/删除来运行一些测试,问题是当我有超过4个分区/分片时,测试在第一个读取元素时停止,并说它返回了错误值NULL在搜索函数中,当小于4时,它完美地运行并通过所有测试。如果您想看一下,可以在这里查看我的main.c文件:

http://hostcode.sourceforge.net/view/1105

我的完整哈希表代码:

http://hostcode.sourceforge.net/view/1103

其他执行哈希表代码的函数:

.c 文件 http://hostcode.sourceforge.net/view/1104

.h 文件 http://hostcode.sourceforge.net/view/1106

谢谢您的时间,我非常感谢您所提供的任何帮助。这是我正在尝试解决的重要大学项目,我已经被卡在这里 2 天了。


5
三星程序员三星程序员是指具有以下能力的程序员:
  • 能够独立完成大多数编程任务。
  • 能够写出易于理解和维护的代码。
  • 能够在实现功能的同时优化代码性能。
此外,一些人还将三星程序员定义为具有更高级别技能的程序员,例如架构师或系统分析师。这些人通常能够设计和构建复杂的软件系统。相比之下,一星程序员只能完成简单的编程任务,二星程序员则能够处理稍微复杂一些的问题。
- digital_revenant
这是另一个链接,用于缺失的代码部分:http://hostcode.sourceforge.net/view/1104 - Ricardo Campos
2
这里的三个星号属于一个很常见的习语--它只是一个动态分配和大小调整的二维数组索引,就像“p = table[a][b]”一样。没什么大不了的。 - Charlie Burns
是的,yes是一个二维数组。它有3个星号,因为它是一个链表。 - Ricardo Campos
1个回答

1

你好,我已经解决了这个问题。在初始化时,我进行了错误的分配。

new_table->table = (list_t ***)calloc(1,sizeof(list_t **)); 

应该是这样的:

它应该像这样:

new_table->table = (list_t ***)calloc(num_shards,sizeof(list_t **));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接