简体   繁体   English

C map / hash-table,它由整数键入并映射到void指针

[英]C map/hash-table that's keyed by integers and maps to void pointers

I am re-writing a light weight image server I wrote in Python using epoll into c (not c++). 我正在重写我用Python编写的轻量级图像服务器,使用epoll进入c(不是c ++)。 I want to write a (or use an existing) very simple map or hash-table that maps integer keys (file descriptors) to void pointers. 我想写一个(或使用现有的)非常简单的映射或散列表,它将整数键(文件描述符)映射到void指针。 What's a good way to go about doing this? 这样做的好方法是什么? I don't need to be able to support any generic types of keys or even strings. 我不需要能够支持任何通用类型的键甚至字符串。 I have one idea: 我有一个想法:

// Initialize map.
size_t map_size = 50;
void ** map = (void **)malloc(sizeof(void *) * map_size);
memset((void *)map, 0, map_size);

// Set values for keys 3, 20, 67
int key_a = 3;
int key_b = 20;
int key_c = 67;
void * value_a = ...;
void * value_b = ...;
void * value_c = ...;

// NOTE: This does not take into account conflicting keys. I would probably solve
// that using an array or linked-list and comparing keys.
map[key_a % map_size] = value_a;
map[key_b % map_size] = value_b;
map[key_c % map_size] = value_c;

Is this sensible or are there much better ways to accomplish this? 这是明智的还是有更好的方法来实现这一目标? Or can someone point me in the right direction to finding an answer? 或者有人能指出我找到答案的正确方向?

File descriptors are small integers on most systems, and often contiguous, as they are used as indices inside the kernel. 文件描述符在大多数系统上都是小整数,并且通常是连续的,因为它们在内核中用作索引。 Hence I propose to just create an array from 0..maxfd (growing dynamically), and use the file descriptor as an integer - with no hashing at all. 因此我建议只从0..maxfd(动态增长)创建一个数组,并将文件描述符用作整数 - 根本不进行散列。

As a safe guard, you may want to protect against systems that use different strategies for allocating file descriptors, eg aborting if it is larger than 2^20. 作为安全防护,您可能希望防止使用不同策略分配文件描述符的系统,例如,如果大于2 ^ 20则中止。

在Ruby的代码库 - st.c中使用通用C哈希表的公共域实现。

There's nothing wrong with using a simple modulus as a "hash algorithm" per se, but it only works well if you know the results will be evenly distributed. 使用简单模数作为“哈希算法”本身没有任何问题,但只有在知道结果将均匀分布的情况下才能正常工作。 In your case, however, you can't technically count on that with file descriptors, since there's no particular guarantee as to what numbers you'll get back from the open/fopen calls. 但是,在您的情况下,您无法在技术上依赖于文件描述符,因为没有特别保证您将从open / fopen调用返回的数字。

There are very simple hash algorithms out there that are pretty fast and work well enough for general use cases. 有非常简单的哈希算法,它们非常快,并且对于一般用例而言运行良好。 You could consider the FNV family , or even the dead-simple Pearson hash. 您可以考虑FNV系列 ,甚至是简单的Pearson哈希。

That said, I'm a bit curious as to why you want a hash table keyed off of file descriptors. 也就是说,我有点好奇为什么你想要一个键入文件描述符的哈希表。 That seems like an odd design detail, and makes me think you're overcomplicating something. 这似乎是一个奇怪的设计细节,让我觉得你过于复杂的东西。

Others have raised good points about whether this is really what you want to do, but just to answer your immediate question, the glibc hashtable functions should be available on most systems. 其他人已经提出了关于这是否真的是你想要做的好点,但只是回答你的问题, glibc哈希表函数应该可以在大多数系统上使用。 Note that you almost certainly want to use the _r variants ( hcreate_r, hsearch_r, hdestroy_r ), since the vanilla versions create and manipulate a single, global hashtable. 请注意,您几乎肯定希望使用_r变体( hcreate_r, hsearch_r, hdestroy_r ),因为vanilla版本创建并操作单个全局散列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM