非常简单的Map实现在C(缓存的目的)?

lf5gs5x2  于 2023-01-08  发布在  其他
关注(0)|答案(8)|浏览(90)

我有一个程序,读取文件中的网址,并在每个网址主机上执行gethostbyname()。这个调用相当耗时。我想缓存它们。
有没有一个非常简单的基于Map的C代码片段,我可以用来做缓存?(我只是不想重新发明轮子)。
它必须具备以下几点:

      • 许可证**的开源(考虑BSD或公共域)。
        *非常简单理想地小于100LOC
  • 密钥为char*,值为void*,无需复制。
  • 真实的上不需要实现remove(),但是需要contains()或者put()应该替换该值。

PS:我把它标记为“家庭作业”,因为它可能是。我只是"非常“懒惰,并希望避免所有常见的陷阱,我可能会遇到,而重新实现。

pftdvrlh

pftdvrlh1#

这是一个非常简单和天真的

  • 固定桶大小
  • 无删除操作
  • inserts替换键和值,并且可以选择释放它们

#include <string.h>
#include <stdlib.h>

#define NR_BUCKETS 1024

struct StrHashNode {
    char *key;
    void *value;
    struct StrHashNode *next;

};

struct StrHashTable {
    struct StrHashNode *buckets[NR_BUCKETS];
    void (*free_key)(char *);
    void (*free_value)(void*);
    unsigned int (*hash)(const char *key);
    int (*cmp)(const char *first,const char *second);
};

void *get(struct StrHashTable *table,const char *key)
{
    unsigned int bucket = table->hash(key)%NR_BUCKETS;
    struct StrHashNode *node;
    node = table->buckets[bucket];
    while(node) {
        if(table->cmp(key,node->key) == 0)
            return node->value;
        node = node->next;
    }
    return NULL;
}
int insert(struct StrHashTable *table,char *key,void *value)
{
    unsigned int bucket = table->hash(key)%NR_BUCKETS;
    struct StrHashNode **tmp;
    struct StrHashNode *node ;

    tmp = &table->buckets[bucket];
    while(*tmp) {
        if(table->cmp(key,(*tmp)->key) == 0)
            break;
        tmp = &(*tmp)->next;
    }
    if(*tmp) {
        if(table->free_key != NULL)
            table->free_key((*tmp)->key);
        if(table->free_value != NULL)
            table->free_value((*tmp)->value);
        node = *tmp;
    } else {
        node = malloc(sizeof *node);
        if(node == NULL)
            return -1;
        node->next = NULL;
        *tmp = node;
    }
    node->key = key;
    node->value = value;

    return 0;
}

unsigned int foo_strhash(const char *str)
{
    unsigned int hash = 0;
    for(; *str; str++)
        hash = 31*hash + *str;
    return hash;
}

#include <stdio.h>
int main(int argc,char *argv[])
{
    struct StrHashTable tbl = {{0},NULL,NULL,foo_strhash,strcmp};

    insert(&tbl,"Test","TestValue");
    insert(&tbl,"Test2","TestValue2");
    puts(get(&tbl,"Test"));
    insert(&tbl,"Test","TestValueReplaced");
    puts(get(&tbl,"Test"));

    return 0;
}
relj7zay

relj7zay2#

Christoper Clark's hashtable implementation非常简单,它有100多行,但不是很多。
克拉克的代码似乎已经作为一个并行化示例进入了Google's Conccurrency Library

zrfyljdw

zrfyljdw3#

C++中的std::map是一棵红黑树;使用an existing red-black tree implementation in C怎么样?我链接的那个更像是700 LOC,但是它的注解很好,从我粗略地看了一下看起来很正常。你可能会找到其他的;这是谷歌搜索“C红黑树”的第一个结果。
如果你对性能不挑剔,你也可以使用一个不平衡的二叉树或者一个最小堆或者类似的东西。使用一个平衡的二叉树,你可以保证O(logn)的查找;对于一个不平衡的树,查找的最坏情况是O(n)(对于节点按顺序插入的病态情况,所以你最终得到一个像链表一样的很长的分支),但是(如果我的记忆是正确的话)平均情况仍然是O(logn)。

kgqe7b3p

kgqe7b3p4#

您可以尝试使用以下实现
clib

bakd9h0s

bakd9h0s5#

是吗
不是代码片段,而是一个高性能的分布式缓存引擎。

5hcedyr0

5hcedyr06#

不懒惰,深刻的明智,以避免写这种东西。
这个library怎么样?我自己从来没有用过,但它似乎声称能满足你的要求。

f0ofjuux

f0ofjuux7#

Dave Hanson的C Interfaces and Implementations包含了一个不错的哈希表,以及许多其他有用的模块。哈希表有150行,但这包括内存管理、高阶Map函数和数组转换。该软件是免费的,值得一买。

kjthegm6

kjthegm68#

在此找到一个实现:c文件和h文件,这两个文件与您要求的文件非常接近。W3C许可证

相关问题