Lua源码之表

lua版本:5.3.5

数据结构

  table是lua唯一的数据结构,也是lua最明显的特色之一,使用者可以在table的基础上实现各种各样的数据结构。table即可以作为数组,又可以作为哈希表,而在实现上,源码里也是将table的内部存储分为了数组和哈希表。

/*
** Tables
*/

typedef union TKey {
   
  struct {
   
    TValuefields;
    int next;  /* for chaining (offset for next node) */
  } nk;
  TValue tvk;
} TKey;


typedef struct Node {
   
  TValue i_val;
  TKey i_key;
} Node;


typedef struct Table {
   
  CommonHeader;
  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */
  lu_byte lsizenode;  /* log2 of size of 'node' array */
  unsigned int sizearray;  /* size of 'array' array */
  TValue *array;  /* array part */
  Node *node;
  Node *lastfree;  /* any free position is before this position */
  struct Table *metatable;
  GCObject *gclist;
} Table;


  • TKey:哈希表里每个节点的key值,除了包含作为key的值,还指向同哈希值的下一个节点。
  • Node:哈希表的内的每个节点,包含key和value。
  • Table:表结构
    • lsizenode:哈希表大小的log2(哈希表大小为2的幂次)。
    • sizearray:数组大小(数组大小为2的幂次)。
    • array:数组头部指针。
    • node:哈希表头部指针。
    • lastfree:指向哈希表内最后一个空着的节点。
    • metatable:元表。
    • gclist:用于垃圾回收。

  结构本身很简单明晰,唯一需要多说下的是哈希表的结构,这里推荐篇文章
  简单来说,这是个闭散列表,TKey里指向的下一个节点就是哈希表内的节点,当新元素(new)的哈希值所指向的位置如果被占据,则检查该位置的老元素(old)是否应该在这:

  • 如果old应在此处,则new找空位,并和old的next连接。
  • 如果old不应该在此处,则old另找新位置,new占据此处。

实现

新增元素

/*
** inserts a new key into a hash table; first, check whether key's main
** position is free. If not, check whether colliding node is in its main
** position or not: if it is not, move colliding node to an empty place and
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
   
  Node *mp;
  TValue aux;
  if (ttisnil(key)) luaG_runerror(L, "table index is nil");
  else if (ttisfloat(key)) {
   
    lua_Integer k;
    if (luaV_tointeger(key, 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值