LCOV - code coverage report
Current view: top level - src - ltable.c Coverage Total Hit
Test: Lua 5.2.4 Lines: 93.2 % 279 260
Test Date: 2024-04-28 10:23:12
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $
       3              : ** Lua tables (hash)
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : 
       8              : /*
       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.
      19              : */
      20              : 
      21              : #include <string.h>
      22              : 
      23              : #define ltable_c
      24              : #define LUA_CORE
      25              : 
      26              : #include "lua.h"
      27              : 
      28              : #include "ldebug.h"
      29              : #include "ldo.h"
      30              : #include "lgc.h"
      31              : #include "lmem.h"
      32              : #include "lobject.h"
      33              : #include "lstate.h"
      34              : #include "lstring.h"
      35              : #include "ltable.h"
      36              : #include "lvm.h"
      37              : 
      38              : 
      39              : /*
      40              : ** max size of array part is 2^MAXBITS
      41              : */
      42              : #if LUAI_BITSINT >= 32
      43              : #define MAXBITS         30
      44              : #else
      45              : #define MAXBITS         (LUAI_BITSINT-2)
      46              : #endif
      47              : 
      48              : #define MAXASIZE        (1 << MAXBITS)
      49              : 
      50              : 
      51              : #define hashpow2(t,n)           (gnode(t, lmod((n), sizenode(t))))
      52              : 
      53              : #define hashstr(t,str)          hashpow2(t, (str)->tsv.hash)
      54              : #define hashboolean(t,p)        hashpow2(t, p)
      55              : 
      56              : 
      57              : /*
      58              : ** for some types, it is better to avoid modulus by power of 2, as
      59              : ** they tend to have many 2 factors.
      60              : */
      61              : #define hashmod(t,n)    (gnode(t, ((n) % ((sizenode(t)-1)|1))))
      62              : 
      63              : 
      64              : #define hashpointer(t,p)        hashmod(t, IntPoint(p))
      65              : 
      66              : 
      67              : #define dummynode               (&dummynode_)
      68              : 
      69              : #define isdummy(n)              ((n) == dummynode)
      70              : 
      71              : static const Node dummynode_ = {
      72              :   {NILCONSTANT},  /* value */
      73              :   {{NILCONSTANT, NULL}}  /* key */
      74              : };
      75              : 
      76              : 
      77              : /*
      78              : ** hash for lua_Numbers
      79              : */
      80        53555 : static Node *hashnum (const Table *t, lua_Number n) {
      81              :   int i;
      82        53555 :   luai_hashnum(i, n);
      83        53555 :   if (i < 0) {
      84          760 :     if (cast(unsigned int, i) == 0u - i)  /* use unsigned to avoid overflows */
      85            0 :       i = 0;  /* handle INT_MIN */
      86          760 :     i = -i;  /* must be a positive value */
      87              :   }
      88        53555 :   return hashmod(t, i);
      89              : }
      90              : 
      91              : 
      92              : 
      93              : /*
      94              : ** returns the `main' position of an element in a table (that is, the index
      95              : ** of its hash value)
      96              : */
      97       180280 : static Node *mainposition (const Table *t, const TValue *key) {
      98       180280 :   switch (ttype(key)) {
      99        26710 :     case LUA_TNUMBER:
     100        26710 :       return hashnum(t, nvalue(key));
     101         1345 :     case LUA_TLNGSTR: {
     102         1345 :       TString *s = rawtsvalue(key);
     103         1345 :       if (s->tsv.extra == 0) {  /* no hash? */
     104          310 :         s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash);
     105          310 :         s->tsv.extra = 1;  /* now it has its hash */
     106              :       }
     107         1345 :       return hashstr(t, rawtsvalue(key));
     108              :     }
     109       151069 :     case LUA_TSHRSTR:
     110       151069 :       return hashstr(t, rawtsvalue(key));
     111          726 :     case LUA_TBOOLEAN:
     112          726 :       return hashboolean(t, bvalue(key));
     113            0 :     case LUA_TLIGHTUSERDATA:
     114            0 :       return hashpointer(t, pvalue(key));
     115            5 :     case LUA_TLCF:
     116            5 :       return hashpointer(t, fvalue(key));
     117          425 :     default:
     118          425 :       return hashpointer(t, gcvalue(key));
     119              :   }
     120              : }
     121              : 
     122              : 
     123              : /*
     124              : ** returns the index for `key' if `key' is an appropriate key to live in
     125              : ** the array part of the table, -1 otherwise.
     126              : */
     127        93215 : static int arrayindex (const TValue *key) {
     128        93215 :   if (ttisnumber(key)) {
     129        24982 :     lua_Number n = nvalue(key);
     130              :     int k;
     131        24982 :     lua_number2int(k, n);
     132        24982 :     if (luai_numeq(cast_num(k), n))
     133        24830 :       return k;
     134              :   }
     135        68385 :   return -1;  /* `key' did not match some condition */
     136              : }
     137              : 
     138              : 
     139              : /*
     140              : ** returns the index of a `key' for table traversals. First goes all
     141              : ** elements in the array part, then elements in the hash part. The
     142              : ** beginning of a traversal is signaled by -1.
     143              : */
     144         1112 : static int findindex (lua_State *L, Table *t, StkId key) {
     145              :   int i;
     146         1112 :   if (ttisnil(key)) return -1;  /* first iteration */
     147         1047 :   i = arrayindex(key);
     148         1047 :   if (0 < i && i <= t->sizearray)  /* is `key' inside array part? */
     149           22 :     return i-1;  /* yes; that's the index (corrected to C) */
     150              :   else {
     151         1025 :     Node *n = mainposition(t, key);
     152              :     for (;;) {  /* check whether `key' is somewhere in the chain */
     153              :       /* key may be dead already, but it is ok to use it in `next' */
     154         1348 :       if (luaV_rawequalobj(gkey(n), key) ||
     155          324 :             (ttisdeadkey(gkey(n)) && iscollectable(key) &&
     156            0 :              deadvalue(gkey(n)) == gcvalue(key))) {
     157         1024 :         i = cast_int(n - gnode(t, 0));  /* key index in hash table */
     158              :         /* hash elements are numbered after array ones */
     159         1024 :         return i + t->sizearray;
     160              :       }
     161          324 :       else n = gnext(n);
     162          324 :       if (n == NULL)
     163            1 :         luaG_runerror(L, "invalid key to " LUA_QL("next"));  /* key not found */
     164              :     }
     165              :   }
     166              : }
     167              : 
     168              : 
     169         1112 : int luaH_next (lua_State *L, Table *t, StkId key) {
     170         1112 :   int i = findindex(L, t, key);  /* find original element */
     171         1111 :   for (i++; i < t->sizearray; i++) {  /* try first array part */
     172           21 :     if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
     173           21 :       setnvalue(key, cast_num(i+1));
     174           21 :       setobj2s(L, key+1, &t->array[i]);
     175           21 :       return 1;
     176              :     }
     177              :   }
     178         1585 :   for (i -= t->sizearray; i < sizenode(t); i++) {  /* then hash part */
     179         1519 :     if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
     180         1024 :       setobj2s(L, key, gkey(gnode(t, i)));
     181         1024 :       setobj2s(L, key+1, gval(gnode(t, i)));
     182         1024 :       return 1;
     183              :     }
     184              :   }
     185           66 :   return 0;  /* no more elements */
     186              : }
     187              : 
     188              : 
     189              : /*
     190              : ** {=============================================================
     191              : ** Rehash
     192              : ** ==============================================================
     193              : */
     194              : 
     195              : 
     196        35953 : static int computesizes (int nums[], int *narray) {
     197              :   int i;
     198              :   int twotoi;  /* 2^i */
     199        35953 :   int a = 0;  /* number of elements smaller than 2^i */
     200        35953 :   int na = 0;  /* number of elements to go to array part */
     201        35953 :   int n = 0;  /* optimal size for array part */
     202        72461 :   for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
     203        61477 :     if (nums[i] > 0) {
     204        61184 :       a += nums[i];
     205        61184 :       if (a > twotoi/2) {  /* more than half elements present? */
     206        61139 :         n = twotoi;  /* optimal size (till now) */
     207        61139 :         na = a;  /* all elements smaller than n will go to array part */
     208              :       }
     209              :     }
     210        61477 :     if (a == *narray) break;  /* all elements already counted */
     211              :   }
     212        35953 :   *narray = n;
     213              :   lua_assert(*narray/2 <= na && na <= *narray);
     214        35953 :   return na;
     215              : }
     216              : 
     217              : 
     218        92168 : static int countint (const TValue *key, int *nums) {
     219        92168 :   int k = arrayindex(key);
     220        92168 :   if (0 < k && k <= MAXASIZE) {  /* is `key' an appropriate array index? */
     221        24714 :     nums[luaO_ceillog2(k)]++;  /* count as such */
     222        24714 :     return 1;
     223              :   }
     224              :   else
     225        67454 :     return 0;
     226              : }
     227              : 
     228              : 
     229        35953 : static int numusearray (const Table *t, int *nums) {
     230              :   int lg;
     231              :   int ttlg;  /* 2^lg */
     232        35953 :   int ause = 0;  /* summation of `nums' */
     233        35953 :   int i = 1;  /* count to traverse all array keys */
     234        72931 :   for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) {  /* for each slice */
     235        72931 :     int lc = 0;  /* counter */
     236        72931 :     int lim = ttlg;
     237        72931 :     if (lim > t->sizearray) {
     238        35956 :       lim = t->sizearray;  /* adjust upper limit */
     239        35956 :       if (i > lim)
     240        35953 :         break;  /* no more elements to count */
     241              :     }
     242              :     /* count elements in range (2^(lg-1), 2^lg] */
     243        81930 :     for (; i <= lim; i++) {
     244        44952 :       if (!ttisnil(&t->array[i-1]))
     245        44883 :         lc++;
     246              :     }
     247        36978 :     nums[lg] += lc;
     248        36978 :     ause += lc;
     249              :   }
     250        35953 :   return ause;
     251              : }
     252              : 
     253              : 
     254        35953 : static int numusehash (const Table *t, int *nums, int *pnasize) {
     255        35953 :   int totaluse = 0;  /* total number of elements */
     256        35953 :   int ause = 0;  /* summation of `nums' */
     257        35953 :   int i = sizenode(t);
     258       118453 :   while (i--) {
     259        82500 :     Node *n = &t->node[i];
     260        82500 :     if (!ttisnil(gval(n))) {
     261        56215 :       ause += countint(gkey(n), nums);
     262        56215 :       totaluse++;
     263              :     }
     264              :   }
     265        35953 :   *pnasize += ause;
     266        35953 :   return totaluse;
     267              : }
     268              : 
     269              : 
     270        24671 : static void setarrayvector (lua_State *L, Table *t, int size) {
     271              :   int i;
     272        24671 :   luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
     273        75165 :   for (i=t->sizearray; i<size; i++)
     274        50494 :      setnilvalue(&t->array[i]);
     275        24671 :   t->sizearray = size;
     276        24671 : }
     277              : 
     278              : 
     279        48073 : static void setnodevector (lua_State *L, Table *t, int size) {
     280              :   int lsize;
     281        48073 :   if (size == 0) {  /* no elements to hash part? */
     282        34734 :     t->node = cast(Node *, dummynode);  /* use common `dummynode' */
     283        34734 :     lsize = 0;
     284              :   }
     285              :   else {
     286              :     int i;
     287        13339 :     lsize = luaO_ceillog2(size);
     288        13339 :     if (lsize > MAXBITS)
     289            0 :       luaG_runerror(L, "table overflow");
     290        13339 :     size = twoto(lsize);
     291        13339 :     t->node = luaM_newvector(L, size, Node);
     292       136281 :     for (i=0; i<size; i++) {
     293       122942 :       Node *n = gnode(t, i);
     294       122942 :       gnext(n) = NULL;
     295       122942 :       setnilvalue(gkey(n));
     296       122942 :       setnilvalue(gval(n));
     297              :     }
     298              :   }
     299        48073 :   t->lsizenode = cast_byte(lsize);
     300        48073 :   t->lastfree = gnode(t, size);  /* all positions are free */
     301        48073 : }
     302              : 
     303              : 
     304        37628 : void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
     305              :   int i;
     306        37628 :   int oldasize = t->sizearray;
     307        37628 :   int oldhsize = t->lsizenode;
     308        37628 :   Node *nold = t->node;  /* save old hash ... */
     309        37628 :   if (nasize > oldasize)  /* array part must grow? */
     310        24671 :     setarrayvector(L, t, nasize);
     311              :   /* create new hash part with appropriate size */
     312        37628 :   setnodevector(L, t, nhsize);
     313        37628 :   if (nasize < oldasize) {  /* array part must shrink? */
     314            0 :     t->sizearray = nasize;
     315              :     /* re-insert elements from vanishing slice */
     316            0 :     for (i=nasize; i<oldasize; i++) {
     317            0 :       if (!ttisnil(&t->array[i]))
     318            0 :         luaH_setint(L, t, i + 1, &t->array[i]);
     319              :     }
     320              :     /* shrink array */
     321            0 :     luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
     322              :   }
     323              :   /* re-insert elements from hash part */
     324       121803 :   for (i = twoto(oldhsize) - 1; i >= 0; i--) {
     325        84175 :     Node *old = nold+i;
     326        84175 :     if (!ttisnil(gval(old))) {
     327              :       /* doesn't need barrier/invalidate cache, as entry was
     328              :          already present in the table */
     329        56215 :       setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
     330              :     }
     331              :   }
     332        37628 :   if (!isdummy(nold))
     333         9668 :     luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
     334        37628 : }
     335              : 
     336              : 
     337          219 : void luaH_resizearray (lua_State *L, Table *t, int nasize) {
     338          219 :   int nsize = isdummy(t->node) ? 0 : sizenode(t);
     339          219 :   luaH_resize(L, t, nasize, nsize);
     340          219 : }
     341              : 
     342              : 
     343        35953 : static void rehash (lua_State *L, Table *t, const TValue *ek) {
     344              :   int nasize, na;
     345              :   int nums[MAXBITS+1];  /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
     346              :   int i;
     347              :   int totaluse;
     348      1150496 :   for (i=0; i<=MAXBITS; i++) nums[i] = 0;  /* reset counts */
     349        35953 :   nasize = numusearray(t, nums);  /* count keys in array part */
     350        35953 :   totaluse = nasize;  /* all those keys are integer keys */
     351        35953 :   totaluse += numusehash(t, nums, &nasize);  /* count keys in hash part */
     352              :   /* count extra key */
     353        35953 :   nasize += countint(ek, nums);
     354        35953 :   totaluse++;
     355              :   /* compute new size for array part */
     356        35953 :   na = computesizes(nums, &nasize);
     357              :   /* resize the table to new computed sizes */
     358        35953 :   luaH_resize(L, t, nasize, totaluse - na);
     359        35953 : }
     360              : 
     361              : 
     362              : 
     363              : /*
     364              : ** }=============================================================
     365              : */
     366              : 
     367              : 
     368        10445 : Table *luaH_new (lua_State *L) {
     369        10445 :   Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
     370        10445 :   t->metatable = NULL;
     371        10445 :   t->flags = cast_byte(~0);
     372        10445 :   t->array = NULL;
     373        10445 :   t->sizearray = 0;
     374        10445 :   setnodevector(L, t, 0);
     375        10445 :   return t;
     376              : }
     377              : 
     378              : 
     379        10150 : void luaH_free (lua_State *L, Table *t) {
     380        10150 :   if (!isdummy(t->node))
     381         3421 :     luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
     382        10150 :   luaM_freearray(L, t->array, t->sizearray);
     383        10150 :   luaM_free(L, t);
     384        10150 : }
     385              : 
     386              : 
     387        73943 : static Node *getfreepos (Table *t) {
     388       119084 :   while (t->lastfree > t->node) {
     389        83131 :     t->lastfree--;
     390        83131 :     if (ttisnil(gkey(t->lastfree)))
     391        37990 :       return t->lastfree;
     392              :   }
     393        35953 :   return NULL;  /* could not find a free place */
     394              : }
     395              : 
     396              : 
     397              : 
     398              : /*
     399              : ** inserts a new key into a hash table; first, check whether key's main
     400              : ** position is free. If not, check whether colliding node is in its main
     401              : ** position or not: if it is not, move colliding node to an empty place and
     402              : ** put new key in its main position; otherwise (colliding node is in its main
     403              : ** position), new key goes to an empty position.
     404              : */
     405       139471 : TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
     406              :   Node *mp;
     407       139471 :   if (ttisnil(key)) luaG_runerror(L, "table index is nil");
     408       139469 :   else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
     409            1 :     luaG_runerror(L, "table index is NaN");
     410       139468 :   mp = mainposition(t, key);
     411       139468 :   if (!ttisnil(gval(mp)) || isdummy(mp)) {  /* main position is taken? */
     412              :     Node *othern;
     413        73943 :     Node *n = getfreepos(t);  /* get a free place */
     414        73943 :     if (n == NULL) {  /* cannot find a free place? */
     415        35953 :       rehash(L, t, key);  /* grow table */
     416              :       /* whatever called 'newkey' take care of TM cache and GC barrier */
     417        35953 :       return luaH_set(L, t, key);  /* insert key into grown table */
     418              :     }
     419              :     lua_assert(!isdummy(n));
     420        37990 :     othern = mainposition(t, gkey(mp));
     421        37990 :     if (othern != mp) {  /* is colliding node out of its main position? */
     422              :       /* yes; move colliding node into free position */
     423         8375 :       while (gnext(othern) != mp) othern = gnext(othern);  /* find previous */
     424         7021 :       gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */
     425         7021 :       *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
     426         7021 :       gnext(mp) = NULL;  /* now `mp' is free */
     427         7021 :       setnilvalue(gval(mp));
     428              :     }
     429              :     else {  /* colliding node is in its own main position */
     430              :       /* new node will go into free position */
     431        30969 :       gnext(n) = gnext(mp);  /* chain new position */
     432        30969 :       gnext(mp) = n;
     433        30969 :       mp = n;
     434              :     }
     435              :   }
     436       103515 :   setobj2t(L, gkey(mp), key);
     437       103515 :   luaC_barrierback(L, obj2gco(t), key);
     438              :   lua_assert(ttisnil(gval(mp)));
     439       103515 :   return gval(mp);
     440              : }
     441              : 
     442              : 
     443              : /*
     444              : ** search function for integers
     445              : */
     446       536472 : const TValue *luaH_getint (Table *t, int key) {
     447              :   /* (1 <= key && key <= t->sizearray) */
     448       536472 :   if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
     449       509627 :     return &t->array[key-1];
     450              :   else {
     451        26845 :     lua_Number nk = cast_num(key);
     452        26845 :     Node *n = hashnum(t, nk);
     453              :     do {  /* check whether `key' is somewhere in the chain */
     454        27714 :       if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
     455          920 :         return gval(n);  /* that's it */
     456        26794 :       else n = gnext(n);
     457        26794 :     } while (n);
     458        25925 :     return luaO_nilobject;
     459              :   }
     460              : }
     461              : 
     462              : 
     463              : /*
     464              : ** search function for short strings
     465              : */
     466       263529 : const TValue *luaH_getstr (Table *t, TString *key) {
     467       263529 :   Node *n = hashstr(t, key);
     468              :   lua_assert(key->tsv.tt == LUA_TSHRSTR);
     469              :   do {  /* check whether `key' is somewhere in the chain */
     470       303072 :     if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
     471       146913 :       return gval(n);  /* that's it */
     472       156159 :     else n = gnext(n);
     473       156159 :   } while (n);
     474       116616 :   return luaO_nilobject;
     475              : }
     476              : 
     477              : 
     478              : /*
     479              : ** main search function
     480              : */
     481       408250 : const TValue *luaH_get (Table *t, const TValue *key) {
     482       408250 :   switch (ttype(key)) {
     483       255088 :     case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
     484            4 :     case LUA_TNIL: return luaO_nilobject;
     485       151670 :     case LUA_TNUMBER: {
     486              :       int k;
     487       151670 :       lua_Number n = nvalue(key);
     488       151670 :       lua_number2int(k, n);
     489       151670 :       if (luai_numeq(cast_num(k), n)) /* index is int? */
     490       151361 :         return luaH_getint(t, k);  /* use specialized version */
     491              :       /* else go through */
     492              :     }
     493              :     default: {
     494         1797 :       Node *n = mainposition(t, key);
     495              :       do {  /* check whether `key' is somewhere in the chain */
     496         2188 :         if (luaV_rawequalobj(gkey(n), key))
     497          745 :           return gval(n);  /* that's it */
     498         1443 :         else n = gnext(n);
     499         1443 :       } while (n);
     500         1052 :       return luaO_nilobject;
     501              :     }
     502              :   }
     503              : }
     504              : 
     505              : 
     506              : /*
     507              : ** beware: when using this function you probably need to check a GC
     508              : ** barrier and invalidate the TM cache.
     509              : */
     510       169808 : TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
     511       169808 :   const TValue *p = luaH_get(t, key);
     512       169808 :   if (p != luaO_nilobject)
     513        72414 :     return cast(TValue *, p);
     514        97394 :   else return luaH_newkey(L, t, key);
     515              : }
     516              : 
     517              : 
     518        87937 : void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
     519        87937 :   const TValue *p = luaH_getint(t, key);
     520              :   TValue *cell;
     521        87937 :   if (p != luaO_nilobject)
     522        87670 :     cell = cast(TValue *, p);
     523              :   else {
     524              :     TValue k;
     525          267 :     setnvalue(&k, cast_num(key));
     526          267 :     cell = luaH_newkey(L, t, &k);
     527              :   }
     528        87937 :   setobj2t(L, cell, value);
     529        87937 : }
     530              : 
     531              : 
     532            2 : static int unbound_search (Table *t, unsigned int j) {
     533            2 :   unsigned int i = j;  /* i is zero or a present index */
     534            2 :   j++;
     535              :   /* find `i' and `j' such that i is present and j is not */
     536            2 :   while (!ttisnil(luaH_getint(t, j))) {
     537            0 :     i = j;
     538            0 :     j *= 2;
     539            0 :     if (j > cast(unsigned int, MAX_INT)) {  /* overflow? */
     540              :       /* table was built with bad purposes: resort to linear search */
     541            0 :       i = 1;
     542            0 :       while (!ttisnil(luaH_getint(t, i))) i++;
     543            0 :       return i - 1;
     544              :     }
     545              :   }
     546              :   /* now do a binary search between them */
     547            2 :   while (j - i > 1) {
     548            0 :     unsigned int m = (i+j)/2;
     549            0 :     if (ttisnil(luaH_getint(t, m))) j = m;
     550            0 :     else i = m;
     551              :   }
     552            2 :   return i;
     553              : }
     554              : 
     555              : 
     556              : /*
     557              : ** Try to find a boundary in table `t'. A `boundary' is an integer index
     558              : ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
     559              : */
     560        18668 : int luaH_getn (Table *t) {
     561        18668 :   unsigned int j = t->sizearray;
     562        18668 :   if (j > 0 && ttisnil(&t->array[j - 1])) {
     563              :     /* there is a boundary in the array part: (binary) search for it */
     564        17797 :     unsigned int i = 0;
     565        70992 :     while (j - i > 1) {
     566        53195 :       unsigned int m = (i+j)/2;
     567        53195 :       if (ttisnil(&t->array[m - 1])) j = m;
     568        50621 :       else i = m;
     569              :     }
     570        17797 :     return i;
     571              :   }
     572              :   /* else must find a boundary in hash part */
     573          871 :   else if (isdummy(t->node))  /* hash part is empty? */
     574          869 :     return j;  /* that is easy... */
     575            2 :   else return unbound_search(t, j);
     576              : }
     577              : 
     578              : 
     579              : 
     580              : #if defined(LUA_DEBUG)
     581              : 
     582              : Node *luaH_mainposition (const Table *t, const TValue *key) {
     583              :   return mainposition(t, key);
     584              : }
     585              : 
     586              : int luaH_isdummy (Node *n) { return isdummy(n); }
     587              : 
     588              : #endif
        

Generated by: LCOV version 2.0-1