aboutsummaryrefslogtreecommitdiff
path: root/ltablib.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltablib.c')
-rw-r--r--ltablib.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/ltablib.c b/ltablib.c
index 485b8405..55a12c7a 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -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
233static void set2 (lua_State *L, int i, int j) { 233static 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*/
261static int partition (lua_State *L, int lo, int up) { 261static 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>
301static int choosePivot (int lo, int up) { 303
304static 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
314static void auxsort (lua_State *L, int lo, int up) { 317static 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
362static int sort (lua_State *L) { 365static 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