我正在寻找一种哈希表的开源 C 实现,它将所有数据保存在一个内存块中,因此可以很容易地通过网络发送它。我只能找到为添加到其中的每个键值对分配小块内存的那些。
非常感谢您提前提供的所有信息。
编辑:它不一定需要是一个哈希表,无论键值对表可能会做什么。
您将序列化此类数据结构的次数(并且通过网络发送也在序列化)与您将使用此类数据结构的次数(在您的程序中)相当低。因此,大多数实现更多地关注速度而不是“可能更容易序列化”方面。
如果所有数据都在一个分配的内存块中,那么对该数据结构的大量操作会有点昂贵,因为您必须:
无论如何,大多数网络操作都是缓冲的,只需遍历键并发送键 + 值。
在 unix 系统上,我可能会使用共享内存缓冲区(请参阅 参考资料shm_open()
),或者如果不可用带有 MAP_SHARED 标志的内存映射文件,请参阅特定于操作系统的差异http://en.wikipedia.org/wiki/Mmap
如果两者shm_open
都不mmap
可用,你仍然可以使用磁盘上的文件(在某种程度上),你必须关心正确的锁定,我会发送一个解锁信号到下一个进程,也许是寻找文件的更新部分,然后该进程再次锁定文件,寻找有趣的部分并照常进行(更新/删除/等)。
在任何情况下,您都可以自由设计散列表的布局或任何您想要的,例如具有固定宽度的键/搜索对。这样您就可以快速访问哈希表的键,如有必要,您可以查找数据部分,然后复制/删除/修改/等。
当然,理想情况下,该文件应该在 ram 磁盘上。
提供哈希表的库倾向于隐藏细节并使事情有效地工作(这通常是程序员在使用哈希表时想要的),因此通常他们处理内存的方式对最终程序员的眼睛是隐藏的,程序员不应该依赖在特定的“内存布局”上,可能会在以下版本的库中发生变化。
编写您自己的函数,以最方便的方式对哈希表进行序列化(和反序列化)以供您使用。如果你需要多次序列化的内容,你可以保留它(当然,当哈希表改变时,你需要更新保存在内存中的序列化“版本”)。
我完全同意阿基拉(+1)。关于数据局部性的另一条评论。一旦表变大,或者卫星数据足够大,肯定会有缓存污染,这会额外减慢对表的任何操作,或者换句话说,你可以依赖 1/2/3 级缓存链来服务当您必须访问卫星数据(例如用于序列化)时,及时处理关键数据,同时忍受缓存未命中。