LCOV - code coverage report
Current view: top level - src - ltable.c Coverage Total Hit
Test: Lua 5.1.5 Lines: 93.9 % 279 262
Test Date: 2024-04-28 10:23:09
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 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 <math.h>
      22              : #include <string.h>
      23              : 
      24              : #define ltable_c
      25              : #define LUA_CORE
      26              : 
      27              : #include "lua.h"
      28              : 
      29              : #include "ldebug.h"
      30              : #include "ldo.h"
      31              : #include "lgc.h"
      32              : #include "lmem.h"
      33              : #include "lobject.h"
      34              : #include "lstate.h"
      35              : #include "ltable.h"
      36              : 
      37              : 
      38              : /*
      39              : ** max size of array part is 2^MAXBITS
      40              : */
      41              : #if LUAI_BITSINT > 26
      42              : #define MAXBITS         26
      43              : #else
      44              : #define MAXBITS         (LUAI_BITSINT-2)
      45              : #endif
      46              : 
      47              : #define MAXASIZE        (1 << MAXBITS)
      48              : 
      49              : 
      50              : #define hashpow2(t,n)      (gnode(t, lmod((n), sizenode(t))))
      51              :   
      52              : #define hashstr(t,str)  hashpow2(t, (str)->tsv.hash)
      53              : #define hashboolean(t,p)        hashpow2(t, p)
      54              : 
      55              : 
      56              : /*
      57              : ** for some types, it is better to avoid modulus by power of 2, as
      58              : ** they tend to have many 2 factors.
      59              : */
      60              : #define hashmod(t,n)    (gnode(t, ((n) % ((sizenode(t)-1)|1))))
      61              : 
      62              : 
      63              : #define hashpointer(t,p)        hashmod(t, IntPoint(p))
      64              : 
      65              : 
      66              : /*
      67              : ** number of ints inside a lua_Number
      68              : */
      69              : #define numints         cast_int(sizeof(lua_Number)/sizeof(int))
      70              : 
      71              : 
      72              : 
      73              : #define dummynode               (&dummynode_)
      74              : 
      75              : static const Node dummynode_ = {
      76              :   {{NULL}, LUA_TNIL},  /* value */
      77              :   {{{NULL}, LUA_TNIL, NULL}}  /* key */
      78              : };
      79              : 
      80              : 
      81              : /*
      82              : ** hash for lua_Numbers
      83              : */
      84        56796 : static Node *hashnum (const Table *t, lua_Number n) {
      85              :   unsigned int a[numints];
      86              :   int i;
      87        56796 :   if (luai_numeq(n, 0))  /* avoid problems with -0 */
      88         3031 :     return gnode(t, 0);
      89        53765 :   memcpy(a, &n, sizeof(a));
      90       107530 :   for (i = 1; i < numints; i++) a[0] += a[i];
      91        53765 :   return hashmod(t, a[0]);
      92              : }
      93              : 
      94              : 
      95              : 
      96              : /*
      97              : ** returns the `main' position of an element in a table (that is, the index
      98              : ** of its hash value)
      99              : */
     100       174954 : static Node *mainposition (const Table *t, const TValue *key) {
     101       174954 :   switch (ttype(key)) {
     102        28329 :     case LUA_TNUMBER:
     103        28329 :       return hashnum(t, nvalue(key));
     104       145130 :     case LUA_TSTRING:
     105       145130 :       return hashstr(t, rawtsvalue(key));
     106          819 :     case LUA_TBOOLEAN:
     107          819 :       return hashboolean(t, bvalue(key));
     108          499 :     case LUA_TLIGHTUSERDATA:
     109          499 :       return hashpointer(t, pvalue(key));
     110          177 :     default:
     111          177 :       return hashpointer(t, gcvalue(key));
     112              :   }
     113              : }
     114              : 
     115              : 
     116              : /*
     117              : ** returns the index for `key' if `key' is an appropriate key to live in
     118              : ** the array part of the table, -1 otherwise.
     119              : */
     120        90635 : static int arrayindex (const TValue *key) {
     121        90635 :   if (ttisnumber(key)) {
     122        25828 :     lua_Number n = nvalue(key);
     123              :     int k;
     124        25828 :     lua_number2int(k, n);
     125        25828 :     if (luai_numeq(cast_num(k), n))
     126        25676 :       return k;
     127              :   }
     128        64959 :   return -1;  /* `key' did not match some condition */
     129              : }
     130              : 
     131              : 
     132              : /*
     133              : ** returns the index of a `key' for table traversals. First goes all
     134              : ** elements in the array part, then elements in the hash part. The
     135              : ** beginning of a traversal is signalled by -1.
     136              : */
     137           57 : static int findindex (lua_State *L, Table *t, StkId key) {
     138              :   int i;
     139           57 :   if (ttisnil(key)) return -1;  /* first iteration */
     140           41 :   i = arrayindex(key);
     141           41 :   if (0 < i && i <= t->sizearray)  /* is `key' inside array part? */
     142           25 :     return i-1;  /* yes; that's the index (corrected to C) */
     143              :   else {
     144           16 :     Node *n = mainposition(t, key);
     145              :     do {  /* check whether `key' is somewhere in the chain */
     146              :       /* key may be dead already, but it is ok to use it in `next' */
     147           19 :       if (luaO_rawequalObj(key2tval(n), key) ||
     148            4 :             (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
     149            0 :              gcvalue(gkey(n)) == gcvalue(key))) {
     150           15 :         i = cast_int(n - gnode(t, 0));  /* key index in hash table */
     151              :         /* hash elements are numbered after array ones */
     152           15 :         return i + t->sizearray;
     153              :       }
     154            4 :       else n = gnext(n);
     155            4 :     } while (n);
     156            1 :     luaG_runerror(L, "invalid key to " LUA_QL("next"));  /* key not found */
     157            0 :     return 0;  /* to avoid warnings */
     158              :   }
     159              : }
     160              : 
     161              : 
     162           57 : int luaH_next (lua_State *L, Table *t, StkId key) {
     163           57 :   int i = findindex(L, t, key);  /* find original element */
     164           56 :   for (i++; i < t->sizearray; i++) {  /* try first array part */
     165           24 :     if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
     166           24 :       setnvalue(key, cast_num(i+1));
     167           24 :       setobj2s(L, key+1, &t->array[i]);
     168           24 :       return 1;
     169              :     }
     170              :   }
     171           45 :   for (i -= t->sizearray; i < sizenode(t); i++) {  /* then hash part */
     172           28 :     if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
     173           15 :       setobj2s(L, key, key2tval(gnode(t, i)));
     174           15 :       setobj2s(L, key+1, gval(gnode(t, i)));
     175           15 :       return 1;
     176              :     }
     177              :   }
     178           17 :   return 0;  /* no more elements */
     179              : }
     180              : 
     181              : 
     182              : /*
     183              : ** {=============================================================
     184              : ** Rehash
     185              : ** ==============================================================
     186              : */
     187              : 
     188              : 
     189        35600 : static int computesizes (int nums[], int *narray) {
     190              :   int i;
     191              :   int twotoi;  /* 2^i */
     192        35600 :   int a = 0;  /* number of elements smaller than 2^i */
     193        35600 :   int na = 0;  /* number of elements to go to array part */
     194        35600 :   int n = 0;  /* optimal size for array part */
     195        71862 :   for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
     196        61056 :     if (nums[i] > 0) {
     197        60757 :       a += nums[i];
     198        60757 :       if (a > twotoi/2) {  /* more than half elements present? */
     199        60711 :         n = twotoi;  /* optimal size (till now) */
     200        60711 :         na = a;  /* all elements smaller than n will go to array part */
     201              :       }
     202              :     }
     203        61056 :     if (a == *narray) break;  /* all elements already counted */
     204              :   }
     205        35600 :   *narray = n;
     206              :   lua_assert(*narray/2 <= na && na <= *narray);
     207        35600 :   return na;
     208              : }
     209              : 
     210              : 
     211        90594 : static int countint (const TValue *key, int *nums) {
     212        90594 :   int k = arrayindex(key);
     213        90594 :   if (0 < k && k <= MAXASIZE) {  /* is `key' an appropriate array index? */
     214        24882 :     nums[ceillog2(k)]++;  /* count as such */
     215        24882 :     return 1;
     216              :   }
     217              :   else
     218        65712 :     return 0;
     219              : }
     220              : 
     221              : 
     222        35600 : static int numusearray (const Table *t, int *nums) {
     223              :   int lg;
     224              :   int ttlg;  /* 2^lg */
     225        35600 :   int ause = 0;  /* summation of `nums' */
     226        35600 :   int i = 1;  /* count to traverse all array keys */
     227        71984 :   for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) {  /* for each slice */
     228        71984 :     int lc = 0;  /* counter */
     229        71984 :     int lim = ttlg;
     230        71984 :     if (lim > t->sizearray) {
     231        35603 :       lim = t->sizearray;  /* adjust upper limit */
     232        35603 :       if (i > lim)
     233        35600 :         break;  /* no more elements to count */
     234              :     }
     235              :     /* count elements in range (2^(lg-1), 2^lg] */
     236        80748 :     for (; i <= lim; i++) {
     237        44364 :       if (!ttisnil(&t->array[i-1]))
     238        44293 :         lc++;
     239              :     }
     240        36384 :     nums[lg] += lc;
     241        36384 :     ause += lc;
     242              :   }
     243        35600 :   return ause;
     244              : }
     245              : 
     246              : 
     247        35600 : static int numusehash (const Table *t, int *nums, int *pnasize) {
     248        35600 :   int totaluse = 0;  /* total number of elements */
     249        35600 :   int ause = 0;  /* summation of `nums' */
     250        35600 :   int i = sizenode(t);
     251       116689 :   while (i--) {
     252        81089 :     Node *n = &t->node[i];
     253        81089 :     if (!ttisnil(gval(n))) {
     254        54994 :       ause += countint(key2tval(n), nums);
     255        54994 :       totaluse++;
     256              :     }
     257              :   }
     258        35600 :   *pnasize += ause;
     259        35600 :   return totaluse;
     260              : }
     261              : 
     262              : 
     263        35014 : static void setarrayvector (lua_State *L, Table *t, int size) {
     264              :   int i;
     265        35014 :   luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
     266        85459 :   for (i=t->sizearray; i<size; i++)
     267        50445 :      setnilvalue(&t->array[i]);
     268        35014 :   t->sizearray = size;
     269        35014 : }
     270              : 
     271              : 
     272        46324 : static void setnodevector (lua_State *L, Table *t, int size) {
     273              :   int lsize;
     274        46324 :   if (size == 0) {  /* no elements to hash part? */
     275        32943 :     t->node = cast(Node *, dummynode);  /* use common `dummynode' */
     276        32943 :     lsize = 0;
     277              :   }
     278              :   else {
     279              :     int i;
     280        13381 :     lsize = ceillog2(size);
     281        13381 :     if (lsize > MAXBITS)
     282            0 :       luaG_runerror(L, "table overflow");
     283        13381 :     size = twoto(lsize);
     284        13381 :     t->node = luaM_newvector(L, size, Node);
     285       133080 :     for (i=0; i<size; i++) {
     286       119699 :       Node *n = gnode(t, i);
     287       119699 :       gnext(n) = NULL;
     288       119699 :       setnilvalue(gkey(n));
     289       119699 :       setnilvalue(gval(n));
     290              :     }
     291              :   }
     292        46324 :   t->lsizenode = cast_byte(lsize);
     293        46324 :   t->lastfree = gnode(t, size);  /* all positions are free */
     294        46324 : }
     295              : 
     296              : 
     297        35813 : static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
     298              :   int i;
     299        35813 :   int oldasize = t->sizearray;
     300        35813 :   int oldhsize = t->lsizenode;
     301        35813 :   Node *nold = t->node;  /* save old hash ... */
     302        35813 :   if (nasize > oldasize)  /* array part must grow? */
     303        24503 :     setarrayvector(L, t, nasize);
     304              :   /* create new hash part with appropriate size */
     305        35813 :   setnodevector(L, t, nhsize);  
     306        35813 :   if (nasize < oldasize) {  /* array part must shrink? */
     307            0 :     t->sizearray = nasize;
     308              :     /* re-insert elements from vanishing slice */
     309            0 :     for (i=nasize; i<oldasize; i++) {
     310            0 :       if (!ttisnil(&t->array[i]))
     311            0 :         setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
     312              :     }
     313              :     /* shrink array */
     314            0 :     luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
     315              :   }
     316              :   /* re-insert elements from hash part */
     317       117115 :   for (i = twoto(oldhsize) - 1; i >= 0; i--) {
     318        81302 :     Node *old = nold+i;
     319        81302 :     if (!ttisnil(gval(old)))
     320        54994 :       setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
     321              :   }
     322        35813 :   if (nold != dummynode)
     323         9507 :     luaM_freearray(L, nold, twoto(oldhsize), Node);  /* free old array */
     324        35813 : }
     325              : 
     326              : 
     327          213 : void luaH_resizearray (lua_State *L, Table *t, int nasize) {
     328          213 :   int nsize = (t->node == dummynode) ? 0 : sizenode(t);
     329          213 :   resize(L, t, nasize, nsize);
     330          213 : }
     331              : 
     332              : 
     333        35600 : static void rehash (lua_State *L, Table *t, const TValue *ek) {
     334              :   int nasize, na;
     335              :   int nums[MAXBITS+1];  /* nums[i] = number of keys between 2^(i-1) and 2^i */
     336              :   int i;
     337              :   int totaluse;
     338       996800 :   for (i=0; i<=MAXBITS; i++) nums[i] = 0;  /* reset counts */
     339        35600 :   nasize = numusearray(t, nums);  /* count keys in array part */
     340        35600 :   totaluse = nasize;  /* all those keys are integer keys */
     341        35600 :   totaluse += numusehash(t, nums, &nasize);  /* count keys in hash part */
     342              :   /* count extra key */
     343        35600 :   nasize += countint(ek, nums);
     344        35600 :   totaluse++;
     345              :   /* compute new size for array part */
     346        35600 :   na = computesizes(nums, &nasize);
     347              :   /* resize the table to new computed sizes */
     348        35600 :   resize(L, t, nasize, totaluse - na);
     349        35600 : }
     350              : 
     351              : 
     352              : 
     353              : /*
     354              : ** }=============================================================
     355              : */
     356              : 
     357              : 
     358        10511 : Table *luaH_new (lua_State *L, int narray, int nhash) {
     359        10511 :   Table *t = luaM_new(L, Table);
     360        10511 :   luaC_link(L, obj2gco(t), LUA_TTABLE);
     361        10511 :   t->metatable = NULL;
     362        10511 :   t->flags = cast_byte(~0);
     363              :   /* temporary values (kept only if some malloc fails) */
     364        10511 :   t->array = NULL;
     365        10511 :   t->sizearray = 0;
     366        10511 :   t->lsizenode = 0;
     367        10511 :   t->node = cast(Node *, dummynode);
     368        10511 :   setarrayvector(L, t, narray);
     369        10511 :   setnodevector(L, t, nhash);
     370        10511 :   return t;
     371              : }
     372              : 
     373              : 
     374        10286 : void luaH_free (lua_State *L, Table *t) {
     375        10286 :   if (t->node != dummynode)
     376         3670 :     luaM_freearray(L, t->node, sizenode(t), Node);
     377        10286 :   luaM_freearray(L, t->array, t->sizearray, TValue);
     378        10286 :   luaM_free(L, t);
     379        10286 : }
     380              : 
     381              : 
     382        72619 : static Node *getfreepos (Table *t) {
     383       115822 :   while (t->lastfree-- > t->node) {
     384        80222 :     if (ttisnil(gkey(t->lastfree)))
     385        37019 :       return t->lastfree;
     386              :   }
     387        35600 :   return NULL;  /* could not find a free place */
     388              : }
     389              : 
     390              : 
     391              : 
     392              : /*
     393              : ** inserts a new key into a hash table; first, check whether key's main 
     394              : ** position is free. If not, check whether colliding node is in its main 
     395              : ** position or not: if it is not, move colliding node to an empty place and 
     396              : ** put new key in its main position; otherwise (colliding node is in its main 
     397              : ** position), new key goes to an empty position. 
     398              : */
     399       136590 : static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
     400       136590 :   Node *mp = mainposition(t, key);
     401       136590 :   if (!ttisnil(gval(mp)) || mp == dummynode) {
     402              :     Node *othern;
     403        72619 :     Node *n = getfreepos(t);  /* get a free place */
     404        72619 :     if (n == NULL) {  /* cannot find a free place? */
     405        35600 :       rehash(L, t, key);  /* grow table */
     406        35600 :       return luaH_set(L, t, key);  /* re-insert key into grown table */
     407              :     }
     408              :     lua_assert(n != dummynode);
     409        37019 :     othern = mainposition(t, key2tval(mp));
     410        37019 :     if (othern != mp) {  /* is colliding node out of its main position? */
     411              :       /* yes; move colliding node into free position */
     412         7925 :       while (gnext(othern) != mp) othern = gnext(othern);  /* find previous */
     413         6429 :       gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */
     414         6429 :       *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
     415         6429 :       gnext(mp) = NULL;  /* now `mp' is free */
     416         6429 :       setnilvalue(gval(mp));
     417              :     }
     418              :     else {  /* colliding node is in its own main position */
     419              :       /* new node will go into free position */
     420        30590 :       gnext(n) = gnext(mp);  /* chain new position */
     421        30590 :       gnext(mp) = n;
     422        30590 :       mp = n;
     423              :     }
     424              :   }
     425       100990 :   gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
     426       100990 :   luaC_barriert(L, t, key);
     427              :   lua_assert(ttisnil(gval(mp)));
     428       100990 :   return gval(mp);
     429              : }
     430              : 
     431              : 
     432              : /*
     433              : ** search function for integers
     434              : */
     435       534327 : const TValue *luaH_getnum (Table *t, int key) {
     436              :   /* (1 <= key && key <= t->sizearray) */
     437       534327 :   if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
     438       505860 :     return &t->array[key-1];
     439              :   else {
     440        28467 :     lua_Number nk = cast_num(key);
     441        28467 :     Node *n = hashnum(t, nk);
     442              :     do {  /* check whether `key' is somewhere in the chain */
     443        29460 :       if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
     444         1230 :         return gval(n);  /* that's it */
     445        28230 :       else n = gnext(n);
     446        28230 :     } while (n);
     447        27237 :     return luaO_nilobject;
     448              :   }
     449              : }
     450              : 
     451              : 
     452              : /*
     453              : ** search function for strings
     454              : */
     455       260098 : const TValue *luaH_getstr (Table *t, TString *key) {
     456       260098 :   Node *n = hashstr(t, key);
     457              :   do {  /* check whether `key' is somewhere in the chain */
     458       302604 :     if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
     459       146309 :       return gval(n);  /* that's it */
     460       156295 :     else n = gnext(n);
     461       156295 :   } while (n);
     462       113789 :   return luaO_nilobject;
     463              : }
     464              : 
     465              : 
     466              : /*
     467              : ** main search function
     468              : */
     469       351919 : const TValue *luaH_get (Table *t, const TValue *key) {
     470       351919 :   switch (ttype(key)) {
     471            4 :     case LUA_TNIL: return luaO_nilobject;
     472       197628 :     case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
     473       153261 :     case LUA_TNUMBER: {
     474              :       int k;
     475       153261 :       lua_Number n = nvalue(key);
     476       153261 :       lua_number2int(k, n);
     477       153261 :       if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
     478       152958 :         return luaH_getnum(t, k);  /* use specialized version */
     479              :       /* else go through */
     480              :     }
     481              :     default: {
     482         1329 :       Node *n = mainposition(t, key);
     483              :       do {  /* check whether `key' is somewhere in the chain */
     484         1758 :         if (luaO_rawequalObj(key2tval(n), key))
     485          681 :           return gval(n);  /* that's it */
     486         1077 :         else n = gnext(n);
     487         1077 :       } while (n);
     488          648 :       return luaO_nilobject;
     489              :     }
     490              :   }
     491              : }
     492              : 
     493              : 
     494       213473 : TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
     495       213473 :   const TValue *p = luaH_get(t, key);
     496       213473 :   t->flags = 0;
     497       213473 :   if (p != luaO_nilobject)
     498       105014 :     return cast(TValue *, p);
     499              :   else {
     500       108459 :     if (ttisnil(key)) luaG_runerror(L, "table index is nil");
     501       108457 :     else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
     502            1 :       luaG_runerror(L, "table index is NaN");
     503       108456 :     return newkey(L, t, key);
     504              :   }
     505              : }
     506              : 
     507              : 
     508        87918 : TValue *luaH_setnum (lua_State *L, Table *t, int key) {
     509        87918 :   const TValue *p = luaH_getnum(t, key);
     510        87918 :   if (p != luaO_nilobject)
     511        87471 :     return cast(TValue *, p);
     512              :   else {
     513              :     TValue k;
     514          447 :     setnvalue(&k, cast_num(key));
     515          447 :     return newkey(L, t, &k);
     516              :   }
     517              : }
     518              : 
     519              : 
     520        54199 : TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
     521        54199 :   const TValue *p = luaH_getstr(t, key);
     522        54199 :   if (p != luaO_nilobject)
     523        26512 :     return cast(TValue *, p);
     524              :   else {
     525              :     TValue k;
     526        27687 :     setsvalue(L, &k, key);
     527        27687 :     return newkey(L, t, &k);
     528              :   }
     529              : }
     530              : 
     531              : 
     532            4 : static int unbound_search (Table *t, unsigned int j) {
     533            4 :   unsigned int i = j;  /* i is zero or a present index */
     534            4 :   j++;
     535              :   /* find `i' and `j' such that i is present and j is not */
     536            4 :   while (!ttisnil(luaH_getnum(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_getnum(t, i))) i++;
     543            0 :       return i - 1;
     544              :     }
     545              :   }
     546              :   /* now do a binary search between them */
     547            4 :   while (j - i > 1) {
     548            0 :     unsigned int m = (i+j)/2;
     549            0 :     if (ttisnil(luaH_getnum(t, m))) j = m;
     550            0 :     else i = m;
     551              :   }
     552            4 :   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        18581 : int luaH_getn (Table *t) {
     561        18581 :   unsigned int j = t->sizearray;
     562        18581 :   if (j > 0 && ttisnil(&t->array[j - 1])) {
     563              :     /* there is a boundary in the array part: (binary) search for it */
     564        17802 :     unsigned int i = 0;
     565        71011 :     while (j - i > 1) {
     566        53209 :       unsigned int m = (i+j)/2;
     567        53209 :       if (ttisnil(&t->array[m - 1])) j = m;
     568        50632 :       else i = m;
     569              :     }
     570        17802 :     return i;
     571              :   }
     572              :   /* else must find a boundary in hash part */
     573          779 :   else if (t->node == dummynode)  /* hash part is empty? */
     574          775 :     return j;  /* that is easy... */
     575            4 :   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 n == dummynode; }
     587              : 
     588              : #endif
        

Generated by: LCOV version 2.0-1