diff options
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 50 |
1 files changed, 49 insertions, 1 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 2.17 2005/03/08 20:10:05 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.18 2005/03/09 16:28:07 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -524,3 +524,51 @@ TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { | |||
524 | } | 524 | } |
525 | } | 525 | } |
526 | 526 | ||
527 | |||
528 | static int unbound_search (Table *t, unsigned int j) { | ||
529 | unsigned int i = j; /* i is zero or a present index */ | ||
530 | j = j+1; | ||
531 | /* find `i' and `j' such that i is present and j is not */ | ||
532 | while (!ttisnil(luaH_getnum(t, j))) { | ||
533 | i = j; | ||
534 | j = i*2; | ||
535 | if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ | ||
536 | /* table was built with bad purposes: resort to linear search */ | ||
537 | i = 1; | ||
538 | while (!ttisnil(luaH_getnum(t, i))) i++; | ||
539 | return i - 1; | ||
540 | } | ||
541 | } | ||
542 | /* now do a binary search between them */ | ||
543 | while (i < j-1) { | ||
544 | unsigned int m = (i+j)/2; | ||
545 | if (ttisnil(luaH_getnum(t, m))) j = m; | ||
546 | else i = m; | ||
547 | } | ||
548 | return i; | ||
549 | } | ||
550 | |||
551 | |||
552 | /* | ||
553 | ** Try to find a boundary in table `t'. A `boundary' is an integer index | ||
554 | ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). | ||
555 | */ | ||
556 | int luaH_getn (Table *t) { | ||
557 | unsigned int j = t->sizearray; | ||
558 | if (j > 0 && ttisnil(&t->array[j - 1])) { | ||
559 | /* there is a boundary in the array part: (binary) search for it */ | ||
560 | unsigned int i = 1; | ||
561 | if (ttisnil(&t->array[1 - 1])) return 0; | ||
562 | while (i < j - 1) { | ||
563 | unsigned int m = (i+j)/2; | ||
564 | if (ttisnil(&t->array[m - 1])) j = m; | ||
565 | else i = m; | ||
566 | } | ||
567 | return i; | ||
568 | } | ||
569 | /* else must find a boundary in hash part */ | ||
570 | else if (t->node == &luaH_dummynode) /* hash part is empty? */ | ||
571 | return j; /* that is easy... */ | ||
572 | else return unbound_search(t, j); | ||
573 | } | ||
574 | |||