Changeset: 4d235bc79982 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4d235bc79982
Modified Files:
        gdk/gdk_qsort.c
        gdk/gdk_qsort_impl.h
Branch: default
Log Message:

Some more tweaks to gdk_qsort.


diffs (138 lines):

diff --git a/gdk/gdk_qsort.c b/gdk/gdk_qsort.c
--- a/gdk/gdk_qsort.c
+++ b/gdk/gdk_qsort.c
@@ -40,7 +40,6 @@ struct qsort_t {
         (buf->hs == 2 ? ((unsigned short *) b)[i] + GDK_VAROFFSET :    \
          ((var_t *) b)[i])))
 #endif
-#define VAL(i)         (buf->base ? OFF(b, (i)) : b + (i) * buf->hs)
 
 /* return index of middle value at indexes a, b, and c */
 #define MED3(a, b, c) (LT(a, b) ?                                      \
@@ -243,13 +242,15 @@ struct qsort_t {
                        SWAP1((i) * buf->ts, (j) * buf->ts, t, buf->ts); \
        } while (0)
 #define GDKqsort_impl GDKqsort_impl_any
+#define INITIALIZER    int z
 #define CMP(i, j)      (buf->base ?                                    \
                         (*buf->cmp)(OFF(h, i),                         \
                                     OFF(h, j)) :                       \
                         (*buf->cmp)(h + (i) * buf->hs,                 \
                                     h + (j) * buf->hs))
-#define EQ(i, j)       (CMP(i, j) == 0)
-#define LE(i, j)       (CMP(i, j) <= 0)
+/* EQ is only ever called directly after LE with the same arguments */
+#define EQ(i, j)       (z == 0)
+#define LE(i, j)       ((z = CMP(i, j)) <= 0)
 #define LT(i, j)       (CMP(i, j) < 0)
 #include "gdk_qsort_impl.h"
 #undef GDKqsort_impl
@@ -257,7 +258,7 @@ struct qsort_t {
 #undef LT
 
 #define GDKqsort_impl GDKqsort_impl_any_rev
-#define LE(i, j)       (CMP(i, j) >= 0)
+#define LE(i, j)       ((z = CMP(i, j)) >= 0)
 #define LT(i, j)       (CMP(i, j) > 0)
 #include "gdk_qsort_impl.h"
 #undef GDKqsort_impl
diff --git a/gdk/gdk_qsort_impl.h b/gdk/gdk_qsort_impl.h
--- a/gdk/gdk_qsort_impl.h
+++ b/gdk/gdk_qsort_impl.h
@@ -66,6 +66,9 @@ GDKqsort_impl(struct qsort_t *buf, char 
        size_t a, b, c, d;
        size_t r;
        int swap_cnt;
+#ifdef INITIALIZER
+       INITIALIZER;
+#endif
 
   loop:
        if (n < 7) {
@@ -84,21 +87,22 @@ GDKqsort_impl(struct qsort_t *buf, char 
                /* for larger arrays, take the middle value from the
                 * first, middle, and last */
                a = 0;
-               r = n - 1;
+               c = n - 1;
                if (n > 40) {
                        /* for even larger arrays, take the middle
                         * value of three middle values */
                        d = n >> 3;
                        a = MED3(a, a + d, a + 2 * d);
                        b = MED3(b - d, b, b + d);
-                       r = MED3(r - 2 * d, r - d, r);
+                       c = MED3(c - 2 * d, c - d, c);
                }
-               b = MED3(a, b, r);
+               b = MED3(a, b, c);
        }
        /* move pivot to start */
-       SWAP(0, b);
+       if (b != 0)
+               SWAP(0, b);
 
-       /* Bentley's and McIlroy's implementation of Dijkstra's Dutch
+       /* Bentley and McIlroy's implementation of Dijkstra's Dutch
         * National Flag Problem */
        a = b = 1;
        c = d = n - 1;
@@ -155,25 +159,39 @@ GDKqsort_impl(struct qsort_t *buf, char 
        multi_SWAP(b, n - r, r);
        /* at this point we have:
         * b == c + 1
-        * [0..b-a): values less than pivot
-        * [b-a..n-(d-c)): values equal to pivot ((b-a)+(d-c) in total)
-        * [n-(d-c)..n): values larger than pivot
+        * [0..b-a): values less than pivot (to be sorted)
+        * [b-a..n-(d-c)): values equal to pivot (in place)
+        * [n-(d-c)..n): values larger than pivot (to be sorted)
         */
-       if ((r = b - a) > 1) {
-               /* sort values less than pivot */
-               GDKqsort_impl(buf, h, t, r);
-       }
-       if ((r = d - c) > 1) {
-               /* sort values greater than pivot */
-#if 0
-               GDKqsort_impl(buf, h + (n - r) * buf->hs, t && buf->ts ? t + (n 
- r) * buf->ts : NULL, r);
-#else
-               /* iterate rather than recurse */
-               h += (n - r) * buf->hs;
-               if (t && buf->ts)
-                       t += (n - r) * buf->ts;
-               n = r;
-               goto loop;
-#endif
+
+       /* use recursion for smaller of the two subarrays, loop back
+        * to start for larger of the two */
+       if (b - a < d - c) {
+               if ((r = b - a) > 1) {
+                       /* sort values less than pivot */
+                       GDKqsort_impl(buf, h, t, r);
+               }
+               if ((r = d - c) > 1) {
+                       /* sort values greater than pivot
+                        * iterate rather than recurse */
+                       h += (n - r) * buf->hs;
+                       if (t && buf->ts)
+                               t += (n - r) * buf->ts;
+                       n = r;
+                       goto loop;
+               }
+       } else {
+               if ((r = d - c) > 1) {
+                       /* sort values greater than pivot */
+                       GDKqsort_impl(buf, h + (n - r) * buf->hs,
+                                     t ? t + (n - r) * buf->ts : NULL,
+                                     r);
+               }
+               if ((r = b - a) > 1) {
+                       /* sort values less than pivot
+                        * iterate rather than recurse */
+                       n = r;
+                       goto loop;
+               }
        }
 }
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to