diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-09-04 15:15:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-09-04 15:15:29 -0300 |
commit | 3a15c7ce4338de8414239a898f6c121294b4dde7 (patch) | |
tree | 2d449c2966afaf5d092b6d07d8f04b2b0a9b13bb /ltable.c | |
parent | 0a6b58c3aac2741cf1c84c44d168c73e3e478c4d (diff) | |
download | lua-3a15c7ce4338de8414239a898f6c121294b4dde7.tar.gz lua-3a15c7ce4338de8414239a898f6c121294b4dde7.tar.bz2 lua-3a15c7ce4338de8414239a898f6c121294b4dde7.zip |
size for array part of a table ('sizearray') changed from 'int' to
'unsigned int', which allows twice as many elements in the array part
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 134 |
1 files changed, 75 insertions, 59 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 2.93 2014/07/29 16:22:24 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.94 2014/08/01 17:24:02 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 | */ |
@@ -40,14 +40,19 @@ | |||
40 | 40 | ||
41 | 41 | ||
42 | /* | 42 | /* |
43 | ** Maximum size of array part (MAXASIZE) is 2^MAXBITS. (SIZEINT is the | 43 | ** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is |
44 | ** minimum between size of int and size of LUA_INTEGER; array indices | 44 | ** the largest integer such that MAXASIZE fits in an unsigned int. |
45 | ** are limited by both types.) | ||
46 | */ | 45 | */ |
47 | #define SIZEINT \ | 46 | #define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) |
48 | (sizeof(int) < sizeof(LUA_INTEGER) ? sizeof(int) : sizeof(LUA_INTEGER)) | 47 | #define MAXASIZE (1u << MAXABITS) |
49 | #define MAXBITS cast_int(SIZEINT * CHAR_BIT - 2) | 48 | |
50 | #define MAXASIZE (1 << MAXBITS) | 49 | /* |
50 | ** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest | ||
51 | ** integer such that 2^MAXHBITS fits in a signed int. (Note that the | ||
52 | ** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still | ||
53 | ** fits comfortably in an unsigned int.) | ||
54 | */ | ||
55 | #define MAXHBITS (MAXABITS - 1) | ||
51 | 56 | ||
52 | 57 | ||
53 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) | 58 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) |
@@ -139,29 +144,29 @@ static Node *mainposition (const Table *t, const TValue *key) { | |||
139 | 144 | ||
140 | /* | 145 | /* |
141 | ** returns the index for `key' if `key' is an appropriate key to live in | 146 | ** returns the index for `key' if `key' is an appropriate key to live in |
142 | ** the array part of the table, -1 otherwise. | 147 | ** the array part of the table, 0 otherwise. |
143 | */ | 148 | */ |
144 | static int arrayindex (const TValue *key) { | 149 | static unsigned int arrayindex (const TValue *key) { |
145 | if (ttisinteger(key)) { | 150 | if (ttisinteger(key)) { |
146 | lua_Integer k = ivalue(key); | 151 | lua_Integer k = ivalue(key); |
147 | if (0 < k && k <= MAXASIZE) /* is `key' an appropriate array index? */ | 152 | if (0 < k && (lua_Unsigned)k <= MAXASIZE) |
148 | return cast_int(k); | 153 | return cast(unsigned int, k); /* 'key' is an appropriate array index */ |
149 | } | 154 | } |
150 | return -1; /* `key' did not match some condition */ | 155 | return 0; /* `key' did not match some condition */ |
151 | } | 156 | } |
152 | 157 | ||
153 | 158 | ||
154 | /* | 159 | /* |
155 | ** returns the index of a `key' for table traversals. First goes all | 160 | ** returns the index of a `key' for table traversals. First goes all |
156 | ** elements in the array part, then elements in the hash part. The | 161 | ** elements in the array part, then elements in the hash part. The |
157 | ** beginning of a traversal is signaled by -1. | 162 | ** beginning of a traversal is signaled by 0. |
158 | */ | 163 | */ |
159 | static int findindex (lua_State *L, Table *t, StkId key) { | 164 | static unsigned int findindex (lua_State *L, Table *t, StkId key) { |
160 | int i; | 165 | unsigned int i; |
161 | if (ttisnil(key)) return -1; /* first iteration */ | 166 | if (ttisnil(key)) return 0; /* first iteration */ |
162 | i = arrayindex(key); | 167 | i = arrayindex(key); |
163 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ | 168 | if (i != 0 && i <= t->sizearray) /* is `key' inside array part? */ |
164 | return i-1; /* yes; that's the index (corrected to C) */ | 169 | return i; /* yes; that's the index */ |
165 | else { | 170 | else { |
166 | int nx; | 171 | int nx; |
167 | Node *n = mainposition(t, key); | 172 | Node *n = mainposition(t, key); |
@@ -172,7 +177,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { | |||
172 | deadvalue(gkey(n)) == gcvalue(key))) { | 177 | deadvalue(gkey(n)) == gcvalue(key))) { |
173 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ | 178 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ |
174 | /* hash elements are numbered after array ones */ | 179 | /* hash elements are numbered after array ones */ |
175 | return i + t->sizearray; | 180 | return (i + 1) + t->sizearray; |
176 | } | 181 | } |
177 | nx = gnext(n); | 182 | nx = gnext(n); |
178 | if (nx == 0) | 183 | if (nx == 0) |
@@ -184,15 +189,15 @@ static int findindex (lua_State *L, Table *t, StkId key) { | |||
184 | 189 | ||
185 | 190 | ||
186 | int luaH_next (lua_State *L, Table *t, StkId key) { | 191 | int luaH_next (lua_State *L, Table *t, StkId key) { |
187 | int i = findindex(L, t, key); /* find original element */ | 192 | unsigned int i = findindex(L, t, key); /* find original element */ |
188 | for (i++; i < t->sizearray; i++) { /* try first array part */ | 193 | for (; i < t->sizearray; i++) { /* try first array part */ |
189 | if (!ttisnil(&t->array[i])) { /* a non-nil value? */ | 194 | if (!ttisnil(&t->array[i])) { /* a non-nil value? */ |
190 | setivalue(key, i + 1); | 195 | setivalue(key, i + 1); |
191 | setobj2s(L, key+1, &t->array[i]); | 196 | setobj2s(L, key+1, &t->array[i]); |
192 | return 1; | 197 | return 1; |
193 | } | 198 | } |
194 | } | 199 | } |
195 | for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ | 200 | for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ |
196 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ | 201 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ |
197 | setobj2s(L, key, gkey(gnode(t, i))); | 202 | setobj2s(L, key, gkey(gnode(t, i))); |
198 | setobj2s(L, key+1, gval(gnode(t, i))); | 203 | setobj2s(L, key+1, gval(gnode(t, i))); |
@@ -209,19 +214,24 @@ int luaH_next (lua_State *L, Table *t, StkId key) { | |||
209 | ** ============================================================== | 214 | ** ============================================================== |
210 | */ | 215 | */ |
211 | 216 | ||
212 | 217 | /* | |
213 | static int computesizes (int nums[], int *narray) { | 218 | ** Compute the optimal size for the array part of table 't'. 'nums' is a |
219 | ** "count array" where 'nums[i]' is the number of integers in the table | ||
220 | ** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and | ||
221 | ** return the number of elements that will go to that part. | ||
222 | */ | ||
223 | static unsigned int computesizes (unsigned int nums[], unsigned int *narray) { | ||
214 | int i; | 224 | int i; |
215 | int twotoi; /* 2^i */ | 225 | unsigned int twotoi; /* 2^i */ |
216 | int a = 0; /* number of elements smaller than 2^i */ | 226 | unsigned int a = 0; /* number of elements smaller than 2^i */ |
217 | int na = 0; /* number of elements to go to array part */ | 227 | unsigned int na = 0; /* number of elements to go to array part */ |
218 | int n = 0; /* optimal size for array part */ | 228 | unsigned int n = 0; /* optimal size for array part */ |
219 | for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { | 229 | for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { |
220 | if (nums[i] > 0) { | 230 | if (nums[i] > 0) { |
221 | a += nums[i]; | 231 | a += nums[i]; |
222 | if (a > twotoi/2) { /* more than half elements present? */ | 232 | if (a > twotoi/2) { /* more than half elements present? */ |
223 | n = twotoi; /* optimal size (till now) */ | 233 | n = twotoi; /* optimal size (till now) */ |
224 | na = a; /* all elements smaller than n will go to array part */ | 234 | na = a; /* all elements up to 'n' will go to array part */ |
225 | } | 235 | } |
226 | } | 236 | } |
227 | if (a == *narray) break; /* all elements already counted */ | 237 | if (a == *narray) break; /* all elements already counted */ |
@@ -232,9 +242,9 @@ static int computesizes (int nums[], int *narray) { | |||
232 | } | 242 | } |
233 | 243 | ||
234 | 244 | ||
235 | static int countint (const TValue *key, int *nums) { | 245 | static int countint (const TValue *key, unsigned int *nums) { |
236 | int k = arrayindex(key); | 246 | unsigned int k = arrayindex(key); |
237 | if (k > 0) { /* is `key' an appropriate array index? */ | 247 | if (k != 0) { /* is `key' an appropriate array index? */ |
238 | nums[luaO_ceillog2(k)]++; /* count as such */ | 248 | nums[luaO_ceillog2(k)]++; /* count as such */ |
239 | return 1; | 249 | return 1; |
240 | } | 250 | } |
@@ -243,20 +253,21 @@ static int countint (const TValue *key, int *nums) { | |||
243 | } | 253 | } |
244 | 254 | ||
245 | 255 | ||
246 | static int numusearray (const Table *t, int *nums) { | 256 | static unsigned int numusearray (const Table *t, unsigned int *nums) { |
247 | int lg; | 257 | int lg; |
248 | int ttlg; /* 2^lg */ | 258 | unsigned int ttlg; /* 2^lg */ |
249 | int ause = 0; /* summation of `nums' */ | 259 | unsigned int ause = 0; /* summation of `nums' */ |
250 | int i = 1; /* count to traverse all array keys */ | 260 | unsigned int i = 1; /* count to traverse all array keys */ |
251 | for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ | 261 | /* traverse each slice */ |
252 | int lc = 0; /* counter */ | 262 | for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { |
253 | int lim = ttlg; | 263 | unsigned int lc = 0; /* counter */ |
264 | unsigned int lim = ttlg; | ||
254 | if (lim > t->sizearray) { | 265 | if (lim > t->sizearray) { |
255 | lim = t->sizearray; /* adjust upper limit */ | 266 | lim = t->sizearray; /* adjust upper limit */ |
256 | if (i > lim) | 267 | if (i > lim) |
257 | break; /* no more elements to count */ | 268 | break; /* no more elements to count */ |
258 | } | 269 | } |
259 | /* count elements in range (2^(lg-1), 2^lg] */ | 270 | /* count elements in range (2^(lg - 1), 2^lg] */ |
260 | for (; i <= lim; i++) { | 271 | for (; i <= lim; i++) { |
261 | if (!ttisnil(&t->array[i-1])) | 272 | if (!ttisnil(&t->array[i-1])) |
262 | lc++; | 273 | lc++; |
@@ -268,9 +279,10 @@ static int numusearray (const Table *t, int *nums) { | |||
268 | } | 279 | } |
269 | 280 | ||
270 | 281 | ||
271 | static int numusehash (const Table *t, int *nums, int *pnasize) { | 282 | static int numusehash (const Table *t, unsigned int *nums, |
283 | unsigned int *pnasize) { | ||
272 | int totaluse = 0; /* total number of elements */ | 284 | int totaluse = 0; /* total number of elements */ |
273 | int ause = 0; /* summation of `nums' */ | 285 | int ause = 0; /* elements added to 'nums' (can go to array part) */ |
274 | int i = sizenode(t); | 286 | int i = sizenode(t); |
275 | while (i--) { | 287 | while (i--) { |
276 | Node *n = &t->node[i]; | 288 | Node *n = &t->node[i]; |
@@ -284,8 +296,8 @@ static int numusehash (const Table *t, int *nums, int *pnasize) { | |||
284 | } | 296 | } |
285 | 297 | ||
286 | 298 | ||
287 | static void setarrayvector (lua_State *L, Table *t, int size) { | 299 | static void setarrayvector (lua_State *L, Table *t, unsigned int size) { |
288 | int i; | 300 | unsigned int i; |
289 | luaM_reallocvector(L, t->array, t->sizearray, size, TValue); | 301 | luaM_reallocvector(L, t->array, t->sizearray, size, TValue); |
290 | for (i=t->sizearray; i<size; i++) | 302 | for (i=t->sizearray; i<size; i++) |
291 | setnilvalue(&t->array[i]); | 303 | setnilvalue(&t->array[i]); |
@@ -293,7 +305,7 @@ static void setarrayvector (lua_State *L, Table *t, int size) { | |||
293 | } | 305 | } |
294 | 306 | ||
295 | 307 | ||
296 | static void setnodevector (lua_State *L, Table *t, int size) { | 308 | static void setnodevector (lua_State *L, Table *t, unsigned int size) { |
297 | int lsize; | 309 | int lsize; |
298 | if (size == 0) { /* no elements to hash part? */ | 310 | if (size == 0) { /* no elements to hash part? */ |
299 | t->node = cast(Node *, dummynode); /* use common `dummynode' */ | 311 | t->node = cast(Node *, dummynode); /* use common `dummynode' */ |
@@ -302,11 +314,11 @@ static void setnodevector (lua_State *L, Table *t, int size) { | |||
302 | else { | 314 | else { |
303 | int i; | 315 | int i; |
304 | lsize = luaO_ceillog2(size); | 316 | lsize = luaO_ceillog2(size); |
305 | if (lsize > MAXBITS) | 317 | if (lsize > MAXHBITS) |
306 | luaG_runerror(L, "table overflow"); | 318 | luaG_runerror(L, "table overflow"); |
307 | size = twoto(lsize); | 319 | size = twoto(lsize); |
308 | t->node = luaM_newvector(L, size, Node); | 320 | t->node = luaM_newvector(L, size, Node); |
309 | for (i=0; i<size; i++) { | 321 | for (i = 0; i < (int)size; i++) { |
310 | Node *n = gnode(t, i); | 322 | Node *n = gnode(t, i); |
311 | gnext(n) = 0; | 323 | gnext(n) = 0; |
312 | setnilvalue(wgkey(n)); | 324 | setnilvalue(wgkey(n)); |
@@ -318,9 +330,11 @@ static void setnodevector (lua_State *L, Table *t, int size) { | |||
318 | } | 330 | } |
319 | 331 | ||
320 | 332 | ||
321 | void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { | 333 | void luaH_resize (lua_State *L, Table *t, unsigned int nasize, |
322 | int i; | 334 | unsigned int nhsize) { |
323 | int oldasize = t->sizearray; | 335 | unsigned int i; |
336 | int j; | ||
337 | unsigned int oldasize = t->sizearray; | ||
324 | int oldhsize = t->lsizenode; | 338 | int oldhsize = t->lsizenode; |
325 | Node *nold = t->node; /* save old hash ... */ | 339 | Node *nold = t->node; /* save old hash ... */ |
326 | if (nasize > oldasize) /* array part must grow? */ | 340 | if (nasize > oldasize) /* array part must grow? */ |
@@ -338,8 +352,8 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { | |||
338 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); | 352 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); |
339 | } | 353 | } |
340 | /* re-insert elements from hash part */ | 354 | /* re-insert elements from hash part */ |
341 | for (i = twoto(oldhsize) - 1; i >= 0; i--) { | 355 | for (j = twoto(oldhsize) - 1; j >= 0; j--) { |
342 | Node *old = nold+i; | 356 | Node *old = nold + j; |
343 | if (!ttisnil(gval(old))) { | 357 | if (!ttisnil(gval(old))) { |
344 | /* doesn't need barrier/invalidate cache, as entry was | 358 | /* doesn't need barrier/invalidate cache, as entry was |
345 | already present in the table */ | 359 | already present in the table */ |
@@ -351,18 +365,20 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { | |||
351 | } | 365 | } |
352 | 366 | ||
353 | 367 | ||
354 | void luaH_resizearray (lua_State *L, Table *t, int nasize) { | 368 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { |
355 | int nsize = isdummy(t->node) ? 0 : sizenode(t); | 369 | int nsize = isdummy(t->node) ? 0 : sizenode(t); |
356 | luaH_resize(L, t, nasize, nsize); | 370 | luaH_resize(L, t, nasize, nsize); |
357 | } | 371 | } |
358 | 372 | ||
359 | 373 | /* | |
374 | ** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i | ||
375 | */ | ||
360 | static void rehash (lua_State *L, Table *t, const TValue *ek) { | 376 | static void rehash (lua_State *L, Table *t, const TValue *ek) { |
361 | int nasize, na; | 377 | unsigned int nasize, na; |
362 | int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ | 378 | unsigned int nums[MAXABITS + 1]; |
363 | int i; | 379 | int i; |
364 | int totaluse; | 380 | int totaluse; |
365 | for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ | 381 | for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ |
366 | nasize = numusearray(t, nums); /* count keys in array part */ | 382 | nasize = numusearray(t, nums); /* count keys in array part */ |
367 | totaluse = nasize; /* all those keys are integer keys */ | 383 | totaluse = nasize; /* all those keys are integer keys */ |
368 | totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ | 384 | totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ |
@@ -478,7 +494,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
478 | */ | 494 | */ |
479 | const TValue *luaH_getint (Table *t, lua_Integer key) { | 495 | const TValue *luaH_getint (Table *t, lua_Integer key) { |
480 | /* (1 <= key && key <= t->sizearray) */ | 496 | /* (1 <= key && key <= t->sizearray) */ |
481 | if (l_castS2U(key - 1) < cast(unsigned int, t->sizearray)) | 497 | if (l_castS2U(key - 1) < t->sizearray) |
482 | return &t->array[key - 1]; | 498 | return &t->array[key - 1]; |
483 | else { | 499 | else { |
484 | Node *n = hashint(t, key); | 500 | Node *n = hashint(t, key); |