0x1. 结构定义
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
GCObject *gclist;
int sizearray; /* size of `array' array */
} Table;
node
字段即为hash桶,array
字段是table的一个优化,如果key是数字并且比较小的话就保存到数组里面,以提高性能。
typedef union TKey {
struct {
TValuefields;
struct Node *next; /* for chaining */
} nk;
TValue tvk;/*这个和nk里面的TValuefields是一样的结构*/
} TKey;
typedef struct Node {
TValue i_val;
TKey i_key;
} Node;
这里的TKey里面的tvk
比较令人疑惑,这里解释下。这个其实和nk里面的TValuefields
是一样的定义,而且这是个union
类型,所以访问tvk
和访问nk的TValuefields
是一样的内容。这样子就可以将TKey
转化为一个Tvalue
的格式,因为有的接口参数是使用TValue
的。这个手发在lua里面很常见。
0x2. hash表
想要实现一个hash表就要解决几个问题:
- hash函数
- hash冲突如何处理
- 扩容
hash函数
由于table是支持各种不同类型的key,所以这里的hash函数会根据具体的类型用不同的hash函数。
hash冲突
lua中解决hash冲突不是常见的链式解决方案,有点像是线性探测和链式的合并。这里首先介绍一个概念main position。一个key对应的main position为该key的桶索引。
rehash
这个和常见的基本一样,也就是申请内存,重新插入。