diff options
Diffstat (limited to 'ltablib.c')
-rw-r--r-- | ltablib.c | 40 |
1 files changed, 23 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltablib.c,v 1.86 2015/11/20 12:30:20 roberto Exp roberto $ | 2 | ** $Id: ltablib.c,v 1.87 2015/11/23 11:09:27 roberto Exp roberto $ |
3 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -230,7 +230,7 @@ static int unpack (lua_State *L) { | |||
230 | ** ======================================================= | 230 | ** ======================================================= |
231 | */ | 231 | */ |
232 | 232 | ||
233 | static void set2 (lua_State *L, int i, int j) { | 233 | static void set2 (lua_State *L, unsigned int i, unsigned int j) { |
234 | lua_seti(L, 1, i); | 234 | lua_seti(L, 1, i); |
235 | lua_seti(L, 1, j); | 235 | lua_seti(L, 1, j); |
236 | } | 236 | } |
@@ -258,9 +258,10 @@ static int sort_comp (lua_State *L, int a, int b) { | |||
258 | ** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] | 258 | ** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] |
259 | ** returns 'i'. | 259 | ** returns 'i'. |
260 | */ | 260 | */ |
261 | static int partition (lua_State *L, int lo, int up) { | 261 | static unsigned int partition (lua_State *L, unsigned int lo, |
262 | int i = lo; /* will be incremented before first use */ | 262 | unsigned int up) { |
263 | int j = up - 1; /* will be decremented before first use */ | 263 | unsigned int i = lo; /* will be incremented before first use */ |
264 | unsigned int j = up - 1; /* will be decremented before first use */ | ||
264 | /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ | 265 | /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ |
265 | for (;;) { | 266 | for (;;) { |
266 | /* next loop: repeat ++i while a[i] < P */ | 267 | /* next loop: repeat ++i while a[i] < P */ |
@@ -292,28 +293,30 @@ static int partition (lua_State *L, int lo, int up) { | |||
292 | 293 | ||
293 | /* | 294 | /* |
294 | ** Choose a "random" pivot in the middle part of the interval [lo, up]. | 295 | ** Choose a "random" pivot in the middle part of the interval [lo, up]. |
295 | ** (If you don't want/need this "randomness", (lo+up)/2 is an excelent | 296 | ** (If you don't want/need this "randomness", (lo+up)/2 is an excellent |
296 | ** choice.) | 297 | ** choice.) |
297 | */ | 298 | */ |
298 | #if !defined(l_sortpivot) | 299 | #if !defined(l_sortpivot) |
299 | /* Use 'time' and 'clock' as sources of "randomness" */ | 300 | /* Use 'time' and 'clock' as sources of "randomness" */ |
301 | |||
300 | #include <time.h> | 302 | #include <time.h> |
301 | static int choosePivot (int lo, int up) { | 303 | |
304 | static unsigned int choosePivot (unsigned int lo, unsigned int up) { | ||
302 | unsigned int t = (unsigned int)(unsigned long)time(NULL); /* time */ | 305 | unsigned int t = (unsigned int)(unsigned long)time(NULL); /* time */ |
303 | unsigned int c = (unsigned int)(unsigned long)clock(); /* clock */ | 306 | unsigned int c = (unsigned int)(unsigned long)clock(); /* clock */ |
304 | unsigned int r4 = (unsigned int)(up - lo) / 4u; /* range/4 */ | 307 | unsigned int r4 = (unsigned int)(up - lo) / 4u; /* range/4 */ |
305 | unsigned int p = (c + t) % (r4 * 2) + (lo + r4); | 308 | unsigned int p = (c + t) % (r4 * 2) + (lo + r4); |
306 | lua_assert(lo + r4 <= p && p <= up - r4); | 309 | lua_assert(lo + r4 <= p && p <= up - r4); |
307 | return (int)p; | 310 | return p; |
308 | } | 311 | } |
309 | 312 | ||
310 | #define l_sortpivot(lo,up) choosePivot(lo,up) | 313 | #define l_sortpivot(lo,up) choosePivot(lo,up) |
311 | #endif | 314 | #endif |
312 | 315 | ||
313 | 316 | ||
314 | static void auxsort (lua_State *L, int lo, int up) { | 317 | static void auxsort (lua_State *L, unsigned int lo, unsigned int up) { |
315 | while (lo < up) { /* loop for tail recursion */ | 318 | while (lo < up) { /* loop for tail recursion */ |
316 | int p; /* Pivot index */ | 319 | unsigned int p; /* Pivot index */ |
317 | /* sort elements 'lo', 'p', and 'up' */ | 320 | /* sort elements 'lo', 'p', and 'up' */ |
318 | lua_geti(L, 1, lo); | 321 | lua_geti(L, 1, lo); |
319 | lua_geti(L, 1, up); | 322 | lua_geti(L, 1, up); |
@@ -323,7 +326,7 @@ static void auxsort (lua_State *L, int lo, int up) { | |||
323 | lua_pop(L, 2); /* remove both values */ | 326 | lua_pop(L, 2); /* remove both values */ |
324 | if (up - lo == 1) /* only 2 elements? */ | 327 | if (up - lo == 1) /* only 2 elements? */ |
325 | return; /* already sorted */ | 328 | return; /* already sorted */ |
326 | if (up - lo < 100) /* small interval? */ | 329 | if (up - lo < 100u) /* small interval? */ |
327 | p = (lo + up)/2; /* middle element is a good pivot */ | 330 | p = (lo + up)/2; /* middle element is a good pivot */ |
328 | else /* for larger intervals, it is worth a random pivot */ | 331 | else /* for larger intervals, it is worth a random pivot */ |
329 | p = l_sortpivot(lo, up); | 332 | p = l_sortpivot(lo, up); |
@@ -360,12 +363,15 @@ static void auxsort (lua_State *L, int lo, int up) { | |||
360 | 363 | ||
361 | 364 | ||
362 | static int sort (lua_State *L) { | 365 | static int sort (lua_State *L) { |
363 | int n = (int)aux_getn(L, 1, TAB_RW); | 366 | lua_Integer n = aux_getn(L, 1, TAB_RW); |
364 | luaL_checkstack(L, 50, ""); /* assume array is smaller than 2^50 */ | 367 | if (n > 1) { /* non-trivial interval? */ |
365 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ | 368 | luaL_argcheck(L, n < INT_MAX, 1, "array too big"); |
366 | luaL_checktype(L, 2, LUA_TFUNCTION); | 369 | luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ |
367 | lua_settop(L, 2); /* make sure there are two arguments */ | 370 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ |
368 | auxsort(L, 1, n); | 371 | luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ |
372 | lua_settop(L, 2); /* make sure there are two arguments */ | ||
373 | auxsort(L, 1, (unsigned int)n); | ||
374 | } | ||
369 | return 0; | 375 | return 0; |
370 | } | 376 | } |
371 | 377 | ||