diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-11-07 10:38:35 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-11-07 10:38:35 -0200 |
| commit | 7b1fba69b7a887e37e57744309299d134e76e06e (patch) | |
| tree | e5743e7f4792f065bb9644e827e43eb9a9c03a22 /ltable.c | |
| parent | 697593d8d5b2e2287919423006c53dcac31d2b70 (diff) | |
| download | lua-7b1fba69b7a887e37e57744309299d134e76e06e.tar.gz lua-7b1fba69b7a887e37e57744309299d134e76e06e.tar.bz2 lua-7b1fba69b7a887e37e57744309299d134e76e06e.zip | |
using 'lastfree == NULL' to signal that table is using the dummy
node for its hash part + new macro 'allocsizenode'
Diffstat (limited to 'ltable.c')
| -rw-r--r-- | ltable.c | 46 |
1 files changed, 23 insertions, 23 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.116 2015/11/03 18:35:21 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.117 2015/11/19 19:16:22 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 | */ |
| @@ -74,8 +74,6 @@ | |||
| 74 | 74 | ||
| 75 | #define dummynode (&dummynode_) | 75 | #define dummynode (&dummynode_) |
| 76 | 76 | ||
| 77 | #define isdummy(n) ((n) == dummynode) | ||
| 78 | |||
| 79 | static const Node dummynode_ = { | 77 | static const Node dummynode_ = { |
| 80 | {NILCONSTANT}, /* value */ | 78 | {NILCONSTANT}, /* value */ |
| 81 | {{NILCONSTANT, 0}} /* key */ | 79 | {{NILCONSTANT, 0}} /* key */ |
| @@ -308,14 +306,14 @@ static void setarrayvector (lua_State *L, Table *t, unsigned int size) { | |||
| 308 | 306 | ||
| 309 | 307 | ||
| 310 | static void setnodevector (lua_State *L, Table *t, unsigned int size) { | 308 | static void setnodevector (lua_State *L, Table *t, unsigned int size) { |
| 311 | int lsize; | ||
| 312 | if (size == 0) { /* no elements to hash part? */ | 309 | if (size == 0) { /* no elements to hash part? */ |
| 313 | t->node = cast(Node *, dummynode); /* use common 'dummynode' */ | 310 | t->node = cast(Node *, dummynode); /* use common 'dummynode' */ |
| 314 | lsize = 0; | 311 | t->lsizenode = 0; |
| 312 | t->lastfree = NULL; /* signal that it is using dummy node */ | ||
| 315 | } | 313 | } |
| 316 | else { | 314 | else { |
| 317 | int i; | 315 | int i; |
| 318 | lsize = luaO_ceillog2(size); | 316 | int lsize = luaO_ceillog2(size); |
| 319 | if (lsize > MAXHBITS) | 317 | if (lsize > MAXHBITS) |
| 320 | luaG_runerror(L, "table overflow"); | 318 | luaG_runerror(L, "table overflow"); |
| 321 | size = twoto(lsize); | 319 | size = twoto(lsize); |
| @@ -326,9 +324,9 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) { | |||
| 326 | setnilvalue(wgkey(n)); | 324 | setnilvalue(wgkey(n)); |
| 327 | setnilvalue(gval(n)); | 325 | setnilvalue(gval(n)); |
| 328 | } | 326 | } |
| 327 | t->lsizenode = cast_byte(lsize); | ||
| 328 | t->lastfree = gnode(t, size); /* all positions are free */ | ||
| 329 | } | 329 | } |
| 330 | t->lsizenode = cast_byte(lsize); | ||
| 331 | t->lastfree = gnode(t, size); /* all positions are free */ | ||
| 332 | } | 330 | } |
| 333 | 331 | ||
| 334 | 332 | ||
| @@ -337,7 +335,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | |||
| 337 | unsigned int i; | 335 | unsigned int i; |
| 338 | int j; | 336 | int j; |
| 339 | unsigned int oldasize = t->sizearray; | 337 | unsigned int oldasize = t->sizearray; |
| 340 | int oldhsize = t->lsizenode; | 338 | int oldhsize = allocsizenode(t); |
| 341 | Node *nold = t->node; /* save old hash ... */ | 339 | Node *nold = t->node; /* save old hash ... */ |
| 342 | if (nasize > oldasize) /* array part must grow? */ | 340 | if (nasize > oldasize) /* array part must grow? */ |
| 343 | setarrayvector(L, t, nasize); | 341 | setarrayvector(L, t, nasize); |
| @@ -354,7 +352,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | |||
| 354 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); | 352 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); |
| 355 | } | 353 | } |
| 356 | /* re-insert elements from hash part */ | 354 | /* re-insert elements from hash part */ |
| 357 | for (j = twoto(oldhsize) - 1; j >= 0; j--) { | 355 | for (j = oldhsize - 1; j >= 0; j--) { |
| 358 | Node *old = nold + j; | 356 | Node *old = nold + j; |
| 359 | if (!ttisnil(gval(old))) { | 357 | if (!ttisnil(gval(old))) { |
| 360 | /* doesn't need barrier/invalidate cache, as entry was | 358 | /* doesn't need barrier/invalidate cache, as entry was |
| @@ -362,13 +360,13 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | |||
| 362 | setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); | 360 | setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); |
| 363 | } | 361 | } |
| 364 | } | 362 | } |
| 365 | if (!isdummy(nold)) | 363 | if (oldhsize > 0) /* not the dummy node? */ |
| 366 | luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */ | 364 | luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */ |
| 367 | } | 365 | } |
| 368 | 366 | ||
| 369 | 367 | ||
| 370 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { | 368 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { |
| 371 | int nsize = isdummy(t->node) ? 0 : sizenode(t); | 369 | int nsize = allocsizenode(t); |
| 372 | luaH_resize(L, t, nasize, nsize); | 370 | luaH_resize(L, t, nasize, nsize); |
| 373 | } | 371 | } |
| 374 | 372 | ||
| @@ -414,7 +412,7 @@ Table *luaH_new (lua_State *L) { | |||
| 414 | 412 | ||
| 415 | 413 | ||
| 416 | void luaH_free (lua_State *L, Table *t) { | 414 | void luaH_free (lua_State *L, Table *t) { |
| 417 | if (!isdummy(t->node)) | 415 | if (!isdummy(t)) |
| 418 | luaM_freearray(L, t->node, cast(size_t, sizenode(t))); | 416 | luaM_freearray(L, t->node, cast(size_t, sizenode(t))); |
| 419 | luaM_freearray(L, t->array, t->sizearray); | 417 | luaM_freearray(L, t->array, t->sizearray); |
| 420 | luaM_free(L, t); | 418 | luaM_free(L, t); |
| @@ -422,10 +420,12 @@ void luaH_free (lua_State *L, Table *t) { | |||
| 422 | 420 | ||
| 423 | 421 | ||
| 424 | static Node *getfreepos (Table *t) { | 422 | static Node *getfreepos (Table *t) { |
| 425 | while (t->lastfree > t->node) { | 423 | if (!isdummy(t)) { |
| 426 | t->lastfree--; | 424 | while (t->lastfree > t->node) { |
| 427 | if (ttisnil(gkey(t->lastfree))) | 425 | t->lastfree--; |
| 428 | return t->lastfree; | 426 | if (ttisnil(gkey(t->lastfree))) |
| 427 | return t->lastfree; | ||
| 428 | } | ||
| 429 | } | 429 | } |
| 430 | return NULL; /* could not find a free place */ | 430 | return NULL; /* could not find a free place */ |
| 431 | } | 431 | } |
| @@ -445,7 +445,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 445 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); | 445 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); |
| 446 | else if (ttisfloat(key)) { | 446 | else if (ttisfloat(key)) { |
| 447 | lua_Integer k; | 447 | lua_Integer k; |
| 448 | if (luaV_tointeger(key, &k, 0)) { /* index is int? */ | 448 | if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */ |
| 449 | setivalue(&aux, k); | 449 | setivalue(&aux, k); |
| 450 | key = &aux; /* insert it as an integer */ | 450 | key = &aux; /* insert it as an integer */ |
| 451 | } | 451 | } |
| @@ -453,7 +453,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 453 | luaG_runerror(L, "table index is NaN"); | 453 | luaG_runerror(L, "table index is NaN"); |
| 454 | } | 454 | } |
| 455 | mp = mainposition(t, key); | 455 | mp = mainposition(t, key); |
| 456 | if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ | 456 | if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ |
| 457 | Node *othern; | 457 | Node *othern; |
| 458 | Node *f = getfreepos(t); /* get a free place */ | 458 | Node *f = getfreepos(t); /* get a free place */ |
| 459 | if (f == NULL) { /* cannot find a free place? */ | 459 | if (f == NULL) { /* cannot find a free place? */ |
| @@ -461,7 +461,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 461 | /* whatever called 'newkey' takes care of TM cache */ | 461 | /* whatever called 'newkey' takes care of TM cache */ |
| 462 | return luaH_set(L, t, key); /* insert key into grown table */ | 462 | return luaH_set(L, t, key); /* insert key into grown table */ |
| 463 | } | 463 | } |
| 464 | lua_assert(!isdummy(f)); | 464 | lua_assert(!isdummy(t)); |
| 465 | othern = mainposition(t, gkey(mp)); | 465 | othern = mainposition(t, gkey(mp)); |
| 466 | if (othern != mp) { /* is colliding node out of its main position? */ | 466 | if (othern != mp) { /* is colliding node out of its main position? */ |
| 467 | /* yes; move colliding node into free position */ | 467 | /* yes; move colliding node into free position */ |
| @@ -651,7 +651,7 @@ int luaH_getn (Table *t) { | |||
| 651 | return i; | 651 | return i; |
| 652 | } | 652 | } |
| 653 | /* else must find a boundary in hash part */ | 653 | /* else must find a boundary in hash part */ |
| 654 | else if (isdummy(t->node)) /* hash part is empty? */ | 654 | else if (isdummy(t)) /* hash part is empty? */ |
| 655 | return j; /* that is easy... */ | 655 | return j; /* that is easy... */ |
| 656 | else return unbound_search(t, j); | 656 | else return unbound_search(t, j); |
| 657 | } | 657 | } |
| @@ -664,6 +664,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) { | |||
| 664 | return mainposition(t, key); | 664 | return mainposition(t, key); |
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | int luaH_isdummy (Node *n) { return isdummy(n); } | 667 | int luaH_isdummy (const Table *t) { return isdummy(t); } |
| 668 | 668 | ||
| 669 | #endif | 669 | #endif |
