1*088332b5SXin Li /*
2*088332b5SXin Li ** $Id: ltable.c $
3*088332b5SXin Li ** Lua tables (hash)
4*088332b5SXin Li ** See Copyright Notice in lua.h
5*088332b5SXin Li */
6*088332b5SXin Li
7*088332b5SXin Li #define ltable_c
8*088332b5SXin Li #define LUA_CORE
9*088332b5SXin Li
10*088332b5SXin Li #include "lprefix.h"
11*088332b5SXin Li
12*088332b5SXin Li
13*088332b5SXin Li /*
14*088332b5SXin Li ** Implementation of tables (aka arrays, objects, or hash tables).
15*088332b5SXin Li ** Tables keep its elements in two parts: an array part and a hash part.
16*088332b5SXin Li ** Non-negative integer keys are all candidates to be kept in the array
17*088332b5SXin Li ** part. The actual size of the array is the largest 'n' such that
18*088332b5SXin Li ** more than half the slots between 1 and n are in use.
19*088332b5SXin Li ** Hash uses a mix of chained scatter table with Brent's variation.
20*088332b5SXin Li ** A main invariant of these tables is that, if an element is not
21*088332b5SXin Li ** in its main position (i.e. the 'original' position that its hash gives
22*088332b5SXin Li ** to it), then the colliding element is in its own main position.
23*088332b5SXin Li ** Hence even when the load factor reaches 100%, performance remains good.
24*088332b5SXin Li */
25*088332b5SXin Li
26*088332b5SXin Li #include <math.h>
27*088332b5SXin Li #include <limits.h>
28*088332b5SXin Li
29*088332b5SXin Li #include "lua.h"
30*088332b5SXin Li
31*088332b5SXin Li #include "ldebug.h"
32*088332b5SXin Li #include "ldo.h"
33*088332b5SXin Li #include "lgc.h"
34*088332b5SXin Li #include "lmem.h"
35*088332b5SXin Li #include "lobject.h"
36*088332b5SXin Li #include "lstate.h"
37*088332b5SXin Li #include "lstring.h"
38*088332b5SXin Li #include "ltable.h"
39*088332b5SXin Li #include "lvm.h"
40*088332b5SXin Li
41*088332b5SXin Li
42*088332b5SXin Li /*
43*088332b5SXin Li ** MAXABITS is the largest integer such that MAXASIZE fits in an
44*088332b5SXin Li ** unsigned int.
45*088332b5SXin Li */
46*088332b5SXin Li #define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
47*088332b5SXin Li
48*088332b5SXin Li
49*088332b5SXin Li /*
50*088332b5SXin Li ** MAXASIZE is the maximum size of the array part. It is the minimum
51*088332b5SXin Li ** between 2^MAXABITS and the maximum size that, measured in bytes,
52*088332b5SXin Li ** fits in a 'size_t'.
53*088332b5SXin Li */
54*088332b5SXin Li #define MAXASIZE luaM_limitN(1u << MAXABITS, TValue)
55*088332b5SXin Li
56*088332b5SXin Li /*
57*088332b5SXin Li ** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a
58*088332b5SXin Li ** signed int.
59*088332b5SXin Li */
60*088332b5SXin Li #define MAXHBITS (MAXABITS - 1)
61*088332b5SXin Li
62*088332b5SXin Li
63*088332b5SXin Li /*
64*088332b5SXin Li ** MAXHSIZE is the maximum size of the hash part. It is the minimum
65*088332b5SXin Li ** between 2^MAXHBITS and the maximum size such that, measured in bytes,
66*088332b5SXin Li ** it fits in a 'size_t'.
67*088332b5SXin Li */
68*088332b5SXin Li #define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node)
69*088332b5SXin Li
70*088332b5SXin Li
71*088332b5SXin Li #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
72*088332b5SXin Li
73*088332b5SXin Li #define hashstr(t,str) hashpow2(t, (str)->hash)
74*088332b5SXin Li #define hashboolean(t,p) hashpow2(t, p)
75*088332b5SXin Li #define hashint(t,i) hashpow2(t, i)
76*088332b5SXin Li
77*088332b5SXin Li
78*088332b5SXin Li /*
79*088332b5SXin Li ** for some types, it is better to avoid modulus by power of 2, as
80*088332b5SXin Li ** they tend to have many 2 factors.
81*088332b5SXin Li */
82*088332b5SXin Li #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
83*088332b5SXin Li
84*088332b5SXin Li
85*088332b5SXin Li #define hashpointer(t,p) hashmod(t, point2uint(p))
86*088332b5SXin Li
87*088332b5SXin Li
88*088332b5SXin Li #define dummynode (&dummynode_)
89*088332b5SXin Li
90*088332b5SXin Li static const Node dummynode_ = {
91*088332b5SXin Li {{NULL}, LUA_VEMPTY, /* value's value and type */
92*088332b5SXin Li LUA_VNIL, 0, {NULL}} /* key type, next, and key value */
93*088332b5SXin Li };
94*088332b5SXin Li
95*088332b5SXin Li
96*088332b5SXin Li static const TValue absentkey = {ABSTKEYCONSTANT};
97*088332b5SXin Li
98*088332b5SXin Li
99*088332b5SXin Li
100*088332b5SXin Li /*
101*088332b5SXin Li ** Hash for floating-point numbers.
102*088332b5SXin Li ** The main computation should be just
103*088332b5SXin Li ** n = frexp(n, &i); return (n * INT_MAX) + i
104*088332b5SXin Li ** but there are some numerical subtleties.
105*088332b5SXin Li ** In a two-complement representation, INT_MAX does not has an exact
106*088332b5SXin Li ** representation as a float, but INT_MIN does; because the absolute
107*088332b5SXin Li ** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
108*088332b5SXin Li ** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
109*088332b5SXin Li ** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
110*088332b5SXin Li ** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
111*088332b5SXin Li ** INT_MIN.
112*088332b5SXin Li */
113*088332b5SXin Li #if !defined(l_hashfloat)
l_hashfloat(lua_Number n)114*088332b5SXin Li static int l_hashfloat (lua_Number n) {
115*088332b5SXin Li int i;
116*088332b5SXin Li lua_Integer ni;
117*088332b5SXin Li n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
118*088332b5SXin Li if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */
119*088332b5SXin Li lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL));
120*088332b5SXin Li return 0;
121*088332b5SXin Li }
122*088332b5SXin Li else { /* normal case */
123*088332b5SXin Li unsigned int u = cast_uint(i) + cast_uint(ni);
124*088332b5SXin Li return cast_int(u <= cast_uint(INT_MAX) ? u : ~u);
125*088332b5SXin Li }
126*088332b5SXin Li }
127*088332b5SXin Li #endif
128*088332b5SXin Li
129*088332b5SXin Li
130*088332b5SXin Li /*
131*088332b5SXin Li ** returns the 'main' position of an element in a table (that is,
132*088332b5SXin Li ** the index of its hash value). The key comes broken (tag in 'ktt'
133*088332b5SXin Li ** and value in 'vkl') so that we can call it on keys inserted into
134*088332b5SXin Li ** nodes.
135*088332b5SXin Li */
mainposition(const Table * t,int ktt,const Value * kvl)136*088332b5SXin Li static Node *mainposition (const Table *t, int ktt, const Value *kvl) {
137*088332b5SXin Li switch (withvariant(ktt)) {
138*088332b5SXin Li case LUA_VNUMINT:
139*088332b5SXin Li return hashint(t, ivalueraw(*kvl));
140*088332b5SXin Li case LUA_VNUMFLT:
141*088332b5SXin Li return hashmod(t, l_hashfloat(fltvalueraw(*kvl)));
142*088332b5SXin Li case LUA_VSHRSTR:
143*088332b5SXin Li return hashstr(t, tsvalueraw(*kvl));
144*088332b5SXin Li case LUA_VLNGSTR:
145*088332b5SXin Li return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl)));
146*088332b5SXin Li case LUA_VFALSE:
147*088332b5SXin Li return hashboolean(t, 0);
148*088332b5SXin Li case LUA_VTRUE:
149*088332b5SXin Li return hashboolean(t, 1);
150*088332b5SXin Li case LUA_VLIGHTUSERDATA:
151*088332b5SXin Li return hashpointer(t, pvalueraw(*kvl));
152*088332b5SXin Li case LUA_VLCF:
153*088332b5SXin Li return hashpointer(t, fvalueraw(*kvl));
154*088332b5SXin Li default:
155*088332b5SXin Li return hashpointer(t, gcvalueraw(*kvl));
156*088332b5SXin Li }
157*088332b5SXin Li }
158*088332b5SXin Li
159*088332b5SXin Li
160*088332b5SXin Li /*
161*088332b5SXin Li ** Returns the main position of an element given as a 'TValue'
162*088332b5SXin Li */
mainpositionTV(const Table * t,const TValue * key)163*088332b5SXin Li static Node *mainpositionTV (const Table *t, const TValue *key) {
164*088332b5SXin Li return mainposition(t, rawtt(key), valraw(key));
165*088332b5SXin Li }
166*088332b5SXin Li
167*088332b5SXin Li
168*088332b5SXin Li /*
169*088332b5SXin Li ** Check whether key 'k1' is equal to the key in node 'n2'.
170*088332b5SXin Li ** This equality is raw, so there are no metamethods. Floats
171*088332b5SXin Li ** with integer values have been normalized, so integers cannot
172*088332b5SXin Li ** be equal to floats. It is assumed that 'eqshrstr' is simply
173*088332b5SXin Li ** pointer equality, so that short strings are handled in the
174*088332b5SXin Li ** default case.
175*088332b5SXin Li */
equalkey(const TValue * k1,const Node * n2)176*088332b5SXin Li static int equalkey (const TValue *k1, const Node *n2) {
177*088332b5SXin Li if (rawtt(k1) != keytt(n2)) /* not the same variants? */
178*088332b5SXin Li return 0; /* cannot be same key */
179*088332b5SXin Li switch (ttypetag(k1)) {
180*088332b5SXin Li case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
181*088332b5SXin Li return 1;
182*088332b5SXin Li case LUA_VNUMINT:
183*088332b5SXin Li return (ivalue(k1) == keyival(n2));
184*088332b5SXin Li case LUA_VNUMFLT:
185*088332b5SXin Li return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2)));
186*088332b5SXin Li case LUA_VLIGHTUSERDATA:
187*088332b5SXin Li return pvalue(k1) == pvalueraw(keyval(n2));
188*088332b5SXin Li case LUA_VLCF:
189*088332b5SXin Li return fvalue(k1) == fvalueraw(keyval(n2));
190*088332b5SXin Li case LUA_VLNGSTR:
191*088332b5SXin Li return luaS_eqlngstr(tsvalue(k1), keystrval(n2));
192*088332b5SXin Li default:
193*088332b5SXin Li return gcvalue(k1) == gcvalueraw(keyval(n2));
194*088332b5SXin Li }
195*088332b5SXin Li }
196*088332b5SXin Li
197*088332b5SXin Li
198*088332b5SXin Li /*
199*088332b5SXin Li ** True if value of 'alimit' is equal to the real size of the array
200*088332b5SXin Li ** part of table 't'. (Otherwise, the array part must be larger than
201*088332b5SXin Li ** 'alimit'.)
202*088332b5SXin Li */
203*088332b5SXin Li #define limitequalsasize(t) (isrealasize(t) || ispow2((t)->alimit))
204*088332b5SXin Li
205*088332b5SXin Li
206*088332b5SXin Li /*
207*088332b5SXin Li ** Returns the real size of the 'array' array
208*088332b5SXin Li */
luaH_realasize(const Table * t)209*088332b5SXin Li LUAI_FUNC unsigned int luaH_realasize (const Table *t) {
210*088332b5SXin Li if (limitequalsasize(t))
211*088332b5SXin Li return t->alimit; /* this is the size */
212*088332b5SXin Li else {
213*088332b5SXin Li unsigned int size = t->alimit;
214*088332b5SXin Li /* compute the smallest power of 2 not smaller than 'n' */
215*088332b5SXin Li size |= (size >> 1);
216*088332b5SXin Li size |= (size >> 2);
217*088332b5SXin Li size |= (size >> 4);
218*088332b5SXin Li size |= (size >> 8);
219*088332b5SXin Li size |= (size >> 16);
220*088332b5SXin Li #if (UINT_MAX >> 30) > 3
221*088332b5SXin Li size |= (size >> 32); /* unsigned int has more than 32 bits */
222*088332b5SXin Li #endif
223*088332b5SXin Li size++;
224*088332b5SXin Li lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
225*088332b5SXin Li return size;
226*088332b5SXin Li }
227*088332b5SXin Li }
228*088332b5SXin Li
229*088332b5SXin Li
230*088332b5SXin Li /*
231*088332b5SXin Li ** Check whether real size of the array is a power of 2.
232*088332b5SXin Li ** (If it is not, 'alimit' cannot be changed to any other value
233*088332b5SXin Li ** without changing the real size.)
234*088332b5SXin Li */
ispow2realasize(const Table * t)235*088332b5SXin Li static int ispow2realasize (const Table *t) {
236*088332b5SXin Li return (!isrealasize(t) || ispow2(t->alimit));
237*088332b5SXin Li }
238*088332b5SXin Li
239*088332b5SXin Li
setlimittosize(Table * t)240*088332b5SXin Li static unsigned int setlimittosize (Table *t) {
241*088332b5SXin Li t->alimit = luaH_realasize(t);
242*088332b5SXin Li setrealasize(t);
243*088332b5SXin Li return t->alimit;
244*088332b5SXin Li }
245*088332b5SXin Li
246*088332b5SXin Li
247*088332b5SXin Li #define limitasasize(t) check_exp(isrealasize(t), t->alimit)
248*088332b5SXin Li
249*088332b5SXin Li
250*088332b5SXin Li
251*088332b5SXin Li /*
252*088332b5SXin Li ** "Generic" get version. (Not that generic: not valid for integers,
253*088332b5SXin Li ** which may be in array part, nor for floats with integral values.)
254*088332b5SXin Li */
getgeneric(Table * t,const TValue * key)255*088332b5SXin Li static const TValue *getgeneric (Table *t, const TValue *key) {
256*088332b5SXin Li Node *n = mainpositionTV(t, key);
257*088332b5SXin Li for (;;) { /* check whether 'key' is somewhere in the chain */
258*088332b5SXin Li if (equalkey(key, n))
259*088332b5SXin Li return gval(n); /* that's it */
260*088332b5SXin Li else {
261*088332b5SXin Li int nx = gnext(n);
262*088332b5SXin Li if (nx == 0)
263*088332b5SXin Li return &absentkey; /* not found */
264*088332b5SXin Li n += nx;
265*088332b5SXin Li }
266*088332b5SXin Li }
267*088332b5SXin Li }
268*088332b5SXin Li
269*088332b5SXin Li
270*088332b5SXin Li /*
271*088332b5SXin Li ** returns the index for 'k' if 'k' is an appropriate key to live in
272*088332b5SXin Li ** the array part of a table, 0 otherwise.
273*088332b5SXin Li */
arrayindex(lua_Integer k)274*088332b5SXin Li static unsigned int arrayindex (lua_Integer k) {
275*088332b5SXin Li if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */
276*088332b5SXin Li return cast_uint(k); /* 'key' is an appropriate array index */
277*088332b5SXin Li else
278*088332b5SXin Li return 0;
279*088332b5SXin Li }
280*088332b5SXin Li
281*088332b5SXin Li
282*088332b5SXin Li /*
283*088332b5SXin Li ** returns the index of a 'key' for table traversals. First goes all
284*088332b5SXin Li ** elements in the array part, then elements in the hash part. The
285*088332b5SXin Li ** beginning of a traversal is signaled by 0.
286*088332b5SXin Li */
findindex(lua_State * L,Table * t,TValue * key,unsigned int asize)287*088332b5SXin Li static unsigned int findindex (lua_State *L, Table *t, TValue *key,
288*088332b5SXin Li unsigned int asize) {
289*088332b5SXin Li unsigned int i;
290*088332b5SXin Li if (ttisnil(key)) return 0; /* first iteration */
291*088332b5SXin Li i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0;
292*088332b5SXin Li if (i - 1u < asize) /* is 'key' inside array part? */
293*088332b5SXin Li return i; /* yes; that's the index */
294*088332b5SXin Li else {
295*088332b5SXin Li const TValue *n = getgeneric(t, key);
296*088332b5SXin Li if (unlikely(isabstkey(n)))
297*088332b5SXin Li luaG_runerror(L, "invalid key to 'next'"); /* key not found */
298*088332b5SXin Li i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */
299*088332b5SXin Li /* hash elements are numbered after array ones */
300*088332b5SXin Li return (i + 1) + asize;
301*088332b5SXin Li }
302*088332b5SXin Li }
303*088332b5SXin Li
304*088332b5SXin Li
luaH_next(lua_State * L,Table * t,StkId key)305*088332b5SXin Li int luaH_next (lua_State *L, Table *t, StkId key) {
306*088332b5SXin Li unsigned int asize = luaH_realasize(t);
307*088332b5SXin Li unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */
308*088332b5SXin Li for (; i < asize; i++) { /* try first array part */
309*088332b5SXin Li if (!isempty(&t->array[i])) { /* a non-empty entry? */
310*088332b5SXin Li setivalue(s2v(key), i + 1);
311*088332b5SXin Li setobj2s(L, key + 1, &t->array[i]);
312*088332b5SXin Li return 1;
313*088332b5SXin Li }
314*088332b5SXin Li }
315*088332b5SXin Li for (i -= asize; cast_int(i) < sizenode(t); i++) { /* hash part */
316*088332b5SXin Li if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */
317*088332b5SXin Li Node *n = gnode(t, i);
318*088332b5SXin Li getnodekey(L, s2v(key), n);
319*088332b5SXin Li setobj2s(L, key + 1, gval(n));
320*088332b5SXin Li return 1;
321*088332b5SXin Li }
322*088332b5SXin Li }
323*088332b5SXin Li return 0; /* no more elements */
324*088332b5SXin Li }
325*088332b5SXin Li
326*088332b5SXin Li
freehash(lua_State * L,Table * t)327*088332b5SXin Li static void freehash (lua_State *L, Table *t) {
328*088332b5SXin Li if (!isdummy(t))
329*088332b5SXin Li luaM_freearray(L, t->node, cast_sizet(sizenode(t)));
330*088332b5SXin Li }
331*088332b5SXin Li
332*088332b5SXin Li
333*088332b5SXin Li /*
334*088332b5SXin Li ** {=============================================================
335*088332b5SXin Li ** Rehash
336*088332b5SXin Li ** ==============================================================
337*088332b5SXin Li */
338*088332b5SXin Li
339*088332b5SXin Li /*
340*088332b5SXin Li ** Compute the optimal size for the array part of table 't'. 'nums' is a
341*088332b5SXin Li ** "count array" where 'nums[i]' is the number of integers in the table
342*088332b5SXin Li ** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
343*088332b5SXin Li ** integer keys in the table and leaves with the number of keys that
344*088332b5SXin Li ** will go to the array part; return the optimal size. (The condition
345*088332b5SXin Li ** 'twotoi > 0' in the for loop stops the loop if 'twotoi' overflows.)
346*088332b5SXin Li */
computesizes(unsigned int nums[],unsigned int * pna)347*088332b5SXin Li static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
348*088332b5SXin Li int i;
349*088332b5SXin Li unsigned int twotoi; /* 2^i (candidate for optimal size) */
350*088332b5SXin Li unsigned int a = 0; /* number of elements smaller than 2^i */
351*088332b5SXin Li unsigned int na = 0; /* number of elements to go to array part */
352*088332b5SXin Li unsigned int optimal = 0; /* optimal size for array part */
353*088332b5SXin Li /* loop while keys can fill more than half of total size */
354*088332b5SXin Li for (i = 0, twotoi = 1;
355*088332b5SXin Li twotoi > 0 && *pna > twotoi / 2;
356*088332b5SXin Li i++, twotoi *= 2) {
357*088332b5SXin Li a += nums[i];
358*088332b5SXin Li if (a > twotoi/2) { /* more than half elements present? */
359*088332b5SXin Li optimal = twotoi; /* optimal size (till now) */
360*088332b5SXin Li na = a; /* all elements up to 'optimal' will go to array part */
361*088332b5SXin Li }
362*088332b5SXin Li }
363*088332b5SXin Li lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
364*088332b5SXin Li *pna = na;
365*088332b5SXin Li return optimal;
366*088332b5SXin Li }
367*088332b5SXin Li
368*088332b5SXin Li
countint(lua_Integer key,unsigned int * nums)369*088332b5SXin Li static int countint (lua_Integer key, unsigned int *nums) {
370*088332b5SXin Li unsigned int k = arrayindex(key);
371*088332b5SXin Li if (k != 0) { /* is 'key' an appropriate array index? */
372*088332b5SXin Li nums[luaO_ceillog2(k)]++; /* count as such */
373*088332b5SXin Li return 1;
374*088332b5SXin Li }
375*088332b5SXin Li else
376*088332b5SXin Li return 0;
377*088332b5SXin Li }
378*088332b5SXin Li
379*088332b5SXin Li
380*088332b5SXin Li /*
381*088332b5SXin Li ** Count keys in array part of table 't': Fill 'nums[i]' with
382*088332b5SXin Li ** number of keys that will go into corresponding slice and return
383*088332b5SXin Li ** total number of non-nil keys.
384*088332b5SXin Li */
numusearray(const Table * t,unsigned int * nums)385*088332b5SXin Li static unsigned int numusearray (const Table *t, unsigned int *nums) {
386*088332b5SXin Li int lg;
387*088332b5SXin Li unsigned int ttlg; /* 2^lg */
388*088332b5SXin Li unsigned int ause = 0; /* summation of 'nums' */
389*088332b5SXin Li unsigned int i = 1; /* count to traverse all array keys */
390*088332b5SXin Li unsigned int asize = limitasasize(t); /* real array size */
391*088332b5SXin Li /* traverse each slice */
392*088332b5SXin Li for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) {
393*088332b5SXin Li unsigned int lc = 0; /* counter */
394*088332b5SXin Li unsigned int lim = ttlg;
395*088332b5SXin Li if (lim > asize) {
396*088332b5SXin Li lim = asize; /* adjust upper limit */
397*088332b5SXin Li if (i > lim)
398*088332b5SXin Li break; /* no more elements to count */
399*088332b5SXin Li }
400*088332b5SXin Li /* count elements in range (2^(lg - 1), 2^lg] */
401*088332b5SXin Li for (; i <= lim; i++) {
402*088332b5SXin Li if (!isempty(&t->array[i-1]))
403*088332b5SXin Li lc++;
404*088332b5SXin Li }
405*088332b5SXin Li nums[lg] += lc;
406*088332b5SXin Li ause += lc;
407*088332b5SXin Li }
408*088332b5SXin Li return ause;
409*088332b5SXin Li }
410*088332b5SXin Li
411*088332b5SXin Li
numusehash(const Table * t,unsigned int * nums,unsigned int * pna)412*088332b5SXin Li static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
413*088332b5SXin Li int totaluse = 0; /* total number of elements */
414*088332b5SXin Li int ause = 0; /* elements added to 'nums' (can go to array part) */
415*088332b5SXin Li int i = sizenode(t);
416*088332b5SXin Li while (i--) {
417*088332b5SXin Li Node *n = &t->node[i];
418*088332b5SXin Li if (!isempty(gval(n))) {
419*088332b5SXin Li if (keyisinteger(n))
420*088332b5SXin Li ause += countint(keyival(n), nums);
421*088332b5SXin Li totaluse++;
422*088332b5SXin Li }
423*088332b5SXin Li }
424*088332b5SXin Li *pna += ause;
425*088332b5SXin Li return totaluse;
426*088332b5SXin Li }
427*088332b5SXin Li
428*088332b5SXin Li
429*088332b5SXin Li /*
430*088332b5SXin Li ** Creates an array for the hash part of a table with the given
431*088332b5SXin Li ** size, or reuses the dummy node if size is zero.
432*088332b5SXin Li ** The computation for size overflow is in two steps: the first
433*088332b5SXin Li ** comparison ensures that the shift in the second one does not
434*088332b5SXin Li ** overflow.
435*088332b5SXin Li */
setnodevector(lua_State * L,Table * t,unsigned int size)436*088332b5SXin Li static void setnodevector (lua_State *L, Table *t, unsigned int size) {
437*088332b5SXin Li if (size == 0) { /* no elements to hash part? */
438*088332b5SXin Li t->node = cast(Node *, dummynode); /* use common 'dummynode' */
439*088332b5SXin Li t->lsizenode = 0;
440*088332b5SXin Li t->lastfree = NULL; /* signal that it is using dummy node */
441*088332b5SXin Li }
442*088332b5SXin Li else {
443*088332b5SXin Li int i;
444*088332b5SXin Li int lsize = luaO_ceillog2(size);
445*088332b5SXin Li if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE)
446*088332b5SXin Li luaG_runerror(L, "table overflow");
447*088332b5SXin Li size = twoto(lsize);
448*088332b5SXin Li t->node = luaM_newvector(L, size, Node);
449*088332b5SXin Li for (i = 0; i < (int)size; i++) {
450*088332b5SXin Li Node *n = gnode(t, i);
451*088332b5SXin Li gnext(n) = 0;
452*088332b5SXin Li setnilkey(n);
453*088332b5SXin Li setempty(gval(n));
454*088332b5SXin Li }
455*088332b5SXin Li t->lsizenode = cast_byte(lsize);
456*088332b5SXin Li t->lastfree = gnode(t, size); /* all positions are free */
457*088332b5SXin Li }
458*088332b5SXin Li }
459*088332b5SXin Li
460*088332b5SXin Li
461*088332b5SXin Li /*
462*088332b5SXin Li ** (Re)insert all elements from the hash part of 'ot' into table 't'.
463*088332b5SXin Li */
reinsert(lua_State * L,Table * ot,Table * t)464*088332b5SXin Li static void reinsert (lua_State *L, Table *ot, Table *t) {
465*088332b5SXin Li int j;
466*088332b5SXin Li int size = sizenode(ot);
467*088332b5SXin Li for (j = 0; j < size; j++) {
468*088332b5SXin Li Node *old = gnode(ot, j);
469*088332b5SXin Li if (!isempty(gval(old))) {
470*088332b5SXin Li /* doesn't need barrier/invalidate cache, as entry was
471*088332b5SXin Li already present in the table */
472*088332b5SXin Li TValue k;
473*088332b5SXin Li getnodekey(L, &k, old);
474*088332b5SXin Li setobjt2t(L, luaH_set(L, t, &k), gval(old));
475*088332b5SXin Li }
476*088332b5SXin Li }
477*088332b5SXin Li }
478*088332b5SXin Li
479*088332b5SXin Li
480*088332b5SXin Li /*
481*088332b5SXin Li ** Exchange the hash part of 't1' and 't2'.
482*088332b5SXin Li */
exchangehashpart(Table * t1,Table * t2)483*088332b5SXin Li static void exchangehashpart (Table *t1, Table *t2) {
484*088332b5SXin Li lu_byte lsizenode = t1->lsizenode;
485*088332b5SXin Li Node *node = t1->node;
486*088332b5SXin Li Node *lastfree = t1->lastfree;
487*088332b5SXin Li t1->lsizenode = t2->lsizenode;
488*088332b5SXin Li t1->node = t2->node;
489*088332b5SXin Li t1->lastfree = t2->lastfree;
490*088332b5SXin Li t2->lsizenode = lsizenode;
491*088332b5SXin Li t2->node = node;
492*088332b5SXin Li t2->lastfree = lastfree;
493*088332b5SXin Li }
494*088332b5SXin Li
495*088332b5SXin Li
496*088332b5SXin Li /*
497*088332b5SXin Li ** Resize table 't' for the new given sizes. Both allocations (for
498*088332b5SXin Li ** the hash part and for the array part) can fail, which creates some
499*088332b5SXin Li ** subtleties. If the first allocation, for the hash part, fails, an
500*088332b5SXin Li ** error is raised and that is it. Otherwise, it copies the elements from
501*088332b5SXin Li ** the shrinking part of the array (if it is shrinking) into the new
502*088332b5SXin Li ** hash. Then it reallocates the array part. If that fails, the table
503*088332b5SXin Li ** is in its original state; the function frees the new hash part and then
504*088332b5SXin Li ** raises the allocation error. Otherwise, it sets the new hash part
505*088332b5SXin Li ** into the table, initializes the new part of the array (if any) with
506*088332b5SXin Li ** nils and reinserts the elements of the old hash back into the new
507*088332b5SXin Li ** parts of the table.
508*088332b5SXin Li */
luaH_resize(lua_State * L,Table * t,unsigned int newasize,unsigned int nhsize)509*088332b5SXin Li void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
510*088332b5SXin Li unsigned int nhsize) {
511*088332b5SXin Li unsigned int i;
512*088332b5SXin Li Table newt; /* to keep the new hash part */
513*088332b5SXin Li unsigned int oldasize = setlimittosize(t);
514*088332b5SXin Li TValue *newarray;
515*088332b5SXin Li /* create new hash part with appropriate size into 'newt' */
516*088332b5SXin Li setnodevector(L, &newt, nhsize);
517*088332b5SXin Li if (newasize < oldasize) { /* will array shrink? */
518*088332b5SXin Li t->alimit = newasize; /* pretend array has new size... */
519*088332b5SXin Li exchangehashpart(t, &newt); /* and new hash */
520*088332b5SXin Li /* re-insert into the new hash the elements from vanishing slice */
521*088332b5SXin Li for (i = newasize; i < oldasize; i++) {
522*088332b5SXin Li if (!isempty(&t->array[i]))
523*088332b5SXin Li luaH_setint(L, t, i + 1, &t->array[i]);
524*088332b5SXin Li }
525*088332b5SXin Li t->alimit = oldasize; /* restore current size... */
526*088332b5SXin Li exchangehashpart(t, &newt); /* and hash (in case of errors) */
527*088332b5SXin Li }
528*088332b5SXin Li /* allocate new array */
529*088332b5SXin Li newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue);
530*088332b5SXin Li if (unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */
531*088332b5SXin Li freehash(L, &newt); /* release new hash part */
532*088332b5SXin Li luaM_error(L); /* raise error (with array unchanged) */
533*088332b5SXin Li }
534*088332b5SXin Li /* allocation ok; initialize new part of the array */
535*088332b5SXin Li exchangehashpart(t, &newt); /* 't' has the new hash ('newt' has the old) */
536*088332b5SXin Li t->array = newarray; /* set new array part */
537*088332b5SXin Li t->alimit = newasize;
538*088332b5SXin Li for (i = oldasize; i < newasize; i++) /* clear new slice of the array */
539*088332b5SXin Li setempty(&t->array[i]);
540*088332b5SXin Li /* re-insert elements from old hash part into new parts */
541*088332b5SXin Li reinsert(L, &newt, t); /* 'newt' now has the old hash */
542*088332b5SXin Li freehash(L, &newt); /* free old hash part */
543*088332b5SXin Li }
544*088332b5SXin Li
545*088332b5SXin Li
luaH_resizearray(lua_State * L,Table * t,unsigned int nasize)546*088332b5SXin Li void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
547*088332b5SXin Li int nsize = allocsizenode(t);
548*088332b5SXin Li luaH_resize(L, t, nasize, nsize);
549*088332b5SXin Li }
550*088332b5SXin Li
551*088332b5SXin Li /*
552*088332b5SXin Li ** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
553*088332b5SXin Li */
rehash(lua_State * L,Table * t,const TValue * ek)554*088332b5SXin Li static void rehash (lua_State *L, Table *t, const TValue *ek) {
555*088332b5SXin Li unsigned int asize; /* optimal size for array part */
556*088332b5SXin Li unsigned int na; /* number of keys in the array part */
557*088332b5SXin Li unsigned int nums[MAXABITS + 1];
558*088332b5SXin Li int i;
559*088332b5SXin Li int totaluse;
560*088332b5SXin Li for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
561*088332b5SXin Li setlimittosize(t);
562*088332b5SXin Li na = numusearray(t, nums); /* count keys in array part */
563*088332b5SXin Li totaluse = na; /* all those keys are integer keys */
564*088332b5SXin Li totaluse += numusehash(t, nums, &na); /* count keys in hash part */
565*088332b5SXin Li /* count extra key */
566*088332b5SXin Li if (ttisinteger(ek))
567*088332b5SXin Li na += countint(ivalue(ek), nums);
568*088332b5SXin Li totaluse++;
569*088332b5SXin Li /* compute new size for array part */
570*088332b5SXin Li asize = computesizes(nums, &na);
571*088332b5SXin Li /* resize the table to new computed sizes */
572*088332b5SXin Li luaH_resize(L, t, asize, totaluse - na);
573*088332b5SXin Li }
574*088332b5SXin Li
575*088332b5SXin Li
576*088332b5SXin Li
577*088332b5SXin Li /*
578*088332b5SXin Li ** }=============================================================
579*088332b5SXin Li */
580*088332b5SXin Li
581*088332b5SXin Li
luaH_new(lua_State * L)582*088332b5SXin Li Table *luaH_new (lua_State *L) {
583*088332b5SXin Li GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table));
584*088332b5SXin Li Table *t = gco2t(o);
585*088332b5SXin Li t->metatable = NULL;
586*088332b5SXin Li t->flags = cast_byte(maskflags); /* table has no metamethod fields */
587*088332b5SXin Li t->array = NULL;
588*088332b5SXin Li t->alimit = 0;
589*088332b5SXin Li setnodevector(L, t, 0);
590*088332b5SXin Li return t;
591*088332b5SXin Li }
592*088332b5SXin Li
593*088332b5SXin Li
luaH_free(lua_State * L,Table * t)594*088332b5SXin Li void luaH_free (lua_State *L, Table *t) {
595*088332b5SXin Li freehash(L, t);
596*088332b5SXin Li luaM_freearray(L, t->array, luaH_realasize(t));
597*088332b5SXin Li luaM_free(L, t);
598*088332b5SXin Li }
599*088332b5SXin Li
600*088332b5SXin Li
getfreepos(Table * t)601*088332b5SXin Li static Node *getfreepos (Table *t) {
602*088332b5SXin Li if (!isdummy(t)) {
603*088332b5SXin Li while (t->lastfree > t->node) {
604*088332b5SXin Li t->lastfree--;
605*088332b5SXin Li if (keyisnil(t->lastfree))
606*088332b5SXin Li return t->lastfree;
607*088332b5SXin Li }
608*088332b5SXin Li }
609*088332b5SXin Li return NULL; /* could not find a free place */
610*088332b5SXin Li }
611*088332b5SXin Li
612*088332b5SXin Li
613*088332b5SXin Li
614*088332b5SXin Li /*
615*088332b5SXin Li ** inserts a new key into a hash table; first, check whether key's main
616*088332b5SXin Li ** position is free. If not, check whether colliding node is in its main
617*088332b5SXin Li ** position or not: if it is not, move colliding node to an empty place and
618*088332b5SXin Li ** put new key in its main position; otherwise (colliding node is in its main
619*088332b5SXin Li ** position), new key goes to an empty position.
620*088332b5SXin Li */
luaH_newkey(lua_State * L,Table * t,const TValue * key)621*088332b5SXin Li TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
622*088332b5SXin Li Node *mp;
623*088332b5SXin Li TValue aux;
624*088332b5SXin Li if (unlikely(ttisnil(key)))
625*088332b5SXin Li luaG_runerror(L, "table index is nil");
626*088332b5SXin Li else if (ttisfloat(key)) {
627*088332b5SXin Li lua_Number f = fltvalue(key);
628*088332b5SXin Li lua_Integer k;
629*088332b5SXin Li if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */
630*088332b5SXin Li setivalue(&aux, k);
631*088332b5SXin Li key = &aux; /* insert it as an integer */
632*088332b5SXin Li }
633*088332b5SXin Li else if (unlikely(luai_numisnan(f)))
634*088332b5SXin Li luaG_runerror(L, "table index is NaN");
635*088332b5SXin Li }
636*088332b5SXin Li mp = mainpositionTV(t, key);
637*088332b5SXin Li if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */
638*088332b5SXin Li Node *othern;
639*088332b5SXin Li Node *f = getfreepos(t); /* get a free place */
640*088332b5SXin Li if (f == NULL) { /* cannot find a free place? */
641*088332b5SXin Li rehash(L, t, key); /* grow table */
642*088332b5SXin Li /* whatever called 'newkey' takes care of TM cache */
643*088332b5SXin Li return luaH_set(L, t, key); /* insert key into grown table */
644*088332b5SXin Li }
645*088332b5SXin Li lua_assert(!isdummy(t));
646*088332b5SXin Li othern = mainposition(t, keytt(mp), &keyval(mp));
647*088332b5SXin Li if (othern != mp) { /* is colliding node out of its main position? */
648*088332b5SXin Li /* yes; move colliding node into free position */
649*088332b5SXin Li while (othern + gnext(othern) != mp) /* find previous */
650*088332b5SXin Li othern += gnext(othern);
651*088332b5SXin Li gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */
652*088332b5SXin Li *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */
653*088332b5SXin Li if (gnext(mp) != 0) {
654*088332b5SXin Li gnext(f) += cast_int(mp - f); /* correct 'next' */
655*088332b5SXin Li gnext(mp) = 0; /* now 'mp' is free */
656*088332b5SXin Li }
657*088332b5SXin Li setempty(gval(mp));
658*088332b5SXin Li }
659*088332b5SXin Li else { /* colliding node is in its own main position */
660*088332b5SXin Li /* new node will go into free position */
661*088332b5SXin Li if (gnext(mp) != 0)
662*088332b5SXin Li gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */
663*088332b5SXin Li else lua_assert(gnext(f) == 0);
664*088332b5SXin Li gnext(mp) = cast_int(f - mp);
665*088332b5SXin Li mp = f;
666*088332b5SXin Li }
667*088332b5SXin Li }
668*088332b5SXin Li setnodekey(L, mp, key);
669*088332b5SXin Li luaC_barrierback(L, obj2gco(t), key);
670*088332b5SXin Li lua_assert(isempty(gval(mp)));
671*088332b5SXin Li return gval(mp);
672*088332b5SXin Li }
673*088332b5SXin Li
674*088332b5SXin Li
675*088332b5SXin Li /*
676*088332b5SXin Li ** Search function for integers. If integer is inside 'alimit', get it
677*088332b5SXin Li ** directly from the array part. Otherwise, if 'alimit' is not equal to
678*088332b5SXin Li ** the real size of the array, key still can be in the array part. In
679*088332b5SXin Li ** this case, try to avoid a call to 'luaH_realasize' when key is just
680*088332b5SXin Li ** one more than the limit (so that it can be incremented without
681*088332b5SXin Li ** changing the real size of the array).
682*088332b5SXin Li */
luaH_getint(Table * t,lua_Integer key)683*088332b5SXin Li const TValue *luaH_getint (Table *t, lua_Integer key) {
684*088332b5SXin Li if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */
685*088332b5SXin Li return &t->array[key - 1];
686*088332b5SXin Li else if (!limitequalsasize(t) && /* key still may be in the array part? */
687*088332b5SXin Li (l_castS2U(key) == t->alimit + 1 ||
688*088332b5SXin Li l_castS2U(key) - 1u < luaH_realasize(t))) {
689*088332b5SXin Li t->alimit = cast_uint(key); /* probably '#t' is here now */
690*088332b5SXin Li return &t->array[key - 1];
691*088332b5SXin Li }
692*088332b5SXin Li else {
693*088332b5SXin Li Node *n = hashint(t, key);
694*088332b5SXin Li for (;;) { /* check whether 'key' is somewhere in the chain */
695*088332b5SXin Li if (keyisinteger(n) && keyival(n) == key)
696*088332b5SXin Li return gval(n); /* that's it */
697*088332b5SXin Li else {
698*088332b5SXin Li int nx = gnext(n);
699*088332b5SXin Li if (nx == 0) break;
700*088332b5SXin Li n += nx;
701*088332b5SXin Li }
702*088332b5SXin Li }
703*088332b5SXin Li return &absentkey;
704*088332b5SXin Li }
705*088332b5SXin Li }
706*088332b5SXin Li
707*088332b5SXin Li
708*088332b5SXin Li /*
709*088332b5SXin Li ** search function for short strings
710*088332b5SXin Li */
luaH_getshortstr(Table * t,TString * key)711*088332b5SXin Li const TValue *luaH_getshortstr (Table *t, TString *key) {
712*088332b5SXin Li Node *n = hashstr(t, key);
713*088332b5SXin Li lua_assert(key->tt == LUA_VSHRSTR);
714*088332b5SXin Li for (;;) { /* check whether 'key' is somewhere in the chain */
715*088332b5SXin Li if (keyisshrstr(n) && eqshrstr(keystrval(n), key))
716*088332b5SXin Li return gval(n); /* that's it */
717*088332b5SXin Li else {
718*088332b5SXin Li int nx = gnext(n);
719*088332b5SXin Li if (nx == 0)
720*088332b5SXin Li return &absentkey; /* not found */
721*088332b5SXin Li n += nx;
722*088332b5SXin Li }
723*088332b5SXin Li }
724*088332b5SXin Li }
725*088332b5SXin Li
726*088332b5SXin Li
luaH_getstr(Table * t,TString * key)727*088332b5SXin Li const TValue *luaH_getstr (Table *t, TString *key) {
728*088332b5SXin Li if (key->tt == LUA_VSHRSTR)
729*088332b5SXin Li return luaH_getshortstr(t, key);
730*088332b5SXin Li else { /* for long strings, use generic case */
731*088332b5SXin Li TValue ko;
732*088332b5SXin Li setsvalue(cast(lua_State *, NULL), &ko, key);
733*088332b5SXin Li return getgeneric(t, &ko);
734*088332b5SXin Li }
735*088332b5SXin Li }
736*088332b5SXin Li
737*088332b5SXin Li
738*088332b5SXin Li /*
739*088332b5SXin Li ** main search function
740*088332b5SXin Li */
luaH_get(Table * t,const TValue * key)741*088332b5SXin Li const TValue *luaH_get (Table *t, const TValue *key) {
742*088332b5SXin Li switch (ttypetag(key)) {
743*088332b5SXin Li case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key));
744*088332b5SXin Li case LUA_VNUMINT: return luaH_getint(t, ivalue(key));
745*088332b5SXin Li case LUA_VNIL: return &absentkey;
746*088332b5SXin Li case LUA_VNUMFLT: {
747*088332b5SXin Li lua_Integer k;
748*088332b5SXin Li if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
749*088332b5SXin Li return luaH_getint(t, k); /* use specialized version */
750*088332b5SXin Li /* else... */
751*088332b5SXin Li } /* FALLTHROUGH */
752*088332b5SXin Li default:
753*088332b5SXin Li return getgeneric(t, key);
754*088332b5SXin Li }
755*088332b5SXin Li }
756*088332b5SXin Li
757*088332b5SXin Li
758*088332b5SXin Li /*
759*088332b5SXin Li ** beware: when using this function you probably need to check a GC
760*088332b5SXin Li ** barrier and invalidate the TM cache.
761*088332b5SXin Li */
luaH_set(lua_State * L,Table * t,const TValue * key)762*088332b5SXin Li TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
763*088332b5SXin Li const TValue *p = luaH_get(t, key);
764*088332b5SXin Li if (!isabstkey(p))
765*088332b5SXin Li return cast(TValue *, p);
766*088332b5SXin Li else return luaH_newkey(L, t, key);
767*088332b5SXin Li }
768*088332b5SXin Li
769*088332b5SXin Li
luaH_setint(lua_State * L,Table * t,lua_Integer key,TValue * value)770*088332b5SXin Li void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
771*088332b5SXin Li const TValue *p = luaH_getint(t, key);
772*088332b5SXin Li TValue *cell;
773*088332b5SXin Li if (!isabstkey(p))
774*088332b5SXin Li cell = cast(TValue *, p);
775*088332b5SXin Li else {
776*088332b5SXin Li TValue k;
777*088332b5SXin Li setivalue(&k, key);
778*088332b5SXin Li cell = luaH_newkey(L, t, &k);
779*088332b5SXin Li }
780*088332b5SXin Li setobj2t(L, cell, value);
781*088332b5SXin Li }
782*088332b5SXin Li
783*088332b5SXin Li
784*088332b5SXin Li /*
785*088332b5SXin Li ** Try to find a boundary in the hash part of table 't'. From the
786*088332b5SXin Li ** caller, we know that 'j' is zero or present and that 'j + 1' is
787*088332b5SXin Li ** present. We want to find a larger key that is absent from the
788*088332b5SXin Li ** table, so that we can do a binary search between the two keys to
789*088332b5SXin Li ** find a boundary. We keep doubling 'j' until we get an absent index.
790*088332b5SXin Li ** If the doubling would overflow, we try LUA_MAXINTEGER. If it is
791*088332b5SXin Li ** absent, we are ready for the binary search. ('j', being max integer,
792*088332b5SXin Li ** is larger or equal to 'i', but it cannot be equal because it is
793*088332b5SXin Li ** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a
794*088332b5SXin Li ** boundary. ('j + 1' cannot be a present integer key because it is
795*088332b5SXin Li ** not a valid integer in Lua.)
796*088332b5SXin Li */
hash_search(Table * t,lua_Unsigned j)797*088332b5SXin Li static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
798*088332b5SXin Li lua_Unsigned i;
799*088332b5SXin Li if (j == 0) j++; /* the caller ensures 'j + 1' is present */
800*088332b5SXin Li do {
801*088332b5SXin Li i = j; /* 'i' is a present index */
802*088332b5SXin Li if (j <= l_castS2U(LUA_MAXINTEGER) / 2)
803*088332b5SXin Li j *= 2;
804*088332b5SXin Li else {
805*088332b5SXin Li j = LUA_MAXINTEGER;
806*088332b5SXin Li if (isempty(luaH_getint(t, j))) /* t[j] not present? */
807*088332b5SXin Li break; /* 'j' now is an absent index */
808*088332b5SXin Li else /* weird case */
809*088332b5SXin Li return j; /* well, max integer is a boundary... */
810*088332b5SXin Li }
811*088332b5SXin Li } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */
812*088332b5SXin Li /* i < j && t[i] present && t[j] absent */
813*088332b5SXin Li while (j - i > 1u) { /* do a binary search between them */
814*088332b5SXin Li lua_Unsigned m = (i + j) / 2;
815*088332b5SXin Li if (isempty(luaH_getint(t, m))) j = m;
816*088332b5SXin Li else i = m;
817*088332b5SXin Li }
818*088332b5SXin Li return i;
819*088332b5SXin Li }
820*088332b5SXin Li
821*088332b5SXin Li
binsearch(const TValue * array,unsigned int i,unsigned int j)822*088332b5SXin Li static unsigned int binsearch (const TValue *array, unsigned int i,
823*088332b5SXin Li unsigned int j) {
824*088332b5SXin Li while (j - i > 1u) { /* binary search */
825*088332b5SXin Li unsigned int m = (i + j) / 2;
826*088332b5SXin Li if (isempty(&array[m - 1])) j = m;
827*088332b5SXin Li else i = m;
828*088332b5SXin Li }
829*088332b5SXin Li return i;
830*088332b5SXin Li }
831*088332b5SXin Li
832*088332b5SXin Li
833*088332b5SXin Li /*
834*088332b5SXin Li ** Try to find a boundary in table 't'. (A 'boundary' is an integer index
835*088332b5SXin Li ** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent
836*088332b5SXin Li ** and 'maxinteger' if t[maxinteger] is present.)
837*088332b5SXin Li ** (In the next explanation, we use Lua indices, that is, with base 1.
838*088332b5SXin Li ** The code itself uses base 0 when indexing the array part of the table.)
839*088332b5SXin Li ** The code starts with 'limit = t->alimit', a position in the array
840*088332b5SXin Li ** part that may be a boundary.
841*088332b5SXin Li **
842*088332b5SXin Li ** (1) If 't[limit]' is empty, there must be a boundary before it.
843*088332b5SXin Li ** As a common case (e.g., after 't[#t]=nil'), check whether 'limit-1'
844*088332b5SXin Li ** is present. If so, it is a boundary. Otherwise, do a binary search
845*088332b5SXin Li ** between 0 and limit to find a boundary. In both cases, try to
846*088332b5SXin Li ** use this boundary as the new 'alimit', as a hint for the next call.
847*088332b5SXin Li **
848*088332b5SXin Li ** (2) If 't[limit]' is not empty and the array has more elements
849*088332b5SXin Li ** after 'limit', try to find a boundary there. Again, try first
850*088332b5SXin Li ** the special case (which should be quite frequent) where 'limit+1'
851*088332b5SXin Li ** is empty, so that 'limit' is a boundary. Otherwise, check the
852*088332b5SXin Li ** last element of the array part. If it is empty, there must be a
853*088332b5SXin Li ** boundary between the old limit (present) and the last element
854*088332b5SXin Li ** (absent), which is found with a binary search. (This boundary always
855*088332b5SXin Li ** can be a new limit.)
856*088332b5SXin Li **
857*088332b5SXin Li ** (3) The last case is when there are no elements in the array part
858*088332b5SXin Li ** (limit == 0) or its last element (the new limit) is present.
859*088332b5SXin Li ** In this case, must check the hash part. If there is no hash part
860*088332b5SXin Li ** or 'limit+1' is absent, 'limit' is a boundary. Otherwise, call
861*088332b5SXin Li ** 'hash_search' to find a boundary in the hash part of the table.
862*088332b5SXin Li ** (In those cases, the boundary is not inside the array part, and
863*088332b5SXin Li ** therefore cannot be used as a new limit.)
864*088332b5SXin Li */
luaH_getn(Table * t)865*088332b5SXin Li lua_Unsigned luaH_getn (Table *t) {
866*088332b5SXin Li unsigned int limit = t->alimit;
867*088332b5SXin Li if (limit > 0 && isempty(&t->array[limit - 1])) { /* (1)? */
868*088332b5SXin Li /* there must be a boundary before 'limit' */
869*088332b5SXin Li if (limit >= 2 && !isempty(&t->array[limit - 2])) {
870*088332b5SXin Li /* 'limit - 1' is a boundary; can it be a new limit? */
871*088332b5SXin Li if (ispow2realasize(t) && !ispow2(limit - 1)) {
872*088332b5SXin Li t->alimit = limit - 1;
873*088332b5SXin Li setnorealasize(t); /* now 'alimit' is not the real size */
874*088332b5SXin Li }
875*088332b5SXin Li return limit - 1;
876*088332b5SXin Li }
877*088332b5SXin Li else { /* must search for a boundary in [0, limit] */
878*088332b5SXin Li unsigned int boundary = binsearch(t->array, 0, limit);
879*088332b5SXin Li /* can this boundary represent the real size of the array? */
880*088332b5SXin Li if (ispow2realasize(t) && boundary > luaH_realasize(t) / 2) {
881*088332b5SXin Li t->alimit = boundary; /* use it as the new limit */
882*088332b5SXin Li setnorealasize(t);
883*088332b5SXin Li }
884*088332b5SXin Li return boundary;
885*088332b5SXin Li }
886*088332b5SXin Li }
887*088332b5SXin Li /* 'limit' is zero or present in table */
888*088332b5SXin Li if (!limitequalsasize(t)) { /* (2)? */
889*088332b5SXin Li /* 'limit' > 0 and array has more elements after 'limit' */
890*088332b5SXin Li if (isempty(&t->array[limit])) /* 'limit + 1' is empty? */
891*088332b5SXin Li return limit; /* this is the boundary */
892*088332b5SXin Li /* else, try last element in the array */
893*088332b5SXin Li limit = luaH_realasize(t);
894*088332b5SXin Li if (isempty(&t->array[limit - 1])) { /* empty? */
895*088332b5SXin Li /* there must be a boundary in the array after old limit,
896*088332b5SXin Li and it must be a valid new limit */
897*088332b5SXin Li unsigned int boundary = binsearch(t->array, t->alimit, limit);
898*088332b5SXin Li t->alimit = boundary;
899*088332b5SXin Li return boundary;
900*088332b5SXin Li }
901*088332b5SXin Li /* else, new limit is present in the table; check the hash part */
902*088332b5SXin Li }
903*088332b5SXin Li /* (3) 'limit' is the last element and either is zero or present in table */
904*088332b5SXin Li lua_assert(limit == luaH_realasize(t) &&
905*088332b5SXin Li (limit == 0 || !isempty(&t->array[limit - 1])));
906*088332b5SXin Li if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1))))
907*088332b5SXin Li return limit; /* 'limit + 1' is absent */
908*088332b5SXin Li else /* 'limit + 1' is also present */
909*088332b5SXin Li return hash_search(t, limit);
910*088332b5SXin Li }
911*088332b5SXin Li
912*088332b5SXin Li
913*088332b5SXin Li
914*088332b5SXin Li #if defined(LUA_DEBUG)
915*088332b5SXin Li
916*088332b5SXin Li /* export these functions for the test library */
917*088332b5SXin Li
luaH_mainposition(const Table * t,const TValue * key)918*088332b5SXin Li Node *luaH_mainposition (const Table *t, const TValue *key) {
919*088332b5SXin Li return mainpositionTV(t, key);
920*088332b5SXin Li }
921*088332b5SXin Li
luaH_isdummy(const Table * t)922*088332b5SXin Li int luaH_isdummy (const Table *t) { return isdummy(t); }
923*088332b5SXin Li
924*088332b5SXin Li #endif
925