2 ** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $
4 ** See Copyright Notice in lua.h
9 ** Implementation of tables (aka arrays, objects, or hash tables).
10 ** Tables keep its elements in two parts: an array part and a hash part.
11 ** Non-negative integer keys are all candidates to be kept in the array
12 ** part. The actual size of the array is the largest `n' such that at
13 ** least half the slots between 0 and n are in use.
14 ** Hash uses a mix of chained scatter table with Brent's variation.
15 ** A main invariant of these tables is that, if an element is not
16 ** in its main position (i.e. the `original' position that its hash gives
17 ** to it), then the colliding element is in its own main position.
18 ** Hence even when the load factor reaches 100%, performance remains good.
25 #include <sys/lua/lua.h>
39 ** max size of array part is 2^MAXBITS
41 #if LUAI_BITSINT >= 32
44 #define MAXBITS (LUAI_BITSINT-2)
47 #define MAXASIZE (1 << MAXBITS)
50 #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
52 #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
53 #define hashboolean(t,p) hashpow2(t, p)
57 ** for some types, it is better to avoid modulus by power of 2, as
58 ** they tend to have many 2 factors.
60 #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
63 #define hashpointer(t,p) hashmod(t, IntPoint(p))
66 #define dummynode (&dummynode_)
68 #define isdummy(n) ((n) == dummynode)
70 static const Node dummynode_
= {
71 {NILCONSTANT
}, /* value */
72 {{NILCONSTANT
, NULL
}} /* key */
77 ** hash for lua_Numbers
79 static Node
*hashnum (const Table
*t
, lua_Number n
) {
83 if (cast(unsigned int, i
) == 0u - i
) /* use unsigned to avoid overflows */
84 i
= 0; /* handle INT_MIN */
85 i
= -i
; /* must be a positive value */
93 ** returns the `main' position of an element in a table (that is, the index
96 static Node
*mainposition (const Table
*t
, const TValue
*key
) {
99 return hashnum(t
, nvalue(key
));
101 TString
*s
= rawtsvalue(key
);
102 if (s
->tsv
.extra
== 0) { /* no hash? */
103 s
->tsv
.hash
= luaS_hash(getstr(s
), s
->tsv
.len
, s
->tsv
.hash
);
104 s
->tsv
.extra
= 1; /* now it has its hash */
106 return hashstr(t
, rawtsvalue(key
));
109 return hashstr(t
, rawtsvalue(key
));
111 return hashboolean(t
, bvalue(key
));
112 case LUA_TLIGHTUSERDATA
:
113 return hashpointer(t
, pvalue(key
));
115 return hashpointer(t
, fvalue(key
));
117 return hashpointer(t
, gcvalue(key
));
123 ** returns the index for `key' if `key' is an appropriate key to live in
124 ** the array part of the table, -1 otherwise.
126 static int arrayindex (const TValue
*key
) {
127 if (ttisnumber(key
)) {
128 lua_Number n
= nvalue(key
);
130 lua_number2int(k
, n
);
131 if (luai_numeq(cast_num(k
), n
))
134 return -1; /* `key' did not match some condition */
139 ** returns the index of a `key' for table traversals. First goes all
140 ** elements in the array part, then elements in the hash part. The
141 ** beginning of a traversal is signaled by -1.
143 static int findindex (lua_State
*L
, Table
*t
, StkId key
) {
145 if (ttisnil(key
)) return -1; /* first iteration */
147 if (0 < i
&& i
<= t
->sizearray
) /* is `key' inside array part? */
148 return i
-1; /* yes; that's the index (corrected to C) */
150 Node
*n
= mainposition(t
, key
);
151 for (;;) { /* check whether `key' is somewhere in the chain */
152 /* key may be dead already, but it is ok to use it in `next' */
153 if (luaV_rawequalobj(gkey(n
), key
) ||
154 (ttisdeadkey(gkey(n
)) && iscollectable(key
) &&
155 deadvalue(gkey(n
)) == gcvalue(key
))) {
156 i
= cast_int(n
- gnode(t
, 0)); /* key index in hash table */
157 /* hash elements are numbered after array ones */
158 return i
+ t
->sizearray
;
162 luaG_runerror(L
, "invalid key to " LUA_QL("next")); /* key not found */
168 int luaH_next (lua_State
*L
, Table
*t
, StkId key
) {
169 int i
= findindex(L
, t
, key
); /* find original element */
170 for (i
++; i
< t
->sizearray
; i
++) { /* try first array part */
171 if (!ttisnil(&t
->array
[i
])) { /* a non-nil value? */
172 setnvalue(key
, cast_num(i
+1));
173 setobj2s(L
, key
+1, &t
->array
[i
]);
177 for (i
-= t
->sizearray
; i
< sizenode(t
); i
++) { /* then hash part */
178 if (!ttisnil(gval(gnode(t
, i
)))) { /* a non-nil value? */
179 setobj2s(L
, key
, gkey(gnode(t
, i
)));
180 setobj2s(L
, key
+1, gval(gnode(t
, i
)));
184 return 0; /* no more elements */
189 ** {=============================================================
191 ** ==============================================================
195 static int computesizes (int nums
[], int *narray
) {
197 int twotoi
; /* 2^i */
198 int a
= 0; /* number of elements smaller than 2^i */
199 int na
= 0; /* number of elements to go to array part */
200 int n
= 0; /* optimal size for array part */
201 for (i
= 0, twotoi
= 1; twotoi
/2 < *narray
; i
++, twotoi
*= 2) {
204 if (a
> twotoi
/2) { /* more than half elements present? */
205 n
= twotoi
; /* optimal size (till now) */
206 na
= a
; /* all elements smaller than n will go to array part */
209 if (a
== *narray
) break; /* all elements already counted */
212 lua_assert(*narray
/2 <= na
&& na
<= *narray
);
217 static int countint (const TValue
*key
, int *nums
) {
218 int k
= arrayindex(key
);
219 if (0 < k
&& k
<= MAXASIZE
) { /* is `key' an appropriate array index? */
220 nums
[luaO_ceillog2(k
)]++; /* count as such */
228 static int numusearray (const Table
*t
, int *nums
) {
231 int ause
= 0; /* summation of `nums' */
232 int i
= 1; /* count to traverse all array keys */
233 for (lg
=0, ttlg
=1; lg
<=MAXBITS
; lg
++, ttlg
*=2) { /* for each slice */
234 int lc
= 0; /* counter */
236 if (lim
> t
->sizearray
) {
237 lim
= t
->sizearray
; /* adjust upper limit */
239 break; /* no more elements to count */
241 /* count elements in range (2^(lg-1), 2^lg] */
242 for (; i
<= lim
; i
++) {
243 if (!ttisnil(&t
->array
[i
-1]))
253 static int numusehash (const Table
*t
, int *nums
, int *pnasize
) {
254 int totaluse
= 0; /* total number of elements */
255 int ause
= 0; /* summation of `nums' */
258 Node
*n
= &t
->node
[i
];
259 if (!ttisnil(gval(n
))) {
260 ause
+= countint(gkey(n
), nums
);
269 static void setarrayvector (lua_State
*L
, Table
*t
, int size
) {
271 luaM_reallocvector(L
, t
->array
, t
->sizearray
, size
, TValue
);
272 for (i
=t
->sizearray
; i
<size
; i
++)
273 setnilvalue(&t
->array
[i
]);
278 static void setnodevector (lua_State
*L
, Table
*t
, int size
) {
280 if (size
== 0) { /* no elements to hash part? */
281 t
->node
= cast(Node
*, dummynode
); /* use common `dummynode' */
286 lsize
= luaO_ceillog2(size
);
288 luaG_runerror(L
, "table overflow");
290 t
->node
= luaM_newvector(L
, size
, Node
);
291 for (i
=0; i
<size
; i
++) {
292 Node
*n
= gnode(t
, i
);
294 setnilvalue(gkey(n
));
295 setnilvalue(gval(n
));
298 t
->lsizenode
= cast_byte(lsize
);
299 t
->lastfree
= gnode(t
, size
); /* all positions are free */
303 void luaH_resize (lua_State
*L
, Table
*t
, int nasize
, int nhsize
) {
305 int oldasize
= t
->sizearray
;
306 int oldhsize
= t
->lsizenode
;
307 Node
*nold
= t
->node
; /* save old hash ... */
308 if (nasize
> oldasize
) /* array part must grow? */
309 setarrayvector(L
, t
, nasize
);
310 /* create new hash part with appropriate size */
311 setnodevector(L
, t
, nhsize
);
312 if (nasize
< oldasize
) { /* array part must shrink? */
313 t
->sizearray
= nasize
;
314 /* re-insert elements from vanishing slice */
315 for (i
=nasize
; i
<oldasize
; i
++) {
316 if (!ttisnil(&t
->array
[i
]))
317 luaH_setint(L
, t
, i
+ 1, &t
->array
[i
]);
320 luaM_reallocvector(L
, t
->array
, oldasize
, nasize
, TValue
);
322 /* re-insert elements from hash part */
323 for (i
= twoto(oldhsize
) - 1; i
>= 0; i
--) {
325 if (!ttisnil(gval(old
))) {
326 /* doesn't need barrier/invalidate cache, as entry was
327 already present in the table */
328 setobjt2t(L
, luaH_set(L
, t
, gkey(old
)), gval(old
));
332 luaM_freearray(L
, nold
, cast(size_t, twoto(oldhsize
))); /* free old array */
336 void luaH_resizearray (lua_State
*L
, Table
*t
, int nasize
) {
337 int nsize
= isdummy(t
->node
) ? 0 : sizenode(t
);
338 luaH_resize(L
, t
, nasize
, nsize
);
342 static void rehash (lua_State
*L
, Table
*t
, const TValue
*ek
) {
344 int nums
[MAXBITS
+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
347 for (i
=0; i
<=MAXBITS
; i
++) nums
[i
] = 0; /* reset counts */
348 nasize
= numusearray(t
, nums
); /* count keys in array part */
349 totaluse
= nasize
; /* all those keys are integer keys */
350 totaluse
+= numusehash(t
, nums
, &nasize
); /* count keys in hash part */
351 /* count extra key */
352 nasize
+= countint(ek
, nums
);
354 /* compute new size for array part */
355 na
= computesizes(nums
, &nasize
);
356 /* resize the table to new computed sizes */
357 luaH_resize(L
, t
, nasize
, totaluse
- na
);
363 ** }=============================================================
367 Table
*luaH_new (lua_State
*L
) {
368 Table
*t
= &luaC_newobj(L
, LUA_TTABLE
, sizeof(Table
), NULL
, 0)->h
;
370 t
->flags
= cast_byte(~0);
373 setnodevector(L
, t
, 0);
378 void luaH_free (lua_State
*L
, Table
*t
) {
379 if (!isdummy(t
->node
))
380 luaM_freearray(L
, t
->node
, cast(size_t, sizenode(t
)));
381 luaM_freearray(L
, t
->array
, t
->sizearray
);
386 static Node
*getfreepos (Table
*t
) {
387 while (t
->lastfree
> t
->node
) {
389 if (ttisnil(gkey(t
->lastfree
)))
392 return NULL
; /* could not find a free place */
398 ** inserts a new key into a hash table; first, check whether key's main
399 ** position is free. If not, check whether colliding node is in its main
400 ** position or not: if it is not, move colliding node to an empty place and
401 ** put new key in its main position; otherwise (colliding node is in its main
402 ** position), new key goes to an empty position.
404 TValue
*luaH_newkey (lua_State
*L
, Table
*t
, const TValue
*key
) {
406 if (ttisnil(key
)) luaG_runerror(L
, "table index is nil");
407 #if defined LUA_HAS_FLOAT_NUMBERS
408 else if (ttisnumber(key
) && luai_numisnan(L
, nvalue(key
)))
409 luaG_runerror(L
, "table index is NaN");
411 mp
= mainposition(t
, key
);
412 if (!ttisnil(gval(mp
)) || isdummy(mp
)) { /* main position is taken? */
414 Node
*n
= getfreepos(t
); /* get a free place */
415 if (n
== NULL
) { /* cannot find a free place? */
416 rehash(L
, t
, key
); /* grow table */
417 /* whatever called 'newkey' take care of TM cache and GC barrier */
418 return luaH_set(L
, t
, key
); /* insert key into grown table */
420 lua_assert(!isdummy(n
));
421 othern
= mainposition(t
, gkey(mp
));
422 if (othern
!= mp
) { /* is colliding node out of its main position? */
423 /* yes; move colliding node into free position */
424 while (gnext(othern
) != mp
) othern
= gnext(othern
); /* find previous */
425 gnext(othern
) = n
; /* redo the chain with `n' in place of `mp' */
426 *n
= *mp
; /* copy colliding node into free pos. (mp->next also goes) */
427 gnext(mp
) = NULL
; /* now `mp' is free */
428 setnilvalue(gval(mp
));
430 else { /* colliding node is in its own main position */
431 /* new node will go into free position */
432 gnext(n
) = gnext(mp
); /* chain new position */
437 setobj2t(L
, gkey(mp
), key
);
438 luaC_barrierback(L
, obj2gco(t
), key
);
439 lua_assert(ttisnil(gval(mp
)));
445 ** search function for integers
447 const TValue
*luaH_getint (Table
*t
, int key
) {
448 /* (1 <= key && key <= t->sizearray) */
449 if (cast(unsigned int, key
-1) < cast(unsigned int, t
->sizearray
))
450 return &t
->array
[key
-1];
452 lua_Number nk
= cast_num(key
);
453 Node
*n
= hashnum(t
, nk
);
454 do { /* check whether `key' is somewhere in the chain */
455 if (ttisnumber(gkey(n
)) && luai_numeq(nvalue(gkey(n
)), nk
))
456 return gval(n
); /* that's it */
459 return luaO_nilobject
;
465 ** search function for short strings
467 const TValue
*luaH_getstr (Table
*t
, TString
*key
) {
468 Node
*n
= hashstr(t
, key
);
469 lua_assert(key
->tsv
.tt
== LUA_TSHRSTR
);
470 do { /* check whether `key' is somewhere in the chain */
471 if (ttisshrstring(gkey(n
)) && eqshrstr(rawtsvalue(gkey(n
)), key
))
472 return gval(n
); /* that's it */
475 return luaO_nilobject
;
480 ** main search function
482 const TValue
*luaH_get (Table
*t
, const TValue
*key
) {
483 switch (ttype(key
)) {
484 case LUA_TSHRSTR
: return luaH_getstr(t
, rawtsvalue(key
));
485 case LUA_TNIL
: return luaO_nilobject
;
488 lua_Number n
= nvalue(key
);
489 lua_number2int(k
, n
);
490 if (luai_numeq(cast_num(k
), n
)) /* index is int? */
491 return luaH_getint(t
, k
); /* use specialized version */
492 /* else go through */
496 Node
*n
= mainposition(t
, key
);
497 do { /* check whether `key' is somewhere in the chain */
498 if (luaV_rawequalobj(gkey(n
), key
))
499 return gval(n
); /* that's it */
502 return luaO_nilobject
;
509 ** beware: when using this function you probably need to check a GC
510 ** barrier and invalidate the TM cache.
512 TValue
*luaH_set (lua_State
*L
, Table
*t
, const TValue
*key
) {
513 const TValue
*p
= luaH_get(t
, key
);
514 if (p
!= luaO_nilobject
)
515 return cast(TValue
*, p
);
516 else return luaH_newkey(L
, t
, key
);
520 void luaH_setint (lua_State
*L
, Table
*t
, int key
, TValue
*value
) {
521 const TValue
*p
= luaH_getint(t
, key
);
523 if (p
!= luaO_nilobject
)
524 cell
= cast(TValue
*, p
);
527 setnvalue(&k
, cast_num(key
));
528 cell
= luaH_newkey(L
, t
, &k
);
530 setobj2t(L
, cell
, value
);
534 static int unbound_search (Table
*t
, unsigned int j
) {
535 unsigned int i
= j
; /* i is zero or a present index */
537 /* find `i' and `j' such that i is present and j is not */
538 while (!ttisnil(luaH_getint(t
, j
))) {
541 if (j
> cast(unsigned int, MAX_INT
)) { /* overflow? */
542 /* table was built with bad purposes: resort to linear search */
544 while (!ttisnil(luaH_getint(t
, i
))) i
++;
548 /* now do a binary search between them */
550 unsigned int m
= (i
+j
)/2;
551 if (ttisnil(luaH_getint(t
, m
))) j
= m
;
559 ** Try to find a boundary in table `t'. A `boundary' is an integer index
560 ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
562 int luaH_getn (Table
*t
) {
563 unsigned int j
= t
->sizearray
;
564 if (j
> 0 && ttisnil(&t
->array
[j
- 1])) {
565 /* there is a boundary in the array part: (binary) search for it */
568 unsigned int m
= (i
+j
)/2;
569 if (ttisnil(&t
->array
[m
- 1])) j
= m
;
574 /* else must find a boundary in hash part */
575 else if (isdummy(t
->node
)) /* hash part is empty? */
576 return j
; /* that is easy... */
577 else return unbound_search(t
, j
);
582 #if defined(LUA_DEBUG)
584 Node
*luaH_mainposition (const Table
*t
, const TValue
*key
) {
585 return mainposition(t
, key
);
588 int luaH_isdummy (Node
*n
) { return isdummy(n
); }