LCOV - code coverage report
Current view: top level - gdk - gdk_qsort.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 115 130 88.5 %
Date: 2024-10-07 21:21:43 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "gdk.h"
      15             : #include "gdk_private.h"
      16             : 
      17             : struct qsort_t {
      18             :         unsigned int hs;
      19             :         unsigned int ts;
      20             :         int (*cmp)(const void *, const void *);
      21             :         const char *base;
      22             :         const void *nil;
      23             : };
      24             : 
      25             : #define glue(a, b, c)           a ## b ## c
      26             : #define CONCAT2(a, b)           a ## b
      27             : #define CONCAT3(a, b, c)        glue(a, b, c)
      28             : 
      29             : /* nil is smallest value, i.e. first for ascending, last for descending */
      30             : #define fixltf(i, j, TPE)       (((TPE *) h)[i] < ((TPE *) h)[j])
      31             : #define fixlef(i, j, TPE)       (((TPE *) h)[i] <= ((TPE *) h)[j])
      32             : #define fixgtl(i, j, TPE)       (((TPE *) h)[i] > ((TPE *) h)[j])
      33             : #define fixgel(i, j, TPE)       (((TPE *) h)[i] >= ((TPE *) h)[j])
      34             : 
      35             : /* nil is largest value, i.e. last for ascending, first for descending */
      36             : #define fixltl(i, j, TPE)       (!fixnil(i, TPE) && (fixnil(j, TPE) || ((TPE *) h)[i] < ((TPE *) h)[j]))
      37             : #define fixlel(i, j, TPE)       (fixnil(j, TPE) || (!fixnil(i, TPE) && ((TPE *) h)[i] <= ((TPE *) h)[j]))
      38             : #define fixgtf(i, j, TPE)       (!fixnil(j, TPE) && (fixnil(i, TPE) || ((TPE *) h)[i] > ((TPE *) h)[j]))
      39             : #define fixgef(i, j, TPE)       (fixnil(i, TPE) || (!fixnil(j, TPE) && ((TPE *) h)[i] >= ((TPE *) h)[j]))
      40             : 
      41             : #define fixeq(i, j, TPE)        (((TPE *) h)[i] == ((TPE *) h)[j])
      42             : #define fixnil(i, TPE)          is_##TPE##_nil(((TPE *) h)[i])
      43             : #define fixswap(i, j, TPE)                                              \
      44             :         do {                                                            \
      45             :                 TPE _t = ((TPE *) h)[i];                                \
      46             :                 ((TPE *) h)[i] = ((TPE *) h)[j];                        \
      47             :                 ((TPE *) h)[j] = _t;                                    \
      48             :                 if (t)                                                  \
      49             :                         SWAP1((i) * buf->ts, (j) * buf->ts, t, buf->ts); \
      50             :         } while (0)
      51             : 
      52             : #define bteltf(i, j)            fixltf(i, j, bte)
      53             : #define btelef(i, j)            fixlef(i, j, bte)
      54             : #define bteltl(i, j)            fixltl(i, j, bte)
      55             : #define btelel(i, j)            fixlel(i, j, bte)
      56             : #define bteltl_rev(i, j)        fixgtl(i, j, bte)
      57             : #define btelel_rev(i, j)        fixgel(i, j, bte)
      58             : #define bteltf_rev(i, j)        fixgtf(i, j, bte)
      59             : #define btelef_rev(i, j)        fixgef(i, j, bte)
      60             : #define bteeq(i, j)             fixeq(i, j, bte)
      61             : #define btenil(i)               fixnil(i, bte)
      62             : #define bteswap(i, j)           fixswap(i, j, bte)
      63             : 
      64             : #define shtltf(i, j)            fixltf(i, j, sht)
      65             : #define shtlef(i, j)            fixlef(i, j, sht)
      66             : #define shtltl(i, j)            fixltl(i, j, sht)
      67             : #define shtlel(i, j)            fixlel(i, j, sht)
      68             : #define shtltl_rev(i, j)        fixgtl(i, j, sht)
      69             : #define shtlel_rev(i, j)        fixgel(i, j, sht)
      70             : #define shtltf_rev(i, j)        fixgtf(i, j, sht)
      71             : #define shtlef_rev(i, j)        fixgef(i, j, sht)
      72             : #define shteq(i, j)             fixeq(i, j, sht)
      73             : #define shtnil(i)               fixnil(i, sht)
      74             : #define shtswap(i, j)           fixswap(i, j, sht)
      75             : 
      76             : #define intltf(i, j)            fixltf(i, j, int)
      77             : #define intlef(i, j)            fixlef(i, j, int)
      78             : #define intltl(i, j)            fixltl(i, j, int)
      79             : #define intlel(i, j)            fixlel(i, j, int)
      80             : #define intltl_rev(i, j)        fixgtl(i, j, int)
      81             : #define intlel_rev(i, j)        fixgel(i, j, int)
      82             : #define intltf_rev(i, j)        fixgtf(i, j, int)
      83             : #define intlef_rev(i, j)        fixgef(i, j, int)
      84             : #define inteq(i, j)             fixeq(i, j, int)
      85             : #define intnil(i)               fixnil(i, int)
      86             : #define intswap(i, j)           fixswap(i, j, int)
      87             : 
      88             : #define lngltf(i, j)            fixltf(i, j, lng)
      89             : #define lnglef(i, j)            fixlef(i, j, lng)
      90             : #define lngltl(i, j)            fixltl(i, j, lng)
      91             : #define lnglel(i, j)            fixlel(i, j, lng)
      92             : #define lngltl_rev(i, j)        fixgtl(i, j, lng)
      93             : #define lnglel_rev(i, j)        fixgel(i, j, lng)
      94             : #define lngltf_rev(i, j)        fixgtf(i, j, lng)
      95             : #define lnglef_rev(i, j)        fixgef(i, j, lng)
      96             : #define lngeq(i, j)             fixeq(i, j, lng)
      97             : #define lngnil(i)               fixnil(i, lng)
      98             : #define lngswap(i, j)           fixswap(i, j, lng)
      99             : 
     100             : #define hgeltf(i, j)            fixltf(i, j, hge)
     101             : #define hgelef(i, j)            fixlef(i, j, hge)
     102             : #define hgeltl(i, j)            fixltl(i, j, hge)
     103             : #define hgelel(i, j)            fixlel(i, j, hge)
     104             : #define hgeltl_rev(i, j)        fixgtl(i, j, hge)
     105             : #define hgelel_rev(i, j)        fixgel(i, j, hge)
     106             : #define hgeltf_rev(i, j)        fixgtf(i, j, hge)
     107             : #define hgelef_rev(i, j)        fixgef(i, j, hge)
     108             : #define hgeeq(i, j)             fixeq(i, j, hge)
     109             : #define hgenil(i)               fixnil(i, hge)
     110             : #define hgeswap(i, j)           fixswap(i, j, hge)
     111             : 
     112             : #define fltltf(i, j)            (!fltnil(j) && (fltnil(i) || fixltf(i, j, flt)))
     113             : #define fltlef(i, j)            (fltnil(i) || (!fltnil(j) && fixlef(i, j, flt)))
     114             : #define fltltl(i, j)            fixltl(i, j, flt)
     115             : #define fltlel(i, j)            fixlel(i, j, flt)
     116             : #define fltltl_rev(i, j)        (!fltnil(i) && (fltnil(j) || fixgtl(i, j, flt)))
     117             : #define fltlel_rev(i, j)        (fltnil(j) || (!fltnil(i) && fixgel(i, j, flt)))
     118             : #define fltltf_rev(i, j)        fixgtf(i, j, flt)
     119             : #define fltlef_rev(i, j)        fixgef(i, j, flt)
     120             : #define flteq(i, j)             (fltnil(i) ? fltnil(j) : !fltnil(j) && fixeq(i, j, flt))
     121             : #define fltnil(i)               fixnil(i, flt)
     122             : #define fltswap(i, j)           fixswap(i, j, flt)
     123             : 
     124             : #define dblltf(i, j)            (!dblnil(j) && (dblnil(i) || fixltf(i, j, dbl)))
     125             : #define dbllef(i, j)            (dblnil(i) || (!dblnil(j) && fixlef(i, j, dbl)))
     126             : #define dblltl(i, j)            fixltl(i, j, dbl)
     127             : #define dbllel(i, j)            fixlel(i, j, dbl)
     128             : #define dblltl_rev(i, j)        (!dblnil(i) && (dblnil(j) || fixgtl(i, j, dbl)))
     129             : #define dbllel_rev(i, j)        (dblnil(j) || (!dblnil(i) && fixgel(i, j, dbl)))
     130             : #define dblltf_rev(i, j)        fixgtf(i, j, dbl)
     131             : #define dbllef_rev(i, j)        fixgef(i, j, dbl)
     132             : #define dbleq(i, j)             (dblnil(i) ? dblnil(j) : !dblnil(j) && fixeq(i, j, dbl))
     133             : #define dblnil(i)               fixnil(i, dbl)
     134             : #define dblswap(i, j)           fixswap(i, j, dbl)
     135             : 
     136             : #define anyCMP(i, j)            (*buf->cmp)(h + (i)*buf->hs, h + (j)*buf->hs)
     137             : #define anyltf(i, j)            (anyCMP(i, j) < 0)
     138             : #define anylef(i, j)            (anyCMP(i, j) <= 0)
     139             : #define anyltl(i, j)            (!anynil(i) && (anynil(j) || anyCMP(i, j) < 0))
     140             : #define anylel(i, j)            (anynil(j) || (!anynil(i) && anyCMP(i, j) <= 0))
     141             : #define anyltl_rev(i, j)        (anyCMP(i, j) > 0)
     142             : #define anylel_rev(i, j)        (anyCMP(i, j) >= 0)
     143             : #define anyltf_rev(i, j)        (!anynil(j) && (anynil(i) || anyCMP(i, j) > 0))
     144             : #define anylef_rev(i, j)        (anynil(i) || (!anynil(j) && anyCMP(i, j) >= 0))
     145             : #define anyeq(i, j)             (anyCMP(i, j) == 0)
     146             : #define anynil(i)               ((*buf->cmp)(h + (i)*buf->hs, buf->nil) == 0)
     147             : #define anyswap(i, j)                                                   \
     148             :         do {                                                            \
     149             :                 SWAP1((i) * buf->hs, (j) * buf->hs, h, buf->hs);       \
     150             :                 if (t)                                                  \
     151             :                         SWAP1((i) * buf->ts, (j) * buf->ts, t, buf->ts); \
     152             :         } while (0)
     153             : 
     154             : #define varOFF(i)               (buf->base + VarHeapVal(h, i, buf->hs))
     155             : #define varCMP(i, j)            (*buf->cmp)(varOFF(i), varOFF(j))
     156             : #define varltf(i, j)            (varCMP(i, j) < 0)
     157             : #define varlef(i, j)            (varCMP(i, j) <= 0)
     158             : #define varltl(i, j)            (!varnil(i) && (varnil(j) || varCMP(i, j) < 0))
     159             : #define varlel(i, j)            (varnil(j) || (!varnil(i) && varCMP(i, j) <= 0))
     160             : #define varltl_rev(i, j)        (varCMP(i, j) > 0)
     161             : #define varlel_rev(i, j)        (varCMP(i, j) >= 0)
     162             : #define varltf_rev(i, j)        (!varnil(j) && (varnil(i) || varCMP(i, j) > 0))
     163             : #define varlef_rev(i, j)        (varnil(i) || (!varnil(j) && varCMP(i, j) >= 0))
     164             : #define vareq(i, j)             (varCMP(i, j) == 0)
     165             : #define varnil(i)               ((*buf->cmp)(varOFF(i), buf->nil) == 0)
     166             : #define varswap(i, j)           anyswap(i, j)
     167             : 
     168             : #define LE(i, j, TPE, SUFF)     CONCAT3(TPE, le, SUFF)(i, j)
     169             : #define LT(i, j, TPE, SUFF)     CONCAT3(TPE, lt, SUFF)(i, j)
     170             : #define EQ(i, j, TPE)           CONCAT2(TPE, eq)(i, j)
     171             : #define SWAP(i, j, TPE)         CONCAT2(TPE, swap)(i, j)
     172             : 
     173             : /* return index of middle value at indexes a, b, and c */
     174             : #define MED3(a, b, c, TPE, SUFF)        (LT(a, b, TPE, SUFF)            \
     175             :                                          ? (LT(b, c, TPE, SUFF)         \
     176             :                                             ? (b)                       \
     177             :                                             : (LT(a, c, TPE, SUFF)      \
     178             :                                                ? (c)                    \
     179             :                                                : (a)))                  \
     180             :                                          : (LT(c, b, TPE, SUFF)         \
     181             :                                             ? (b)                       \
     182             :                                             : (LT(a, c, TPE, SUFF)      \
     183             :                                                ? (a)                    \
     184             :                                                : (c))))
     185             : 
     186             : /* generic swap: swap w bytes starting at indexes i and j with each
     187             :  * other from the array given by b */
     188             : #define SWAP1(i, j, b, w)                                               \
     189             :         do {                                                            \
     190             :                 for (size_t _z = (w), _i = (i), _j = (j); _z > 0; _z--) { \
     191             :                         char _tmp = b[_i];                              \
     192             :                         b[_i++] = b[_j];                                \
     193             :                         b[_j++] = _tmp;                                 \
     194             :                 }                                                       \
     195             :         } while (0)
     196             : /* swap n items from both h and t arrays starting at indexes i and j */
     197             : #define multi_SWAP(i, j, n)                                             \
     198             :         do {                                                            \
     199             :                 SWAP1((i) * buf->hs, (j) * buf->hs, h, n * buf->hs);   \
     200             :                 if (t)                                                  \
     201             :                         SWAP1((i) * buf->ts, (j) * buf->ts, t, n * buf->ts); \
     202             :         } while (0)
     203             : 
     204             : /* From here we define and redefine tokens and include the
     205             :  * implementation file multiple times to get versions for different
     206             :  * types and to get both ascending and descending (reverse) sort.
     207             :  * Note that for reverse sort, the LE (less or equal) and LT (less
     208             :  * than) macros are in fact greater or equal and greater than.  */
     209             : 
     210             : #define TPE bte
     211             : #define SUFF f
     212             : #include "gdk_qsort_impl.h"
     213             : #undef SUFF
     214             : #define SUFF l
     215             : #include "gdk_qsort_impl.h"
     216             : #undef SUFF
     217             : #define SUFF l_rev
     218             : #include "gdk_qsort_impl.h"
     219             : #undef SUFF
     220             : #define SUFF f_rev
     221             : #include "gdk_qsort_impl.h"
     222             : #undef SUFF
     223             : #undef TPE
     224             : 
     225             : #define TPE sht
     226             : #define SUFF f
     227             : #include "gdk_qsort_impl.h"
     228             : #undef SUFF
     229             : #define SUFF l
     230             : #include "gdk_qsort_impl.h"
     231             : #undef SUFF
     232             : #define SUFF l_rev
     233             : #include "gdk_qsort_impl.h"
     234             : #undef SUFF
     235             : #define SUFF f_rev
     236             : #include "gdk_qsort_impl.h"
     237             : #undef SUFF
     238             : #undef TPE
     239             : 
     240             : #define TPE int
     241             : #define SUFF f
     242             : #include "gdk_qsort_impl.h"
     243             : #undef SUFF
     244             : #define SUFF l
     245             : #include "gdk_qsort_impl.h"
     246             : #undef SUFF
     247             : #define SUFF l_rev
     248             : #include "gdk_qsort_impl.h"
     249             : #undef SUFF
     250             : #define SUFF f_rev
     251             : #include "gdk_qsort_impl.h"
     252             : #undef SUFF
     253             : #undef TPE
     254             : 
     255             : #define TPE lng
     256             : #define SUFF f
     257             : #include "gdk_qsort_impl.h"
     258             : #undef SUFF
     259             : #define SUFF l
     260             : #include "gdk_qsort_impl.h"
     261             : #undef SUFF
     262             : #define SUFF l_rev
     263             : #include "gdk_qsort_impl.h"
     264             : #undef SUFF
     265             : #define SUFF f_rev
     266             : #include "gdk_qsort_impl.h"
     267             : #undef SUFF
     268             : #undef TPE
     269             : 
     270             : #ifdef HAVE_HGE
     271             : #define TPE hge
     272             : #define SUFF f
     273             : #include "gdk_qsort_impl.h"
     274             : #undef SUFF
     275             : #define SUFF l
     276             : #include "gdk_qsort_impl.h"
     277             : #undef SUFF
     278             : #define SUFF l_rev
     279             : #include "gdk_qsort_impl.h"
     280             : #undef SUFF
     281             : #define SUFF f_rev
     282             : #include "gdk_qsort_impl.h"
     283             : #undef SUFF
     284             : #undef TPE
     285             : #endif
     286             : 
     287             : #define TPE flt
     288             : #define SUFF f
     289             : #include "gdk_qsort_impl.h"
     290             : #undef SUFF
     291             : #define SUFF l
     292             : #include "gdk_qsort_impl.h"
     293             : #undef SUFF
     294             : #define SUFF l_rev
     295             : #include "gdk_qsort_impl.h"
     296             : #undef SUFF
     297             : #define SUFF f_rev
     298             : #include "gdk_qsort_impl.h"
     299             : #undef SUFF
     300             : #undef TPE
     301             : 
     302             : #define TPE dbl
     303             : #define SUFF f
     304             : #include "gdk_qsort_impl.h"
     305             : #undef SUFF
     306             : #define SUFF l
     307             : #include "gdk_qsort_impl.h"
     308             : #undef SUFF
     309             : #define SUFF l_rev
     310             : #include "gdk_qsort_impl.h"
     311             : #undef SUFF
     312             : #define SUFF f_rev
     313             : #include "gdk_qsort_impl.h"
     314             : #undef SUFF
     315             : #undef TPE
     316             : 
     317             : #define TPE any
     318             : #define SUFF f
     319             : #include "gdk_qsort_impl.h"
     320             : #undef SUFF
     321             : #define SUFF l
     322             : #include "gdk_qsort_impl.h"
     323             : #undef SUFF
     324             : #define SUFF l_rev
     325             : #include "gdk_qsort_impl.h"
     326             : #undef SUFF
     327             : #define SUFF f_rev
     328             : #include "gdk_qsort_impl.h"
     329             : #undef SUFF
     330             : #undef TPE
     331             : 
     332             : #define TPE var
     333             : #define SUFF f
     334             : #include "gdk_qsort_impl.h"
     335             : #undef SUFF
     336             : #define SUFF l
     337             : #include "gdk_qsort_impl.h"
     338             : #undef SUFF
     339             : #define SUFF l_rev
     340             : #include "gdk_qsort_impl.h"
     341             : #undef SUFF
     342             : #define SUFF f_rev
     343             : #include "gdk_qsort_impl.h"
     344             : #undef SUFF
     345             : #undef TPE
     346             : 
     347             : /* Sort the array `h' of `n' elements with size `hs' each and type
     348             :  * `ts' in ascending or descending (if `reverse' is true) order.  If
     349             :  * the type `tpe' indicates a variable-sized type, `h' contains
     350             :  * offsets into the `base' array which should be NULL otherwise.  The
     351             :  * array `t', if not NULL, contains `n' values of size `ts' each which
     352             :  * will be moved around together with the corresponding elements in
     353             :  * `h' (i.e. `t' is the payload).  If `nilslast' is true, nils sort at
     354             :  * the end, otherwise at the beginning of the result.
     355             :  *
     356             :  * This function uses a variant of quicksort and is thus not a stable
     357             :  * sort. */
     358             : void
     359     3020242 : GDKqsort(void *restrict h, void *restrict t, const void *restrict base,
     360             :          size_t n, int hs, int ts, int tpe, bool reverse, bool nilslast)
     361             : {
     362     3020242 :         struct qsort_t buf;
     363             : 
     364     3020242 :         assert(hs > 0);
     365     3020242 :         assert(ts >= 0);
     366     3020242 :         assert(tpe != TYPE_void);
     367     3020242 :         assert((ts == 0) == (t == NULL));
     368             : 
     369     3020242 :         if (n <= 1)
     370       47568 :                 return;         /* nothing to do */
     371             : 
     372     3019469 :         buf.hs = (unsigned int) hs;
     373     3019469 :         buf.ts = (unsigned int) ts;
     374     3019469 :         buf.cmp = ATOMcompare(tpe);
     375     3019469 :         buf.base = base;
     376     3019469 :         buf.nil = ATOMnilptr(tpe);
     377     3019469 :         assert(ATOMvarsized(tpe) ? base != NULL : base == NULL);
     378             : 
     379     3019469 :         tpe = ATOMbasetype(tpe);
     380             : 
     381     3019469 :         if (reverse) {
     382      286377 :                 if (nilslast) {
     383             :                         /* "normal" descending sort order, i.e. with
     384             :                          * NILs as smallest value, so they come
     385             :                          * last */
     386      286319 :                         if (ATOMvarsized(tpe)) {
     387          94 :                                 GDKqsort_impl_varl_rev(&buf, h, t, n);
     388          94 :                                 return;
     389             :                         }
     390      286225 :                         switch (tpe) {
     391        1008 :                         case TYPE_bte:
     392        1008 :                                 GDKqsort_impl_btel_rev(&buf, h, t, n);
     393        1008 :                                 break;
     394           7 :                         case TYPE_sht:
     395           7 :                                 GDKqsort_impl_shtl_rev(&buf, h, t, n);
     396           7 :                                 break;
     397      284928 :                         case TYPE_int:
     398      284928 :                                 GDKqsort_impl_intl_rev(&buf, h, t, n);
     399      284928 :                                 break;
     400         117 :                         case TYPE_lng:
     401         117 :                                 GDKqsort_impl_lngl_rev(&buf, h, t, n);
     402         117 :                                 break;
     403             : #ifdef HAVE_HGE
     404         126 :                         case TYPE_hge:
     405         126 :                                 GDKqsort_impl_hgel_rev(&buf, h, t, n);
     406         126 :                                 break;
     407             : #endif
     408           8 :                         case TYPE_flt:
     409           8 :                                 GDKqsort_impl_fltl_rev(&buf, h, t, n);
     410           8 :                                 break;
     411          25 :                         case TYPE_dbl:
     412          25 :                                 GDKqsort_impl_dbll_rev(&buf, h, t, n);
     413          25 :                                 break;
     414           6 :                         default:
     415           6 :                                 GDKqsort_impl_anyl_rev(&buf, h, t, n);
     416           6 :                                 break;
     417             :                         }
     418             :                 } else {
     419          58 :                         if (ATOMvarsized(tpe)) {
     420          10 :                                 GDKqsort_impl_varf_rev(&buf, h, t, n);
     421          10 :                                 return;
     422             :                         }
     423          48 :                         switch (tpe) {
     424          20 :                         case TYPE_bte:
     425          20 :                                 GDKqsort_impl_btef_rev(&buf, h, t, n);
     426          20 :                                 break;
     427           0 :                         case TYPE_sht:
     428           0 :                                 GDKqsort_impl_shtf_rev(&buf, h, t, n);
     429           0 :                                 break;
     430           4 :                         case TYPE_int:
     431           4 :                                 GDKqsort_impl_intf_rev(&buf, h, t, n);
     432           4 :                                 break;
     433          16 :                         case TYPE_lng:
     434          16 :                                 GDKqsort_impl_lngf_rev(&buf, h, t, n);
     435          16 :                                 break;
     436             : #ifdef HAVE_HGE
     437           1 :                         case TYPE_hge:
     438           1 :                                 GDKqsort_impl_hgef_rev(&buf, h, t, n);
     439           1 :                                 break;
     440             : #endif
     441           4 :                         case TYPE_flt:
     442           4 :                                 GDKqsort_impl_fltf_rev(&buf, h, t, n);
     443           4 :                                 break;
     444           3 :                         case TYPE_dbl:
     445           3 :                                 GDKqsort_impl_dblf_rev(&buf, h, t, n);
     446           3 :                                 break;
     447           0 :                         default:
     448           0 :                                 GDKqsort_impl_anyf_rev(&buf, h, t, n);
     449           0 :                                 break;
     450             :                         }
     451             :                 }
     452             :         } else {
     453     2733092 :                 if (nilslast) {
     454        2095 :                         if (ATOMvarsized(tpe)) {
     455          11 :                                 GDKqsort_impl_varl(&buf, h, t, n);
     456          11 :                                 return;
     457             :                         }
     458        2084 :                         switch (tpe) {
     459          29 :                         case TYPE_bte:
     460          29 :                                 GDKqsort_impl_btel(&buf, h, t, n);
     461          29 :                                 break;
     462           0 :                         case TYPE_sht:
     463           0 :                                 GDKqsort_impl_shtl(&buf, h, t, n);
     464           0 :                                 break;
     465        2037 :                         case TYPE_int:
     466        2037 :                                 GDKqsort_impl_intl(&buf, h, t, n);
     467        2037 :                                 break;
     468          13 :                         case TYPE_lng:
     469          13 :                                 GDKqsort_impl_lngl(&buf, h, t, n);
     470          13 :                                 break;
     471             : #ifdef HAVE_HGE
     472           0 :                         case TYPE_hge:
     473           0 :                                 GDKqsort_impl_hgel(&buf, h, t, n);
     474           0 :                                 break;
     475             : #endif
     476           3 :                         case TYPE_flt:
     477           3 :                                 GDKqsort_impl_fltl(&buf, h, t, n);
     478           3 :                                 break;
     479           2 :                         case TYPE_dbl:
     480           2 :                                 GDKqsort_impl_dbll(&buf, h, t, n);
     481           2 :                                 break;
     482           0 :                         default:
     483           0 :                                 GDKqsort_impl_anyl(&buf, h, t, n);
     484           0 :                                 break;
     485             :                         }
     486             :                 } else {
     487             :                         /* "normal" ascending sort order, i.e. with
     488             :                          * NILs as smallest value, so they come
     489             :                          * first */
     490     2730997 :                         if (ATOMvarsized(tpe)) {
     491       46743 :                                 GDKqsort_impl_varf(&buf, h, t, n);
     492       46743 :                                 return;
     493             :                         }
     494     2684254 :                         switch (tpe) {
     495        3064 :                         case TYPE_bte:
     496        3064 :                                 GDKqsort_impl_btef(&buf, h, t, n);
     497        3064 :                                 break;
     498         915 :                         case TYPE_sht:
     499         915 :                                 GDKqsort_impl_shtf(&buf, h, t, n);
     500         915 :                                 break;
     501     2675062 :                         case TYPE_int:
     502     2675062 :                                 GDKqsort_impl_intf(&buf, h, t, n);
     503     2675062 :                                 break;
     504        4820 :                         case TYPE_lng:
     505        4820 :                                 GDKqsort_impl_lngf(&buf, h, t, n);
     506        4820 :                                 break;
     507             : #ifdef HAVE_HGE
     508         249 :                         case TYPE_hge:
     509         249 :                                 GDKqsort_impl_hgef(&buf, h, t, n);
     510         249 :                                 break;
     511             : #endif
     512          21 :                         case TYPE_flt:
     513          21 :                                 GDKqsort_impl_fltf(&buf, h, t, n);
     514          21 :                                 break;
     515         119 :                         case TYPE_dbl:
     516         119 :                                 GDKqsort_impl_dblf(&buf, h, t, n);
     517         119 :                                 break;
     518           4 :                         default:
     519           4 :                                 GDKqsort_impl_anyf(&buf, h, t, n);
     520           4 :                                 break;
     521             :                         }
     522             :                 }
     523             :         }
     524             : }

Generated by: LCOV version 1.14