玩具语言LLL之Hash

本文深入探讨了哈希表在文本处理和检索领域的高效应用,特别是针对C程序员的挑战与解决方案。详细介绍了哈希表的计算方式、内存分配策略以及灵活运用技巧,包括使用obstack作为基础内存池、自扩展机制与复合单向链表的数据结构。文章还涉及了内存优化和链表操作的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在所有事情之前,必须要搞点铺垫,hash表显然是必须的。所有的编译还是解释语言,都是把各种自然文本剁碎成token,然后进行链接处理。文本和文本的检索是所有事情的核心。在这个领域里hash表是最高效且简单的,至少在编程上是这样。不过,hash表对于c程序员来说,确实非常不友好的。c程序员往往面临双重角色,第一追求纯粹的高效,第二追求工程管理上的简单。对于任何人来说,这两方面都是一个非常纠结的话题。好在,对于编译系统来说这相对不复杂。

 

在这个hash表里,我使用2^N次方作为长度。与(&)的计算效率要比或(%)高一些,这也适合基于块的语法解析。hash的计算方式是字符串,这个算法来自linux kernel,不一定很好,暂时用一下。它对长字符串的处理效率不好,暂时用一下,便于代码迭代。hash表使用传统的get和probe原语,都是基于字符串的hash。当hash容量超出,会自扩展,在这个过程中会重构hash表。我总是把hash表比喻成一个绳子上挂一串串的香肠,绳子是数组,香肠是链表。一般,链表使用单纯的单向链表,只是指向next节点。在这里,使用了一个“复合”单向链表。这是一套BSD下的宏,Linux也有。这个链表其实是在单头桩下,能够在不考虑头桩下直接删除节点,当作一种单头桩双向链表也可。之所以使用这个数据结构,是项目还不太明确,不清楚是否要直接删除hash表的某个节点。不过,这是以后的事情,这里说这点主要是在讨论hash表的灵活运用问题。

 

在这里涉及到内存分配问题,mem.c和mem.h负责这方面。我还不确定这个玩具语言到底是编译还是解释还是嵌入解释,这个负责内存的分配。realloc和free,都提出内存释放或旧内存的size,这有利于内存优化。

 

在hash里有个结构是obstack。这玩意最早我发现在gcc里,不知道什么时候出现在glibc的标准中,非常好用的堆栈式内存池。语言分析基本都是堆栈式的,我选择它作为基础内存池。

 

总之,一个简单的hash表,没太多可说的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值