summaryrefslogtreecommitdiff
path: root/src/lua51/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua51/ltable.c')
-rw-r--r--src/lua51/ltable.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/lua51/ltable.c b/src/lua51/ltable.c
index ec84f4f..f489a03 100644
--- a/src/lua51/ltable.c
+++ b/src/lua51/ltable.c
@@ -159,6 +159,9 @@ static int findindex (lua_State *L, Table *t, StkId key) {
}
+//c table的遍历操作,返回下一个node
+//c 先计算key的hash,如果在array范围内,在array中找,否则在hash中找
+//c 注意实际上不会两个for循环都走
int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
@@ -208,8 +211,10 @@ static int computesizes (int nums[], int *narray) {
}
+//c 返回1或0,是否将这个key算进要加入表的数组部分
static int countint (const TValue *key, int *nums) {
int k = arrayindex(key);
+ //c 所以数字key的最大范围是0~MAXASIZE
if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
nums[ceillog2(k)]++; /* count as such */
return 1;
@@ -294,6 +299,9 @@ static void setnodevector (lua_State *L, Table *t, int size) {
}
+//c 重新分配table的哈希部分大小为
+//nasize 是 array size
+//nhsize 是 hash table size
static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int i;
int oldasize = t->sizearray;
@@ -330,18 +338,26 @@ void luaH_resizearray (lua_State *L, Table *t, int nasize) {
}
+//c 给table的散列桶部分重新hash
+//c 用于给table扩容
static void rehash (lua_State *L, Table *t, const TValue *ek) {
+ //c 先计算落在2^(i-1)~2^i范围内的各个区间的元素数量,用于决策新容量
int nasize, na;
+ //c 以2的指数级扩展的数组,记录的是指数。能看出来表的最大大小是2^MAXBITS
int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
int i;
int totaluse;
for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
+ //c 遍历数组部分和散列桶部分,找出正整数key的值的数量,以此更新nums[]
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
/* count extra key */
+ //c 加上这个key(如果在范围内的话)
nasize += countint(ek, nums);
totaluse++;
+ //c 找到一个位置i,这个位置之前的元素个数大于50%,即2^i/2。这个位置之后意味着太空了,效率比较低
+ //c 这个位置
/* compute new size for array part */
na = computesizes(nums, &nasize);
/* resize the table to new computed sizes */
@@ -354,7 +370,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
** }=============================================================
*/
-
+//c 新建table
Table *luaH_new (lua_State *L, int narray, int nhash) {
Table *t = luaM_new(L, Table);
luaC_link(L, obj2gco(t), LUA_TTABLE);
@@ -388,7 +404,7 @@ static Node *getfreepos (Table *t) {
}
-
+//c 表新建key
/*
** 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
@@ -398,30 +414,41 @@ static Node *getfreepos (Table *t) {
*/
static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp = mainposition(t, key);
- if (!ttisnil(gval(mp)) || mp == dummynode) {
+ if (!ttisnil(gval(mp)) || mp == dummynode) {//c mainposition上已经有数据
Node *othern;
Node *n = getfreepos(t); /* get a free place */
+ //c 如果没有空位,扩展hash table大小为2倍
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
+ //c 扩展完大小后重试
return luaH_set(L, t, key); /* re-insert key into grown table */
}
lua_assert(n != dummynode);
+ //c 先看一下现在mainposition上的这个node,它的mainposition是不是这个值
+ //c 不是的话给新的key让路
othern = mainposition(t, key2tval(mp));
if (othern != mp) { /* is colliding node out of its main position? */
+ // 把mp空出来,mp里的值移到n(freeposition)
/* yes; move colliding node into free position */
+ //? 这行没看懂
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
gnext(mp) = NULL; /* now `mp' is free */
setnilvalue(gval(mp));
+ //mp是要赋值的位置,即新key的元素的位置
}
else { /* colliding node is in its own main position */
/* new node will go into free position */
+ //c 将free position插入到mp后第一个
gnext(n) = gnext(mp); /* chain new position */
gnext(mp) = n;
+ //c 修改一下mp指针,指向freeposition,留个后续使用
mp = n;
}
}
+ //c 如果mainposition位置上是空的,可以直接用mp位置存
+ //c 赋值
gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
luaC_barriert(L, t, key);
lua_assert(ttisnil(gval(mp)));
@@ -553,6 +580,7 @@ static int unbound_search (Table *t, unsigned int j) {
}
+//c 获得table长度
/*
** Try to find a boundary in table `t'. A `boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
@@ -560,7 +588,9 @@ static int unbound_search (Table *t, unsigned int j) {
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
+ // 二分查找,找到
/* there is a boundary in the array part: (binary) search for it */
+ // i是左界,j是右界
unsigned int i = 0;
while (j - i > 1) {
unsigned int m = (i+j)/2;