LCOV - code coverage report
Current view: top level - gdk - gdk_cand.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 728 994 73.2 %
Date: 2024-11-15 19:37:45 Functions: 24 25 96.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             : #include "gdk_cand.h"
      17             : 
      18             : bool
      19        9627 : BATiscand(BAT *b)
      20             : {
      21        9627 :         if (ATOMtype(b->ttype) != TYPE_oid)
      22             :                 return false;
      23        9627 :         if (complex_cand(b))
      24             :                 return true;
      25        9453 :         if (b->ttype == TYPE_void && is_oid_nil(b->tseqbase))
      26             :                 return false;
      27       18905 :         return b->tsorted && BATtkey(b);
      28             : }
      29             : 
      30             : /* create a new, dense candidate list with values from `first' up to,
      31             :  * but not including, `last' */
      32             : static inline BAT *
      33       10168 : newdensecand(oid first, oid last)
      34             : {
      35       10168 :         if (last <= first)
      36           0 :                 first = last = 0; /* empty range */
      37       10168 :         return BATdense(0, first, last - first);
      38             : }
      39             : 
      40             : /* merge two candidate lists and produce a new one
      41             :  *
      42             :  * candidate lists are VOID-headed BATs with an OID tail which is
      43             :  * sorted and unique.
      44             :  */
      45             : BAT *
      46      114063 : BATmergecand(BAT *a, BAT *b)
      47             : {
      48      114063 :         BAT *bn;
      49      114063 :         oid *restrict p, i;
      50      114063 :         struct canditer cia, cib;
      51             : 
      52      114063 :         BATcheck(a, NULL);
      53      114063 :         BATcheck(b, NULL);
      54             : 
      55      114063 :         canditer_init(&cia, NULL, a);
      56      113832 :         canditer_init(&cib, NULL, b);
      57             : 
      58             :         /* we can return a if b is empty (and v.v.) */
      59      114103 :         if (cia.ncand == 0) {
      60       36632 :                 bn = canditer_slice(&cib, 0, cib.ncand);
      61       36600 :                 goto doreturn;
      62             :         }
      63       77471 :         if (cib.ncand == 0) {
      64       18909 :                 bn = canditer_slice(&cia, 0, cia.ncand);
      65       18921 :                 goto doreturn;
      66             :         }
      67             :         /* we can return a if a fully covers b (and v.v) */
      68       58562 :         if (cia.tpe == cand_dense && cib.tpe == cand_dense) {
      69             :                 /* both are dense */
      70       18064 :                 if (cia.seq <= cib.seq && cib.seq <= cia.seq + cia.ncand) {
      71             :                         /* partial overlap starting with a, or b is
      72             :                          * smack bang after a */
      73        7577 :                         bn = newdensecand(cia.seq, cia.seq + cia.ncand < cib.seq + cib.ncand ? cib.seq + cib.ncand : cia.seq + cia.ncand);
      74        7587 :                         goto doreturn;
      75             :                 }
      76       10487 :                 if (cib.seq <= cia.seq && cia.seq <= cib.seq + cib.ncand) {
      77             :                         /* partial overlap starting with b, or a is
      78             :                          * smack bang after b */
      79        2593 :                         bn = newdensecand(cib.seq, cia.seq + cia.ncand < cib.seq + cib.ncand ? cib.seq + cib.ncand : cia.seq + cia.ncand);
      80        2593 :                         goto doreturn;
      81             :                 }
      82             :         }
      83       48392 :         if (cia.tpe == cand_dense
      84        9962 :             && cia.seq <= cib.seq
      85        4375 :             && canditer_last(&cia) >= canditer_last(&cib)) {
      86         220 :                 bn = canditer_slice(&cia, 0, cia.ncand);
      87         220 :                 goto doreturn;
      88             :         }
      89       48172 :         if (cib.tpe == cand_dense
      90       35674 :             && cib.seq <= cia.seq
      91       10326 :             && canditer_last(&cib) >= canditer_last(&cia)) {
      92         172 :                 bn = canditer_slice(&cib, 0, cib.ncand);
      93         172 :                 goto doreturn;
      94             :         }
      95             : 
      96       48000 :         bn = COLnew(0, TYPE_oid, cia.ncand + cib.ncand, TRANSIENT);
      97       47974 :         if (bn == NULL)
      98           0 :                 goto doreturn;
      99       47974 :         p = (oid *) Tloc(bn, 0);
     100       47974 :         if (cia.tpe == cand_dense && cib.tpe == cand_dense) {
     101             :                 /* both lists are dense */
     102        7895 :                 if (cia.seq > cib.seq) {
     103        4184 :                         struct canditer ci;
     104        4184 :                         ci = cia;
     105        4184 :                         cia = cib;
     106        4184 :                         cib = ci;
     107             :                 }
     108             :                 /* cia completely before cib */
     109        7895 :                 assert(cia.seq + cia.ncand < cib.seq);
     110       30256 :                 for (i = cia.seq; i < cia.seq + cia.ncand; i++)
     111       22361 :                         *p++ = i;
     112             :                 /* there is a gap */
     113       26656 :                 for (i = cib.seq; i < cib.seq + cib.ncand; i++)
     114       18761 :                         *p++ = i;
     115       40079 :         } else if (cia.tpe == cand_dense || cib.tpe == cand_dense) {
     116       29433 :                 if (cib.tpe == cand_dense) {
     117       27665 :                         struct canditer ci;
     118       27665 :                         ci = cia;
     119       27665 :                         cia = cib;
     120       27665 :                         cib = ci;
     121             :                 }
     122             :                 /* only cia is dense */
     123             : 
     124             :                 /* copy part of cib that's before the start of cia */
     125      115741 :                 while (canditer_peek(&cib) < cia.seq) {
     126       86238 :                         *p++ = canditer_next(&cib);
     127             :                 }
     128             :                 /* copy all of cia */
     129       66708 :                 for (i = cia.seq; i < cia.seq + cia.ncand; i++)
     130       37205 :                         *p++ = i;
     131             :                 /* skip over part of cib that overlaps with cia */
     132       29503 :                 canditer_setidx(&cib, canditer_search(&cib, cia.seq + cia.ncand, true));
     133             :                 /* copy rest of cib */
     134      111249 :                 while (cib.next < cib.ncand) {
     135       81669 :                         *p++ = canditer_next(&cib);
     136             :                 }
     137             :         } else {
     138             :                 /* a and b are both not dense */
     139       10646 :                 oid ao = canditer_next(&cia);
     140       10641 :                 oid bo = canditer_next(&cib);
     141    22748826 :                 while (!is_oid_nil(ao) && !is_oid_nil(bo)) {
     142    22738179 :                         if (ao < bo) {
     143    13138575 :                                 *p++ = ao;
     144    13138575 :                                 ao = canditer_next(&cia);
     145     9599604 :                         } else if (bo < ao) {
     146     8567547 :                                 *p++ = bo;
     147     8567547 :                                 bo = canditer_next(&cib);
     148             :                         } else {
     149     1032057 :                                 *p++ = ao;
     150     1032057 :                                 ao = canditer_next(&cia);
     151     1032071 :                                 bo = canditer_next(&cib);
     152             :                         }
     153             :                 }
     154      546927 :                 while (!is_oid_nil(ao)) {
     155      536280 :                         *p++ = ao;
     156      536280 :                         ao = canditer_next(&cia);
     157             :                 }
     158      415050 :                 while (!is_oid_nil(bo)) {
     159      404404 :                         *p++ = bo;
     160      404404 :                         bo = canditer_next(&cib);
     161             :                 }
     162             :         }
     163             : 
     164             :         /* properties */
     165       48049 :         BATsetcount(bn, (BUN) (p - (oid *) Tloc(bn, 0)));
     166       47955 :         bn->trevsorted = BATcount(bn) <= 1;
     167       47955 :         bn->tsorted = true;
     168       47955 :         bn->tkey = true;
     169       47955 :         bn->tnil = false;
     170       47955 :         bn->tnonil = true;
     171       47955 :         bn = virtualize(bn);
     172      114108 :   doreturn:
     173      114108 :         TRC_DEBUG(ALGO, ALGOBATFMT "," ALGOBATFMT " -> " ALGOOPTBATFMT "\n",
     174             :                   ALGOBATPAR(a), ALGOBATPAR(b), ALGOOPTBATPAR(bn));
     175             :         return bn;
     176             : }
     177             : 
     178             : /* intersect two candidate lists and produce a new one
     179             :  *
     180             :  * candidate lists are VOID-headed BATs with an OID tail which is
     181             :  * sorted and unique.
     182             :  */
     183             : BAT *
     184           9 : BATintersectcand(BAT *a, BAT *b)
     185             : {
     186           9 :         BAT *bn;
     187           9 :         oid *restrict p;
     188           9 :         struct canditer cia, cib;
     189             : 
     190           9 :         BATcheck(a, NULL);
     191           9 :         BATcheck(b, NULL);
     192             : 
     193           9 :         canditer_init(&cia, NULL, a);
     194           9 :         canditer_init(&cib, NULL, b);
     195             : 
     196           9 :         if (cia.ncand == 0 || cib.ncand == 0) {
     197           2 :                 bn = BATdense(0, 0, 0);
     198           2 :                 goto doreturn;
     199             :         }
     200             : 
     201           7 :         if (cia.tpe == cand_dense && cib.tpe == cand_dense) {
     202             :                 /* both lists are dense */
     203           0 :                 bn = newdensecand(MAX(cia.seq, cib.seq), MIN(cia.seq + cia.ncand, cib.seq + cib.ncand));
     204           0 :                 goto doreturn;
     205             :         }
     206             : 
     207           7 :         bn = COLnew(0, TYPE_oid, MIN(cia.ncand, cib.ncand), TRANSIENT);
     208           7 :         if (bn == NULL)
     209           0 :                 goto doreturn;
     210           7 :         p = (oid *) Tloc(bn, 0);
     211           7 :         if (cia.tpe == cand_dense || cib.tpe == cand_dense) {
     212           7 :                 if (cib.tpe == cand_dense) {
     213           7 :                         struct canditer ci;
     214           7 :                         ci = cia;
     215           7 :                         cia = cib;
     216           7 :                         cib = ci;
     217             :                 }
     218             :                 /* only cia is dense */
     219             : 
     220             :                 /* search for first value in cib that is contained in cia */
     221           7 :                 canditer_setidx(&cib, canditer_search(&cib, cia.seq, true));
     222           7 :                 oid bo;
     223          33 :                 while (!is_oid_nil(bo = canditer_next(&cib)) && bo < cia.seq + cia.ncand)
     224          26 :                         *p++ = bo;
     225             :         } else {
     226             :                 /* a and b are both not dense */
     227           0 :                 oid ao = canditer_next(&cia);
     228           0 :                 oid bo = canditer_next(&cib);
     229           0 :                 while (!is_oid_nil(ao) && !is_oid_nil(bo)) {
     230           0 :                         if (ao < bo)
     231           0 :                                 ao = canditer_next(&cia);
     232           0 :                         else if (bo < ao)
     233           0 :                                 bo = canditer_next(&cib);
     234             :                         else {
     235           0 :                                 *p++ = ao;
     236           0 :                                 ao = canditer_next(&cia);
     237           0 :                                 bo = canditer_next(&cib);
     238             :                         }
     239             :                 }
     240             :         }
     241             : 
     242             :         /* properties */
     243           7 :         BATsetcount(bn, (BUN) (p - (oid *) Tloc(bn, 0)));
     244           7 :         bn->trevsorted = BATcount(bn) <= 1;
     245           7 :         bn->tsorted = true;
     246           7 :         bn->tkey = true;
     247           7 :         bn->tnil = false;
     248           7 :         bn->tnonil = true;
     249           7 :         bn = virtualize(bn);
     250           9 :   doreturn:
     251           9 :         TRC_DEBUG(ALGO, ALGOBATFMT "," ALGOBATFMT " -> " ALGOOPTBATFMT "\n",
     252             :                   ALGOBATPAR(a), ALGOBATPAR(b), ALGOOPTBATPAR(bn));
     253             :         return bn;
     254             : }
     255             : 
     256             : /* calculate the difference of two candidate lists and produce a new one
     257             :  */
     258             : BAT *
     259        6754 : BATdiffcand(BAT *a, BAT *b)
     260             : {
     261        6754 :         BAT *bn;
     262        6754 :         oid *restrict p;
     263        6754 :         struct canditer cia, cib;
     264             : 
     265        6754 :         BATcheck(a, NULL);
     266        6754 :         BATcheck(b, NULL);
     267             : 
     268        6754 :         canditer_init(&cia, NULL, a);
     269        6748 :         canditer_init(&cib, NULL, b);
     270             : 
     271        6747 :         if (cia.ncand == 0) {
     272           0 :                 bn = BATdense(0, 0, 0);
     273           0 :                 goto doreturn;
     274             :         }
     275        6747 :         if (cib.ncand == 0) {
     276         704 :                 bn = canditer_slice(&cia, 0, cia.ncand);
     277         704 :                 goto doreturn;
     278             :         }
     279             : 
     280        6043 :         if (cib.seq > canditer_last(&cia) || canditer_last(&cib) < cia.seq) {
     281             :                 /* no overlap, return a */
     282           0 :                 bn = canditer_slice(&cia, 0, cia.ncand);
     283           0 :                 goto doreturn;
     284             :         }
     285             : 
     286        6043 :         if (cia.tpe == cand_dense && cib.tpe == cand_dense) {
     287             :                 /* both a and b are dense */
     288        3036 :                 if (cia.seq < cib.seq) {
     289             :                         /* a starts before b */
     290         671 :                         if (cia.seq + cia.ncand <= cib.seq + cib.ncand) {
     291             :                                 /* b overlaps with end of a */
     292          91 :                                 bn = canditer_slice(&cia, 0, cib.seq - cia.seq);
     293          91 :                                 goto doreturn;
     294             :                         }
     295             :                         /* b is subset of a */
     296         580 :                         bn = canditer_slice2(&cia, 0, cib.seq - cia.seq,
     297             :                                              cib.seq + cib.ncand - cia.seq,
     298             :                                              cia.ncand);
     299         583 :                         goto doreturn;
     300             :                 } else {
     301             :                         /* cia.seq >= cib.seq */
     302        2365 :                         if (cia.seq + cia.ncand > cib.seq + cib.ncand) {
     303             :                                 /* b overlaps with beginning of a */
     304         174 :                                 bn = canditer_slice(&cia, cib.seq + cib.ncand - cia.seq, cia.ncand);
     305         174 :                                 goto doreturn;
     306             :                         }
     307             :                         /* a is subset f b */
     308        2191 :                         bn = BATdense(0, 0, 0);
     309        2192 :                         goto doreturn;
     310             :                 }
     311             :         }
     312        3007 :         if (cib.tpe == cand_dense) {
     313             :                 /* b is dense and a is not: we can copy the part of a
     314             :                  * that is before the start of b and the part of a
     315             :                  * that is after the end of b */
     316        2474 :                 bn = canditer_slice2val(&cia, oid_nil, cib.seq,
     317             :                                         cib.seq + cib.ncand, oid_nil);
     318        2480 :                 goto doreturn;
     319             :         }
     320             : 
     321             :         /* b is not dense */
     322         533 :         bn = COLnew(0, TYPE_oid, BATcount(a), TRANSIENT);
     323         534 :         if (bn == NULL)
     324           0 :                 goto doreturn;
     325         534 :         p = Tloc(bn, 0);
     326             :         /* find first position in b that is in range of a */
     327         534 :         canditer_setidx(&cib, canditer_search(&cib, cia.seq, true));
     328             :         {
     329             :                 /* because we may jump over this declaration, we put
     330             :                  * it inside a block */
     331         533 :                 oid ob = canditer_next(&cib);
     332     7004586 :                 for (BUN i = 0; i < cia.ncand; i++) {
     333     7004052 :                         oid oa = canditer_next(&cia);
     334     9348805 :                         while (!is_oid_nil(ob) && ob < oa) {
     335     2349426 :                                 ob = canditer_next(&cib);
     336             :                         }
     337     7004053 :                         if (is_oid_nil(ob) || oa < ob)
     338     4700827 :                                 *p++ = oa;
     339             :                 }
     340             :         }
     341             : 
     342             :         /* properties */
     343         534 :         BATsetcount(bn, (BUN) (p - (oid *) Tloc(bn, 0)));
     344         534 :         bn->trevsorted = BATcount(bn) <= 1;
     345         534 :         bn->tsorted = true;
     346         534 :         bn->tkey = true;
     347         534 :         bn->tnil = false;
     348         534 :         bn->tnonil = true;
     349         534 :         bn = virtualize(bn);
     350        6758 :   doreturn:
     351        6758 :         TRC_DEBUG(ALGO, ALGOBATFMT "," ALGOBATFMT " -> " ALGOOPTBATFMT "\n",
     352             :                   ALGOBATPAR(a), ALGOBATPAR(b), ALGOOPTBATPAR(bn));
     353             :         return bn;
     354             : }
     355             : 
     356             : /* return offset of first value in cand that is >= o */
     357             : static inline BUN
     358      865986 : binsearchcand(const oid *cand, BUN hi, oid o)
     359             : {
     360      865986 :         BUN lo = 0;
     361             : 
     362      865986 :         if (o <= cand[lo])
     363             :                 return 0;
     364      424744 :         if (o > cand[hi])
     365      387610 :                 return hi + 1;
     366             :         /* loop invariant: cand[lo] < o <= cand[hi] */
     367      174598 :         while (hi > lo + 1) {
     368      154047 :                 BUN mid = (lo + hi) / 2;
     369      154047 :                 if (cand[mid] == o)
     370       16583 :                         return mid;
     371      137464 :                 if (cand[mid] < o)
     372             :                         lo = mid;
     373             :                 else
     374       99124 :                         hi = mid;
     375             :         }
     376             :         return hi;
     377             : }
     378             : 
     379             : /* count number of 1 bits in ci->mask between bit positions lo
     380             :  * (inclusive) and hi (not inclusive) */
     381             : static BUN
     382        1121 : count_mask_bits(const struct canditer *ci, BUN lo, BUN hi)
     383             : {
     384        1121 :         BUN n;
     385        1121 :         assert(lo <= hi);
     386        1121 :         assert(ci->tpe == cand_mask);
     387        1121 :         if (lo == hi)
     388             :                 return 0;
     389        1121 :         lo += ci->firstbit;
     390        1121 :         hi += ci->firstbit;
     391        1121 :         BUN loi = lo / 32;
     392        1121 :         BUN hii = hi / 32;
     393        1121 :         lo %= 32;
     394        1121 :         hi %= 32;
     395        1121 :         if (loi == hii)
     396         174 :                 return (BUN) candmask_pop((ci->mask[loi] & ((1U << hi) - 1)) >> lo);
     397         947 :         n = (BUN) candmask_pop(ci->mask[loi++] >> lo);
     398     1927596 :         while (loi < hii)
     399     1926649 :                 n += (BUN) candmask_pop(ci->mask[loi++]);
     400         947 :         if (hi != 0)
     401          69 :                 n += (BUN) candmask_pop(ci->mask[loi] & ((1U << hi) - 1));
     402             :         return n;
     403             : }
     404             : 
     405             : /* initialize a candidate iterator */
     406             : void
     407     9943104 : canditer_init(struct canditer *ci, BAT *b, BAT *s)
     408             : {
     409     9943104 :         assert(ci != NULL);
     410     9943104 :         BUN batcount = 0;
     411     9943104 :         oid hseq = 0;
     412     9943104 :         if (b) {
     413     9075270 :                 MT_lock_set(&b->theaplock);
     414     9085919 :                 batcount = BATcount(b);
     415     9085919 :                 hseq = b->hseqbase;
     416     9085919 :                 MT_lock_unset(&b->theaplock);
     417             :         }
     418             : 
     419     9964121 :         if (s == NULL) {
     420     5468470 :                 if (b == NULL) {
     421             :                         /* trivially empty candidate list */
     422           0 :                         *ci = (struct canditer) {
     423             :                                 .tpe = cand_dense,
     424             :                         };
     425           0 :                         return;
     426             :                 }
     427             :                 /* every row is a candidate */
     428     5468470 :                 *ci = (struct canditer) {
     429             :                         .tpe = cand_dense,
     430             :                         .seq = hseq,
     431             :                         .hseq = hseq,
     432             :                         .ncand = batcount,
     433             :                 };
     434     5468470 :                 return;
     435             :         }
     436             : 
     437     4495651 :         assert(ATOMtype(s->ttype) == TYPE_oid || s->ttype == TYPE_msk);
     438     4495651 :         assert(s->ttype == TYPE_msk|| s->tsorted);
     439     4495651 :         assert(s->ttype == TYPE_msk|| s->tkey);
     440     4495651 :         assert(s->ttype == TYPE_msk|| s->tnonil);
     441     4495651 :         assert(s->ttype == TYPE_void || s->tvheap == NULL);
     442             : 
     443     4495651 :         BUN cnt = BATcount(s);
     444             : 
     445     4495651 :         if (cnt == 0 || (b != NULL && batcount == 0)) {
     446             :                 /* candidate list for empty BAT or empty candidate list */
     447     1241849 :                 *ci = (struct canditer) {
     448             :                         .tpe = cand_dense,
     449     1241849 :                         .hseq = s->hseqbase,
     450             :                         .s = s,
     451             :                 };
     452     1241849 :                 return;
     453             :         }
     454             : 
     455     3253802 :         *ci = (struct canditer) {
     456     3253802 :                 .seq = s->tseqbase,
     457     3253802 :                 .hseq = s->hseqbase,
     458             :                 .s = s,
     459             :         };
     460             : 
     461     3253802 :         if (mask_cand(s)) {
     462        1124 :                 ci->tpe = cand_mask;
     463        1124 :                 ci->mask = (const uint32_t *) ccand_first(s);
     464        1124 :                 ci->seq = s->tseqbase - (oid) CCAND(s)->firstbit;
     465        1124 :                 ci->hseq = s->hseqbase;
     466        1124 :                 ci->nvals = ccand_free(s) / sizeof(uint32_t);
     467        1124 :                 cnt = ci->nvals * 32;
     468     3252678 :         } else if (s->ttype == TYPE_msk) {
     469           0 :                 assert(0);
     470             :                 ci->tpe = cand_mask;
     471             :                 ci->mask = (const uint32_t *) s->theap->base;
     472             :                 ci->seq = s->hseqbase;
     473             :                 ci->nvals = (cnt + 31U) / 32U;
     474     3252678 :         } else if (s->ttype == TYPE_void) {
     475     2743532 :                 assert(!is_oid_nil(ci->seq));
     476     2743532 :                 if (s->tvheap) {
     477       60504 :                         assert(ccand_free(s) % SIZEOF_OID == 0);
     478       60504 :                         ci->nvals = ccand_free(s) / SIZEOF_OID;
     479       60504 :                         if (ci->nvals > 0) {
     480       60504 :                                 ci->tpe = cand_except;
     481       60504 :                                 ci->oids = (const oid *) ccand_first(s);
     482             :                         } else {
     483             :                                 /* why the vheap? */
     484             :                                 ci->tpe = cand_dense;
     485             :                         }
     486             :                 } else {
     487             :                         ci->tpe = cand_dense;
     488             :                 }
     489      509146 :         } else if (is_oid_nil(ci->seq)) {
     490      473125 :                 ci->tpe = cand_materialized;
     491      473125 :                 ci->oids = (const oid *) Tloc(s, 0);
     492      473125 :                 ci->seq = ci->oids[0];
     493      473125 :                 ci->nvals = cnt;
     494             :         } else {
     495             :                 /* materialized dense: no exceptions */
     496             :                 ci->tpe = cand_dense;
     497             :         }
     498     3253802 :         switch (ci->tpe) {
     499      473215 :         case cand_materialized:
     500      473215 :                 if (b != NULL) {
     501      374757 :                         BUN p = binsearchcand(ci->oids, cnt - 1U, hseq);
     502             :                         /* p == cnt means candidate list is completely
     503             :                          * before b */
     504      374762 :                         ci->offset = p;
     505      374762 :                         ci->oids += p;
     506      374762 :                         cnt -= p;
     507      374762 :                         if (cnt > 0) {
     508      374762 :                                 cnt = binsearchcand(ci->oids, cnt  - 1U,
     509             :                                                     hseq + batcount);
     510             :                                 /* cnt == 0 means candidate list is
     511             :                                  * completely after b */
     512             :                         }
     513      374753 :                         if (cnt == 0) {
     514             :                                 /* no overlap */
     515           0 :                                 *ci = (struct canditer) {
     516             :                                         .tpe = cand_dense,
     517             :                                         .s = s,
     518             :                                 };
     519           0 :                                 return;
     520             :                         }
     521      374753 :                         ci->seq = ci->oids[0];
     522      374753 :                         ci->nvals = cnt;
     523      374753 :                         if (ci->oids[cnt - 1U] - ci->seq == cnt - 1U) {
     524             :                                 /* actually dense */
     525          60 :                                 ci->tpe = cand_dense;
     526          60 :                                 ci->oids = NULL;
     527          60 :                                 ci->nvals = 0;
     528             :                         }
     529             :                 }
     530             :                 break;
     531       60504 :         case cand_except:
     532             :                 /* exceptions must all be within range of s */
     533       60504 :                 assert(ci->oids[0] >= ci->seq);
     534       60504 :                 assert(ci->oids[ci->nvals - 1U] < ci->seq + cnt + ci->nvals);
     535             :                 /* prune exceptions at either end of range of s */
     536       91518 :                 while (ci->nvals > 0 && ci->oids[0] == ci->seq) {
     537       31014 :                         ci->nvals--;
     538       31014 :                         ci->oids++;
     539       31014 :                         ci->seq++;
     540             :                 }
     541       60712 :                 while (ci->nvals > 0 &&
     542       59762 :                        ci->oids[ci->nvals - 1U] == ci->seq + cnt + ci->nvals - 1U)
     543         208 :                         ci->nvals--;
     544       60504 :                 if (b != NULL) {
     545       59977 :                         if (ci->seq + cnt + ci->nvals <= hseq ||
     546       59977 :                             ci->seq >= hseq + batcount) {
     547             :                                 /* candidate list does not overlap with b */
     548           0 :                                 *ci = (struct canditer) {
     549             :                                         .tpe = cand_dense,
     550             :                                         .s = s,
     551             :                                 };
     552           0 :                                 return;
     553             :                         }
     554             :                 }
     555       60504 :                 if (ci->nvals > 0) {
     556       59554 :                         if (b == NULL)
     557             :                                 break;
     558       59157 :                         BUN p;
     559       59157 :                         p = binsearchcand(ci->oids, ci->nvals - 1U, hseq);
     560       59157 :                         if (p == ci->nvals) {
     561             :                                 /* all exceptions before start of b */
     562           0 :                                 ci->offset = hseq - ci->seq - ci->nvals;
     563           0 :                                 cnt = ci->seq + cnt + ci->nvals - hseq;
     564           0 :                                 ci->seq = hseq;
     565           0 :                                 ci->nvals = 0;
     566           0 :                                 ci->tpe = cand_dense;
     567           0 :                                 ci->oids = NULL;
     568           0 :                                 break;
     569             :                         }
     570       59157 :                         assert(hseq > ci->seq || p == 0);
     571       59157 :                         if (hseq > ci->seq) {
     572             :                                 /* skip candidates, possibly including
     573             :                                  * exceptions */
     574           0 :                                 ci->oids += p;
     575           0 :                                 ci->nvals -= p;
     576           0 :                                 p = hseq - ci->seq - p;
     577           0 :                                 cnt -= p;
     578           0 :                                 ci->offset += p;
     579           0 :                                 ci->seq = hseq;
     580             :                         }
     581       59157 :                         if (ci->seq + cnt + ci->nvals > hseq + batcount) {
     582           0 :                                 p = binsearchcand(ci->oids, ci->nvals - 1U,
     583             :                                                   hseq + batcount);
     584           0 :                                 ci->nvals = p;
     585           0 :                                 cnt = hseq + batcount - ci->seq - ci->nvals;
     586             :                         }
     587       59157 :                         while (ci->nvals > 0 && ci->oids[0] == ci->seq) {
     588           0 :                                 ci->nvals--;
     589           0 :                                 ci->oids++;
     590           0 :                                 ci->seq++;
     591             :                         }
     592       59157 :                         while (ci->nvals > 0 &&
     593       59157 :                                ci->oids[ci->nvals - 1U] == ci->seq + cnt + ci->nvals - 1U)
     594           0 :                                 ci->nvals--;
     595       59157 :                         if (ci->nvals > 0)
     596             :                                 break;
     597             :                 }
     598         950 :                 ci->tpe = cand_dense;
     599         950 :                 ci->oids = NULL;
     600             :                 /* fall through */
     601     2719913 :         case cand_dense:
     602     2719913 :                 if (b != NULL) {
     603     2358773 :                         if (ci->seq + cnt <= hseq ||
     604     2358773 :                             ci->seq >= hseq + batcount) {
     605             :                                 /* no overlap */
     606           0 :                                 *ci = (struct canditer) {
     607             :                                         .tpe = cand_dense,
     608             :                                         .s = s,
     609             :                                 };
     610           0 :                                 return;
     611             :                         }
     612     2358773 :                         if (hseq > ci->seq) {
     613           0 :                                 cnt -= hseq - ci->seq;
     614           0 :                                 ci->offset += hseq - ci->seq;
     615           0 :                                 ci->seq = hseq;
     616             :                         }
     617     2358773 :                         if (ci->seq + cnt > hseq + batcount)
     618           0 :                                 cnt = hseq + batcount - ci->seq;
     619             :                 }
     620             :                 break;
     621        1120 :         case cand_mask:
     622        1120 :                 assert(s->tseqbase != oid_nil);
     623        1120 :                 if (b != NULL) {
     624         343 :                         if (ci->seq + cnt <= hseq ||
     625         343 :                             ci->seq >= hseq + batcount) {
     626             :                                 /* no overlap */
     627           0 :                                 *ci = (struct canditer) {
     628             :                                         .tpe = cand_dense,
     629             :                                         .s = s,
     630             :                                 };
     631           0 :                                 return;
     632             :                         }
     633         343 :                         if (hseq > ci->seq) {
     634           0 :                                 cnt = hseq - ci->seq;
     635           0 :                                 ci->mask += cnt / 32U;
     636           0 :                                 ci->firstbit = (uint8_t) (cnt % 32U);
     637           0 :                                 cnt = BATcount(s) - cnt;
     638           0 :                                 ci->seq = hseq;
     639             :                         }
     640         343 :                         if (ci->seq + cnt > hseq + batcount) {
     641         243 :                                 cnt = hseq + batcount - ci->seq;
     642             :                         }
     643         343 :                         ci->nvals = (ci->firstbit + cnt + 31U) / 32U;
     644             :                 }
     645             :                 /* if first value is only partially used, check
     646             :                  * whether there are any 1 bits in the used part */
     647        1120 :                 if (ci->firstbit > 0 && (ci->mask[0] >> ci->firstbit) == 0) {
     648           0 :                         if (cnt <= 32U - ci->firstbit) {
     649             :                                 cnt = 0;
     650             :                                 /* returns below */
     651             :                         } else {
     652           0 :                                 cnt -= 32U - ci->firstbit;
     653           0 :                                 ci->firstbit = 0;
     654           0 :                                 ci->mask++;
     655           0 :                                 ci->nvals--;
     656             :                         }
     657             :                 }
     658             :                 /* skip over any zero mask words that are used completely */
     659        1120 :                 if (ci->firstbit == 0) {
     660        1316 :                         while (cnt >= 32U && ci->mask[0] == 0) {
     661         195 :                                 cnt -= 32U;
     662         195 :                                 ci->mask++;
     663         195 :                                 ci->nvals--;
     664             :                         }
     665             :                 }
     666             :                 /* check whether there are any 1 bits in the last word */
     667        1120 :                 if (cnt == 0 ||
     668        1120 :                     (cnt < 32U - ci->firstbit &&
     669         174 :                      ((ci->mask[0] >> ci->firstbit) & ((1U << cnt) - 1U)) == 0)) {
     670             :                         /* no one bits in the whole relevant portion
     671             :                          * of the bat */
     672           0 :                         *ci = (struct canditer) {
     673             :                                 .tpe = cand_dense,
     674             :                                 .s = s,
     675             :                         };
     676           0 :                         return;
     677             :                 }
     678             :                 /* here we know there are 1 bits in the first mask
     679             :                  * word */
     680        1120 :                 int i = candmask_lobit(ci->mask[0] >> ci->firstbit);
     681        1120 :                 assert(i >= 0);      /* there should be a set bit */
     682        1120 :                 ci->firstbit += i;
     683        1120 :                 cnt -= i;
     684        1120 :                 if (mask_cand(s))
     685        1121 :                         ci->mskoff = s->tseqbase - (oid) CCAND(s)->firstbit + (ci->mask - (const uint32_t *) ccand_first(s)) * 32U;
     686             :                 else
     687           0 :                         ci->mskoff = s->tseqbase + (ci->mask - (const uint32_t *) s->theap->base) * 32U;
     688        1120 :                 ci->seq = ci->mskoff + ci->firstbit;
     689        1120 :                 ci->nextbit = ci->firstbit;
     690             :                 /* at this point we know that bit ci->firstbit is set
     691             :                  * in ci->mask[0] */
     692        1120 :                 ci->lastbit = (ci->firstbit + cnt - 1U) % 32U + 1U;
     693        1120 :                 if (ci->lastbit < 32 &&
     694         243 :                     (ci->mask[ci->nvals - 1] & ((1U << ci->lastbit) - 1)) == 0) {
     695             :                         /* last partial word is all zero */
     696           0 :                         cnt -= ci->lastbit;
     697           0 :                         ci->lastbit = 32;
     698           0 :                         ci->nvals--;
     699             :                 }
     700        1120 :                 if (ci->lastbit == 32) {
     701             :                         /* "remove" zero words at the end */
     702         878 :                         while (cnt >= 32 && ci->mask[ci->nvals - 1] == 0) {
     703           0 :                                 ci->nvals--;
     704           0 :                                 cnt -= 32;
     705             :                         }
     706             :                 }
     707        1120 :                 ci->ncand = count_mask_bits(ci, 0, cnt);
     708        1121 :                 return;
     709             :         default:
     710           0 :                 MT_UNREACHABLE();
     711             :         }
     712     3252678 :         ci->ncand = cnt;
     713     3252678 :         ci->hseq += ci->offset;
     714             : }
     715             : 
     716             : /* return the next candidate without advancing */
     717             : oid
     718     2254723 : canditer_peek(const struct canditer *ci)
     719             : {
     720     2254723 :         oid o = oid_nil;
     721     2254723 :         if (ci->next == ci->ncand)
     722        5721 :                 return oid_nil;
     723     2249002 :         switch (ci->tpe) {
     724     2007306 :         case cand_dense:
     725     2007306 :                 o = ci->seq + ci->next;
     726     2007306 :                 break;
     727      237717 :         case cand_materialized:
     728      237717 :                 assert(ci->next < ci->nvals);
     729      237717 :                 o = ci->oids[ci->next];
     730      237717 :                 break;
     731        3979 :         case cand_except:
     732        3979 :                 o = ci->seq + ci->add + ci->next;
     733        3989 :                 for (oid a = ci->add; a < ci->nvals && o == ci->oids[a]; a++)
     734          10 :                         o++;
     735             :                 break;
     736           0 :         case cand_mask: {
     737           0 :                 BUN m = ci->nextmsk;
     738           0 :                 uint8_t b = ci->nextbit;
     739           0 :                 while ((ci->mask[m] >> b) == 0) {
     740           0 :                         m++;
     741           0 :                         b = 0;
     742             :                 }
     743           0 :                 b += candmask_lobit(ci->mask[m] >> b);
     744           0 :                 o = ci->mskoff + m * 32 + b;
     745           0 :                 break;
     746             :         }
     747             :         default:
     748           0 :                 MT_UNREACHABLE();
     749             :         }
     750             :         return o;
     751             : }
     752             : 
     753             : /* return the previous candidate */
     754             : oid
     755        1937 : canditer_prev(struct canditer *ci)
     756             : {
     757        1937 :         if (ci->next == 0)
     758           0 :                 return oid_nil;
     759        1937 :         switch (ci->tpe) {
     760        1937 :         case cand_dense:
     761        1937 :                 return ci->seq + --ci->next;
     762           0 :         case cand_materialized:
     763           0 :                 return ci->oids[--ci->next];
     764             :         case cand_except:
     765           0 :                 break;
     766           0 :         case cand_mask:
     767           0 :                 for (;;) {
     768           0 :                         if (ci->nextbit == 0) {
     769           0 :                                 ci->nextbit = 32;
     770           0 :                                 while (ci->mask[--ci->nextmsk] == 0)
     771             :                                         ;
     772             :                         }
     773           0 :                         if (ci->mask[ci->nextmsk] & (1U << --ci->nextbit))
     774             :                                 break;
     775             :                 }
     776           0 :                 ci->next--;
     777           0 :                 return ci->mskoff + ci->nextmsk * 32 + ci->nextbit;
     778             :         default:
     779           0 :                 MT_UNREACHABLE();
     780             :         }
     781           0 :         oid o = ci->seq + ci->add + --ci->next;
     782           0 :         while (ci->add > 0 && o == ci->oids[ci->add - 1]) {
     783           0 :                 ci->add--;
     784           0 :                 o--;
     785             :         }
     786             :         return o;
     787             : }
     788             : 
     789             : /* return the previous candidate without retreating */
     790             : oid
     791        4421 : canditer_peekprev(const struct canditer *ci)
     792             : {
     793        4421 :         oid o = oid_nil;
     794             : 
     795        4421 :         if (ci->next == 0)
     796           0 :                 return oid_nil;
     797        4421 :         switch (ci->tpe) {
     798        4421 :         case cand_dense:
     799        4421 :                 return ci->seq + ci->next - 1;
     800           0 :         case cand_materialized:
     801           0 :                 return ci->oids[ci->next - 1];
     802           0 :         case cand_except:
     803           0 :                 o = ci->seq + ci->add + ci->next - 1;
     804           0 :                 for (oid a = ci->add; a > 0 && o == ci->oids[a - 1]; a--)
     805           0 :                         o--;
     806             :                 break;
     807           0 :         case cand_mask: {
     808           0 :                 BUN m = ci->nextmsk;
     809           0 :                 uint8_t b = ci->nextbit;
     810           0 :                 do {
     811           0 :                         if (b == 0) {
     812           0 :                                 b = 32;
     813           0 :                                 while (ci->mask[--m] == 0)
     814             :                                         ;
     815             :                         }
     816           0 :                 } while ((ci->mask[m] & (1U << --b)) == 0);
     817           0 :                 o = ci->mskoff + m * 32 + b;
     818           0 :                 if (++b == 32) {
     819             :                         b = 0;
     820             :                         m++;
     821             :                 }
     822             :                 break;
     823             :         }
     824             :         default:
     825           0 :                 MT_UNREACHABLE();
     826             :         }
     827             :         return o;
     828             : }
     829             : 
     830             : /* if o is a candidate, return it, else return the next candidate from
     831             :  * the cand_mask iterator ci after (if next is set) or before (if next
     832             :  * is unset) o; if there are no more candidates, return oid_nil */
     833             : oid
     834           0 : canditer_mask_next(const struct canditer *ci, oid o, bool next)
     835             : {
     836           0 :         if (o < ci->mskoff)
     837           0 :                 return next ? ci->mskoff + ci->firstbit : oid_nil;
     838           0 :         o -= ci->mskoff;
     839           0 :         BUN p = o / 32;
     840           0 :         o %= 32;
     841           0 :         if (p >= ci->nvals || (p == ci->nvals - 1 && o >= ci->lastbit))
     842           0 :                 return next ? oid_nil : canditer_last(ci);
     843           0 :         if (next) {
     844           0 :                 while ((ci->mask[p] & (1U << o)) == 0) {
     845           0 :                         if (++o == 32) {
     846           0 :                                 o = 0;
     847           0 :                                 if (++p == ci->nvals)
     848           0 :                                         return oid_nil;
     849             :                         }
     850             :                 }
     851           0 :                 if (p == ci->nvals - 1 && o >= ci->lastbit)
     852           0 :                         return oid_nil;
     853             :         } else {
     854           0 :                 while ((ci->mask[p] & (1U << o)) == 0) {
     855           0 :                         if (o == 0) {
     856           0 :                                 o = 31;
     857           0 :                                 if (p == 0)
     858           0 :                                         return oid_nil;
     859           0 :                                 p--;
     860             :                         } else {
     861           0 :                                 o--;
     862             :                         }
     863             :                 }
     864           0 :                 if (p == 0 && o < ci->firstbit)
     865           0 :                         return oid_nil;
     866             :         }
     867           0 :         return ci->mskoff + 32 * p + o;
     868             : }
     869             : 
     870             : /* return the last candidate */
     871             : oid
     872      250009 : canditer_last(const struct canditer *ci)
     873             : {
     874      250009 :         if (ci->ncand == 0)
     875           0 :                 return oid_nil;
     876      250009 :         switch (ci->tpe) {
     877      229722 :         case cand_dense:
     878      229722 :                 return ci->seq + ci->ncand - 1;
     879       18351 :         case cand_materialized:
     880       18351 :                 return ci->oids[ci->ncand - 1];
     881        1935 :         case cand_except:
     882        1935 :                 return ci->seq + ci->ncand + ci->nvals - 1;
     883           1 :         case cand_mask:
     884           1 :                 for (uint8_t i = ci->lastbit; i > 0; ) {
     885           1 :                         if (ci->mask[ci->nvals - 1] & (1U << --i))
     886           1 :                                 return ci->mskoff + (ci->nvals - 1) * 32 + i;
     887             :                 }
     888           0 :                 break;          /* cannot happen */
     889             :         default:
     890           0 :                 MT_UNREACHABLE();
     891             :         }
     892           0 :         return oid_nil;         /* cannot happen */
     893             : }
     894             : 
     895             : /* return the candidate at the given index */
     896             : oid
     897   309228756 : canditer_idx(const struct canditer *ci, BUN p)
     898             : {
     899   309228756 :         if (p >= ci->ncand)
     900           0 :                 return oid_nil;
     901   309228756 :         switch (ci->tpe) {
     902   171613502 :         case cand_dense:
     903   171613502 :                 return ci->seq + p;
     904   137582586 :         case cand_materialized:
     905   137582586 :                 return ci->oids[p];
     906       32593 :         case cand_except: {
     907       32593 :                 oid o = ci->seq + p;
     908       32593 :                 if (o < ci->oids[0])
     909             :                         return o;
     910       17339 :                 if (o + ci->nvals > ci->oids[ci->nvals - 1])
     911             :                         return o + ci->nvals;
     912       12929 :                 BUN lo = 0, hi = ci->nvals - 1;
     913      104602 :                 while (hi - lo > 1) {
     914       78744 :                         BUN mid = (hi + lo) / 2;
     915       78744 :                         if (ci->oids[mid] - mid > o)
     916             :                                 hi = mid;
     917             :                         else
     918       44370 :                                 lo = mid;
     919             :                 }
     920       12929 :                 return o + hi;
     921             :         }
     922          75 :         case cand_mask: {
     923          75 :                 BUN x;
     924          75 :                 if ((x = candmask_pop(ci->mask[0] >> ci->firstbit)) > p) {
     925          24 :                         for (uint8_t i = ci->firstbit; ; i++) {
     926          99 :                                 if (ci->mask[0] & (1U << i)) {
     927          99 :                                         if (p == 0)
     928          75 :                                                 return ci->mskoff + i;
     929          24 :                                         p--;
     930             :                                 }
     931             :                         }
     932             :                 }
     933           0 :                 for (BUN n = 1; n < ci->nvals; n++) {
     934           0 :                         uint32_t mask = ci->mask[n];
     935           0 :                         p -= x;
     936           0 :                         x = candmask_pop(mask);
     937           0 :                         if (x > p) {
     938           0 :                                 for (uint8_t i = 0; ; i++) {
     939           0 :                                         if (mask & (1U << i)) {
     940           0 :                                                 if (p == 0)
     941           0 :                                                         return ci->mskoff + n * 32 + i;
     942           0 :                                                 p--;
     943             :                                         }
     944             :                                 }
     945             :                         }
     946             :                 }
     947           0 :                 break;          /* cannot happen */
     948             :         }
     949             :         default:
     950           0 :                 MT_UNREACHABLE();
     951             :         }
     952           0 :         return oid_nil;         /* cannot happen */
     953             : }
     954             : 
     955             : /* set the index for the next candidate to be returned */
     956             : void
     957      600752 : canditer_setidx(struct canditer *ci, BUN p)
     958             : {
     959      600752 :         if (p != ci->next) {
     960      572198 :                 if (p >= ci->ncand) {
     961       58677 :                         ci->next = ci->ncand;
     962       58677 :                         switch (ci->tpe) {
     963           0 :                         case cand_except:
     964           0 :                                 ci->add = ci->nvals;
     965           0 :                                 break;
     966           0 :                         case cand_mask:
     967           0 :                                 ci->nextbit = ci->lastbit;
     968           0 :                                 ci->nextmsk = ci->nvals;
     969           0 :                                 if (ci->nextbit == 32)
     970           0 :                                         ci->nextbit = 0;
     971             :                                 else
     972           0 :                                         ci->nextmsk--;
     973             :                                 break;
     974             :                         default:
     975             :                                 break;
     976             :                         }
     977             :                 } else {
     978      513521 :                         ci->next = p;
     979      513521 :                         switch (ci->tpe) {
     980        2318 :                         case cand_except:
     981        2318 :                                 ci->add = canditer_idx(ci, p) - ci->seq - p;
     982        2318 :                                 break;
     983           0 :                         case cand_mask: {
     984           0 :                                 oid o = canditer_idx(ci, p) - ci->mskoff;
     985           0 :                                 ci->nextmsk = o / 32;
     986           0 :                                 ci->nextbit = (uint8_t) (o % 32);
     987           0 :                                 break;
     988             :                         }
     989             :                         default:
     990             :                                 break;
     991             :                         }
     992             :                 }
     993             :         }
     994      600752 : }
     995             : 
     996             : /* reset */
     997             : void
     998      783192 : canditer_reset(struct canditer *ci)
     999             : {
    1000      783192 :         if (ci->tpe == cand_mask) {
    1001           0 :                 ci->nextbit = ci->firstbit;
    1002           0 :                 ci->nextmsk = 0;
    1003             :         } else {
    1004      783192 :                 ci->add = 0;
    1005             :         }
    1006      783192 :         ci->next = 0;
    1007      783192 : }
    1008             : 
    1009             : /* return index of given candidate if it occurs; if the candidate does
    1010             :  * not occur, if next is set, return index of next larger candidate,
    1011             :  * if next is not set, return BUN_NONE */
    1012             : BUN
    1013     1134358 : canditer_search(const struct canditer *ci, oid o, bool next)
    1014             : {
    1015     1134358 :         BUN p;
    1016             : 
    1017     1134358 :         switch (ci->tpe) {
    1018     1076216 :         case cand_dense:
    1019     1076216 :                 if (o < ci->seq)
    1020         917 :                         return next ? 0 : BUN_NONE;
    1021     1075299 :                 if (o >= ci->seq + ci->ncand)
    1022      191298 :                         return next ? ci->ncand : BUN_NONE;
    1023      884001 :                 return o - ci->seq;
    1024       46991 :         case cand_materialized:
    1025       46991 :                 if (ci->nvals == 0)
    1026             :                         return 0;
    1027       46999 :                 p = binsearchcand(ci->oids, ci->nvals - 1, o);
    1028       47051 :                 if (next || (p != ci->nvals && ci->oids[p] == o))
    1029       46806 :                         return p;
    1030             :                 break;
    1031       11151 :         case cand_except:
    1032       11151 :                 if (o < ci->seq)
    1033           0 :                         return next ? 0 : BUN_NONE;
    1034       11151 :                 if (o >= ci->seq + ci->ncand + ci->nvals)
    1035         926 :                         return next ? ci->ncand : BUN_NONE;
    1036       10225 :                 p = binsearchcand(ci->oids, ci->nvals - 1, o);
    1037       10225 :                 if (next || p == ci->nvals || ci->oids[p] != o)
    1038       10070 :                         return o - ci->seq - p;
    1039             :                 break;
    1040           0 :         case cand_mask:
    1041           0 :                 if (o < ci->mskoff) {
    1042           0 :                         return next ? 0 : BUN_NONE;
    1043             :                 }
    1044           0 :                 o -= ci->mskoff;
    1045           0 :                 p = o / 32;
    1046           0 :                 if (p >= ci->nvals)
    1047           0 :                         return next ? ci->ncand : BUN_NONE;
    1048           0 :                 o %= 32;
    1049           0 :                 if (p == ci->nvals - 1 && o >= ci->lastbit)
    1050           0 :                         return next ? ci->ncand : BUN_NONE;
    1051           0 :                 if (next || ci->mask[p] & (1U << o))
    1052           0 :                         return count_mask_bits(ci, 0, p * 32 + o) + !(ci->mask[p] & (1U << o));
    1053             :                 break;
    1054             :         default:
    1055           0 :                 MT_UNREACHABLE();
    1056             :         }
    1057             :         return BUN_NONE;
    1058             : }
    1059             : 
    1060             : static BAT *
    1061         151 : canditer_sliceval_mask(const struct canditer *ci, oid lo1, oid hi1, BUN cnt1,
    1062             :                        oid lo2, oid hi2, BUN cnt2)
    1063             : {
    1064         151 :         assert(cnt2 == 0 || !is_oid_nil(lo2));
    1065         151 :         assert(cnt2 == 0 || lo2 >= hi1);
    1066         151 :         if (is_oid_nil(lo1) || lo1 < ci->mskoff + ci->firstbit)
    1067          69 :                 lo1 = ci->mskoff + ci->firstbit;
    1068         151 :         if (is_oid_nil(hi1) || hi1 >= ci->mskoff + (ci->nvals - 1) * 32 + ci->lastbit)
    1069         143 :                 hi1 = ci->mskoff + (ci->nvals - 1) * 32 + ci->lastbit;
    1070             : 
    1071         151 :         BAT *bn = COLnew(0, TYPE_oid, cnt1 + cnt2, TRANSIENT);
    1072         151 :         if (bn == NULL)
    1073             :                 return NULL;
    1074         151 :         bn->tkey = true;
    1075             : 
    1076         151 :         if (hi1 > ci->mskoff) {
    1077         151 :                 if (lo1 < ci->mskoff)
    1078             :                         lo1 = 0;
    1079             :                 else
    1080         151 :                         lo1 -= ci->mskoff;
    1081         151 :                 hi1 -= ci->mskoff;
    1082         856 :                 for (oid o = lo1; o < hi1 && cnt1 > 0; o++) {
    1083         705 :                         if (ci->mask[o / 32] & (1U << (o % 32))) {
    1084         295 :                                 if (BUNappend(bn, &(oid){o + ci->mskoff}, false) != GDK_SUCCEED) {
    1085           0 :                                         BBPreclaim(bn);
    1086           0 :                                         return NULL;
    1087             :                                 }
    1088         295 :                                 cnt1--;
    1089             :                         }
    1090             :                 }
    1091             :         }
    1092         151 :         if (cnt2 > 0) {
    1093           0 :                 if (lo2 < ci->mskoff + ci->firstbit)
    1094             :                         lo2 = ci->mskoff + ci->firstbit;
    1095           0 :                 if (is_oid_nil(hi2) || hi2 >= ci->mskoff + (ci->nvals - 1) * 32 + ci->lastbit)
    1096           0 :                         hi2 = ci->mskoff + (ci->nvals - 1) * 32 + ci->lastbit;
    1097             : 
    1098           0 :                 lo2 -= ci->mskoff;
    1099           0 :                 hi2 -= ci->mskoff;
    1100           0 :                 for (oid o = lo2; o < hi2 && cnt2 > 0; o++) {
    1101           0 :                         if (ci->mask[o / 32] & (1U << (o % 32))) {
    1102           0 :                                 if (BUNappend(bn, &(oid){o + ci->mskoff}, false) != GDK_SUCCEED) {
    1103           0 :                                         BBPreclaim(bn);
    1104           0 :                                         return NULL;
    1105             :                                 }
    1106           0 :                                 cnt2--;
    1107             :                         }
    1108             :                 }
    1109             :         }
    1110             :         return bn;
    1111             : }
    1112             : 
    1113             : /* return either an actual BATslice or a new BAT that contains the
    1114             :  * "virtual" slice of the input candidate list BAT; except, unlike
    1115             :  * BATslice, the hseqbase of the returned BAT is 0; note for cand_mask
    1116             :  * candidate iterators, the BUN values refer to number of 1 bits */
    1117             : BAT *
    1118      565168 : canditer_slice(const struct canditer *ci, BUN lo, BUN hi)
    1119             : {
    1120      565168 :         BAT *bn;
    1121      565168 :         oid o;
    1122      565168 :         BUN add;
    1123             : 
    1124      565168 :         assert(ci != NULL);
    1125             : 
    1126      565168 :         if (lo >= ci->ncand || lo >= hi)
    1127      132777 :                 return BATdense(0, 0, 0);
    1128      432391 :         if (hi > ci->ncand)
    1129             :                 hi = ci->ncand;
    1130      432391 :         if (hi - lo == 1)
    1131      352903 :                 return BATdense(0, canditer_idx(ci, lo), 1);
    1132       79488 :         switch (ci->tpe) {
    1133        4269 :         case cand_materialized:
    1134        4269 :                 if (ci->s) {
    1135        4269 :                         bn = BATslice(ci->s, lo + ci->offset, hi + ci->offset);
    1136        4271 :                         BAThseqbase(bn, 0);
    1137        4271 :                         return bn;
    1138             :                 }
    1139           0 :                 bn = COLnew(0, TYPE_oid, hi - lo, TRANSIENT);
    1140           0 :                 if (bn == NULL)
    1141             :                         return NULL;
    1142           0 :                 BATsetcount(bn, hi - lo);
    1143           0 :                 memcpy(Tloc(bn, 0), ci->oids + lo, (hi - lo) * sizeof(oid));
    1144           0 :                 break;
    1145       74931 :         case cand_dense:
    1146       74931 :                 return BATdense(0, ci->seq + lo, hi - lo);
    1147         285 :         case cand_except:
    1148         285 :                 o = canditer_idx(ci, lo);
    1149         285 :                 add = o - ci->seq - lo;
    1150         285 :                 assert(add <= ci->nvals);
    1151         285 :                 if (add == ci->nvals || o + hi - lo < ci->oids[add]) {
    1152             :                         /* after last exception or before next
    1153             :                          * exception: return dense sequence */
    1154         243 :                         return BATdense(0, o, hi - lo);
    1155             :                 }
    1156          42 :                 bn = COLnew(0, TYPE_oid, hi - lo, TRANSIENT);
    1157          42 :                 if (bn == NULL)
    1158             :                         return NULL;
    1159          42 :                 BATsetcount(bn, hi - lo);
    1160         320 :                 for (oid *dst = Tloc(bn, 0); lo < hi; lo++) {
    1161         373 :                         while (add < ci->nvals && o == ci->oids[add]) {
    1162          95 :                                 o++;
    1163          95 :                                 add++;
    1164             :                         }
    1165         278 :                         *dst++ = o++;
    1166             :                 }
    1167             :                 break;
    1168           3 :         case cand_mask:
    1169           3 :                 return canditer_sliceval_mask(ci, canditer_idx(ci, lo),
    1170             :                                               oid_nil, hi - lo,
    1171             :                                               oid_nil, oid_nil, 0);
    1172             :         default:
    1173           0 :                 MT_UNREACHABLE();
    1174             :         }
    1175          42 :         bn->tsorted = true;
    1176          42 :         bn->trevsorted = BATcount(bn) <= 1;
    1177          42 :         bn->tkey = true;
    1178          42 :         bn->tseqbase = oid_nil;
    1179          42 :         bn->tnil = false;
    1180          42 :         bn->tnonil = true;
    1181          42 :         bn->tminpos = 0;
    1182          42 :         bn->tmaxpos = BATcount(bn) - 1;
    1183          42 :         return virtualize(bn);
    1184             : }
    1185             : 
    1186             : /* like the above, except the bounds are given by values instead of
    1187             :  * indexes */
    1188             : BAT *
    1189      369556 : canditer_sliceval(const struct canditer *ci, oid lo, oid hi)
    1190             : {
    1191      369556 :         if (ci->tpe != cand_mask) {
    1192     1108106 :                 return canditer_slice(
    1193             :                         ci,
    1194      369290 :                         is_oid_nil(lo) ? 0 : canditer_search(ci, lo, true),
    1195      369408 :                         is_oid_nil(hi) ? ci->ncand : canditer_search(ci, hi, true));
    1196             :         }
    1197             : 
    1198         148 :         return canditer_sliceval_mask(ci, lo, hi, ci->ncand,
    1199             :                                       oid_nil, oid_nil, 0);
    1200             : }
    1201             : 
    1202             : /* return the combination of two slices */
    1203             : BAT *
    1204       40771 : canditer_slice2(const struct canditer *ci, BUN lo1, BUN hi1, BUN lo2, BUN hi2)
    1205             : {
    1206       40771 :         BAT *bn;
    1207       40771 :         oid o;
    1208       40771 :         BUN add;
    1209             : 
    1210       40771 :         assert(lo1 <= hi1);
    1211       40771 :         assert(lo2 <= hi2);
    1212       40771 :         assert(hi1 <= lo2 || (lo2 == 0 && hi2 == 0));
    1213             : 
    1214       40771 :         if (hi1 == lo2)         /* consecutive slices: combine into one */
    1215        2893 :                 return canditer_slice(ci, lo1, hi2);
    1216       37878 :         if (lo2 == hi2 || hi1 >= ci->ncand || lo2 >= ci->ncand) {
    1217             :                 /* empty second slice */
    1218       31126 :                 return canditer_slice(ci, lo1, hi1);
    1219             :         }
    1220        6752 :         if (lo1 == hi1)         /* empty first slice */
    1221        2001 :                 return canditer_slice(ci, lo2, hi2);
    1222        4751 :         if (lo1 >= ci->ncand)     /* out of range */
    1223             :                 return BATdense(0, 0, 0);
    1224             : 
    1225        4751 :         if (hi2 >= ci->ncand)
    1226             :                 hi2 = ci->ncand;
    1227             : 
    1228        4751 :         bn = COLnew(0, TYPE_oid, hi1 - lo1 + hi2 - lo2, TRANSIENT);
    1229        4763 :         if (bn == NULL)
    1230             :                 return NULL;
    1231        4763 :         BATsetcount(bn, hi1 - lo1 + hi2 - lo2);
    1232        4762 :         bn->tsorted = true;
    1233        4762 :         bn->trevsorted = BATcount(bn) <= 1;
    1234        4762 :         bn->tkey = true;
    1235        4762 :         bn->tseqbase = oid_nil;
    1236        4762 :         bn->tnil = false;
    1237        4762 :         bn->tnonil = true;
    1238             : 
    1239        4762 :         oid *dst = Tloc(bn, 0);
    1240             : 
    1241        4762 :         switch (ci->tpe) {
    1242        2423 :         case cand_materialized:
    1243        2423 :                 memcpy(dst, ci->oids + lo1, (hi1 - lo1) * sizeof(oid));
    1244        2423 :                 memcpy(dst + hi1 - lo1, ci->oids + lo2, (hi2 - lo2) * sizeof(oid));
    1245        2423 :                 break;
    1246             :         case cand_dense:
    1247      943194 :                 while (lo1 < hi1)
    1248      940856 :                         *dst++ = ci->seq + lo1++;
    1249      274221 :                 while (lo2 < hi2)
    1250      271883 :                         *dst++ = ci->seq + lo2++;
    1251             :                 break;
    1252           1 :         case cand_except:
    1253           1 :                 o = canditer_idx(ci, lo1);
    1254           1 :                 add = o - ci->seq - lo1;
    1255           1 :                 assert(add <= ci->nvals);
    1256           1 :                 if (add == ci->nvals) {
    1257             :                         /* after last exception: return dense sequence */
    1258           0 :                         while (lo1 < hi1)
    1259           0 :                                 *dst++ = ci->seq + add + lo1++;
    1260             :                 } else {
    1261           2 :                         while (lo1 < hi1) {
    1262           1 :                                 while (add < ci->nvals && o == ci->oids[add]) {
    1263           0 :                                         o++;
    1264           0 :                                         add++;
    1265             :                                 }
    1266           1 :                                 *dst++ = o++;
    1267           1 :                                 lo1++;
    1268             :                         }
    1269             :                 }
    1270           1 :                 o = canditer_idx(ci, lo2);
    1271           1 :                 add = o - ci->seq - lo2;
    1272           1 :                 assert(add <= ci->nvals);
    1273           1 :                 if (add == ci->nvals) {
    1274             :                         /* after last exception: return dense sequence */
    1275           0 :                         while (lo2 < hi2)
    1276           0 :                                 *dst++ = ci->seq + add + lo2++;
    1277             :                 } else {
    1278           4 :                         while (lo2 < hi2) {
    1279           6 :                                 while (add < ci->nvals && o == ci->oids[add]) {
    1280           3 :                                         o++;
    1281           3 :                                         add++;
    1282             :                                 }
    1283           3 :                                 *dst++ = o++;
    1284           3 :                                 lo2++;
    1285             :                         }
    1286             :                 }
    1287             :                 break;
    1288           0 :         case cand_mask:
    1289           0 :                 return canditer_sliceval_mask(ci, canditer_idx(ci, lo1),
    1290             :                                               oid_nil, hi1 - lo1,
    1291             :                                               canditer_idx(ci, lo2),
    1292             :                                               oid_nil, hi2 - lo2);
    1293             :         default:
    1294           0 :                 MT_UNREACHABLE();
    1295             :         }
    1296        4762 :         return virtualize(bn);
    1297             : }
    1298             : 
    1299             : BAT *
    1300       40198 : canditer_slice2val(const struct canditer *ci, oid lo1, oid hi1, oid lo2, oid hi2)
    1301             : {
    1302       40198 :         if (ci->tpe != cand_mask) {
    1303      158376 :                 return canditer_slice2(
    1304             :                         ci,
    1305       37434 :                         is_oid_nil(lo1) ? 0 : canditer_search(ci, lo1, true),
    1306       40198 :                         is_oid_nil(hi1) ? ci->ncand : canditer_search(ci, hi1, true),
    1307       40232 :                         is_oid_nil(lo2) ? 0 : canditer_search(ci, lo2, true),
    1308         314 :                         is_oid_nil(hi2) ? ci->ncand : canditer_search(ci, hi2, true));
    1309             :         }
    1310             : 
    1311           0 :         return canditer_sliceval_mask(ci, lo1, hi1, ci->ncand,
    1312           0 :                                       lo2, hi2, ci->ncand);
    1313             : }
    1314             : 
    1315             : BAT *
    1316        3190 : BATnegcands(oid tseq, BUN nr, BAT *odels)
    1317             : {
    1318        3190 :         const char *nme;
    1319        3190 :         Heap *dels;
    1320        3190 :         BUN lo, hi;
    1321        3190 :         ccand_t *c;
    1322        3190 :         BAT *bn;
    1323             : 
    1324        3190 :         bn = BATdense(0, tseq, nr);
    1325        3194 :         if (bn == NULL)
    1326             :                 return NULL;
    1327        3194 :         if (BATcount(odels) == 0)
    1328        2771 :                 goto doreturn;
    1329             : 
    1330         423 :         lo = SORTfndfirst(odels, &bn->tseqbase);
    1331         422 :         hi = SORTfndfirst(odels, &(oid) {bn->tseqbase + BATcount(bn)});
    1332         422 :         if (lo == hi)
    1333             :                 return bn;
    1334         422 :         if (lo + nr == hi) {
    1335         133 :                 BATsetcount(bn, 0);
    1336         134 :                 goto doreturn;
    1337             :         }
    1338             : 
    1339         289 :         nme = BBP_physical(bn->batCacheid);
    1340         289 :         if ((dels = GDKmalloc(sizeof(Heap))) == NULL){
    1341           0 :                 BBPreclaim(bn);
    1342           0 :                 return NULL;
    1343             :         }
    1344         578 :         *dels = (Heap) {
    1345         289 :                 .farmid = BBPselectfarm(bn->batRole, bn->ttype, varheap),
    1346         289 :                 .parentid = bn->batCacheid,
    1347             :                 .dirty = true,
    1348             :                 .refs = ATOMIC_VAR_INIT(1),
    1349             :         };
    1350         289 :         strconcat_len(dels->filename, sizeof(dels->filename),
    1351             :                       nme, ".theap", NULL);
    1352             : 
    1353         578 :         if (dels->farmid < 0 ||
    1354         289 :             HEAPalloc(dels, hi - lo + (sizeof(ccand_t)/sizeof(oid)), sizeof(oid)) != GDK_SUCCEED) {
    1355           0 :                 GDKfree(dels);
    1356           0 :                 BBPreclaim(bn);
    1357           0 :                 return NULL;
    1358             :         }
    1359         289 :         c = (ccand_t *) dels->base;
    1360         289 :         *c = (ccand_t) {
    1361             :                 .type = CAND_NEGOID,
    1362             :         };
    1363         289 :         dels->free = sizeof(ccand_t) + sizeof(oid) * (hi - lo);
    1364         289 :         BATiter bi = bat_iterator(odels);
    1365         289 :         if (bi.type == TYPE_void) {
    1366         166 :                 oid *r = (oid *) (dels->base + sizeof(ccand_t));
    1367       93673 :                 for (BUN x = lo; x < hi; x++)
    1368       93507 :                         r[x - lo] = x + odels->tseqbase;
    1369             :         } else {
    1370         123 :                 oid *r = (oid *) (dels->base + sizeof(ccand_t));
    1371         123 :                 memcpy(r, (const oid *) bi.base + lo, sizeof(oid) * (hi - lo));
    1372             :         }
    1373         289 :         bat_iterator_end(&bi);
    1374         289 :         assert(bn->tvheap == NULL);
    1375         289 :         bn->tvheap = dels;
    1376         289 :         BATsetcount(bn, bn->batCount - (hi - lo));
    1377        3194 :   doreturn:
    1378        3194 :         TRC_DEBUG(ALGO, "nr=" BUNFMT ", odels=" ALGOBATFMT
    1379             :                   " -> " ALGOBATFMT "\n",
    1380             :                   nr, ALGOBATPAR(odels),
    1381             :                   ALGOBATPAR(bn));
    1382             :         return bn;
    1383             : }
    1384             : 
    1385             : BAT *
    1386       75978 : BATmaskedcands(oid hseq, BUN nr, BAT *masked, bool selected)
    1387             : {
    1388       75978 :         const char *nme;
    1389       75978 :         Heap *msks;
    1390       75978 :         ccand_t *c;
    1391       75978 :         BUN nmask;
    1392       75978 :         BAT *bn;
    1393             : 
    1394       75978 :         assert(masked->ttype == TYPE_msk);
    1395             : 
    1396       75978 :         bn = COLnew(hseq, TYPE_void, 0, TRANSIENT);
    1397       75978 :         if (bn == NULL)
    1398             :                 return NULL;
    1399       75978 :         BATtseqbase(bn, hseq);
    1400             : 
    1401       75977 :         if (BATcount(masked) == 0)
    1402             :                 return bn;
    1403             : 
    1404       75978 :         nme = BBP_physical(bn->batCacheid);
    1405       75978 :         if ((msks = GDKmalloc(sizeof(Heap))) == NULL){
    1406           0 :                 BBPreclaim(bn);
    1407           0 :                 return NULL;
    1408             :         }
    1409      151956 :         *msks = (Heap) {
    1410       75978 :                 .farmid = BBPselectfarm(bn->batRole, bn->ttype, varheap),
    1411       75978 :                 .parentid = bn->batCacheid,
    1412             :                 .dirty = true,
    1413             :                 .refs = ATOMIC_VAR_INIT(1),
    1414             :         };
    1415       75978 :         strconcat_len(msks->filename, sizeof(msks->filename),
    1416             :                       nme, ".theap", NULL);
    1417             : 
    1418       75978 :         nmask = (nr + 31) / 32;
    1419      151956 :         if (msks->farmid < 0 ||
    1420       75978 :             HEAPalloc(msks, nmask + (sizeof(ccand_t)/sizeof(uint32_t)), sizeof(uint32_t)) != GDK_SUCCEED) {
    1421           0 :                 GDKfree(msks);
    1422           0 :                 BBPreclaim(bn);
    1423           0 :                 return NULL;
    1424             :         }
    1425       75978 :         c = (ccand_t *) msks->base;
    1426       75978 :         *c = (ccand_t) {
    1427             :                 .type = CAND_MSK,
    1428             : //              .mask = true,
    1429             :         };
    1430       75978 :         msks->free = sizeof(ccand_t) + nmask * sizeof(uint32_t);
    1431       75978 :         uint32_t *r = (uint32_t*)(msks->base + sizeof(ccand_t));
    1432       75978 :         BATiter bi = bat_iterator(masked);
    1433       75978 :         if (selected) {
    1434       75978 :                 if (nr <= bi.count)
    1435       75978 :                         memcpy(r, bi.base, nmask * sizeof(uint32_t));
    1436             :                 else
    1437           0 :                         memcpy(r, bi.base, (bi.count + 31) / 32 * sizeof(uint32_t));
    1438             :         } else {
    1439           0 :                 const uint32_t *s = (const uint32_t *) bi.base;
    1440           0 :                 BUN nmask_ = (bi.count + 31) / 32;
    1441           0 :                 for (BUN i = 0; i < nmask_; i++)
    1442           0 :                         r[i] = ~s[i];
    1443             :         }
    1444       75978 :         if (nr > bi.count) {
    1445           0 :                 BUN rest = bi.count & 31;
    1446           0 :                 BUN nmask_ = (bi.count + 31) / 32;
    1447           0 :                 if (rest > 0)
    1448           0 :                         r[nmask_ -1] |= ((1U << (32 - rest)) - 1) << rest;
    1449           0 :                 for (BUN j = nmask_; j < nmask; j++)
    1450           0 :                         r[j] = ~0;
    1451             :         }
    1452       75978 :         bat_iterator_end(&bi);
    1453             :         /* make sure last word doesn't have any spurious bits set */
    1454       75977 :         BUN cnt = nr % 32;
    1455       75977 :         if (cnt > 0)
    1456       74102 :                 r[nmask - 1] &= (1U << cnt) - 1;
    1457             :         cnt = 0;
    1458     9959360 :         for (BUN i = 0; i < nmask; i++) {
    1459     9883383 :                 if (cnt == 0 && r[i] != 0)
    1460       75899 :                         c->firstbit = candmask_lobit(r[i]) + i * 32;
    1461     9883383 :                 cnt += candmask_pop(r[i]);
    1462             :         }
    1463       75977 :         if (cnt > 0) {
    1464       75900 :                 assert(bn->tvheap == NULL);
    1465       75900 :                 bn->tvheap = msks;
    1466       75900 :                 bn->tseqbase += (oid) c->firstbit;
    1467             :         } else {
    1468             :                 /* no point having a mask if it's empty */
    1469          77 :                 HEAPfree(msks, true);
    1470          76 :                 GDKfree(msks);
    1471             :         }
    1472       75977 :         BATsetcount(bn, cnt);
    1473       75977 :         TRC_DEBUG(ALGO, "hseq=" OIDFMT ", masked=" ALGOBATFMT ", selected=%s"
    1474             :                   " -> " ALGOBATFMT "\n",
    1475             :                   hseq, ALGOBATPAR(masked),
    1476             :                   selected ? "true" : "false",
    1477             :                   ALGOBATPAR(bn));
    1478       75977 :         assert(bn->tseqbase != oid_nil);
    1479             :         return bn;
    1480             : }
    1481             : 
    1482             : /* convert a masked candidate list to a positive or negative candidate list */
    1483             : BAT *
    1484       78908 : BATunmask(BAT *b)
    1485             : {
    1486             : //      assert(!mask_cand(b) || CCAND(b)->mask); /* todo handle negmask case */
    1487       78908 :         BUN cnt;
    1488       78908 :         uint32_t rem;
    1489       78908 :         uint32_t val;
    1490       78908 :         const uint32_t *src;
    1491       78908 :         oid *dst;
    1492       78908 :         BUN n = 0;
    1493       78908 :         oid tseq = b->hseqbase;
    1494       78908 :         bool negcand = false;
    1495             : 
    1496       78908 :         BATiter bi = bat_iterator(b);
    1497       78908 :         if (mask_cand(b)) {
    1498       75245 :                 cnt = ccand_free(b) / sizeof(uint32_t);
    1499       75245 :                 rem = 0;
    1500       75245 :                 src = (const uint32_t *) ccand_first(b);
    1501       75245 :                 tseq = b->tseqbase;
    1502       75245 :                 tseq -= (oid) CCAND(b)->firstbit;
    1503             :                 /* create negative candidate list if more than half the
    1504             :                  * bits are set */
    1505       75245 :                 negcand = BATcount(b) > cnt * 16;
    1506             :         } else {
    1507        3663 :                 cnt = bi.count / 32;
    1508        3663 :                 rem = bi.count % 32;
    1509        3663 :                 src = (const uint32_t *) bi.base;
    1510             :         }
    1511       78908 :         BAT *bn;
    1512             : 
    1513       78908 :         if (negcand) {
    1514       63485 :                 bn = COLnew(b->hseqbase, TYPE_void, 0, TRANSIENT);
    1515       63485 :                 if (bn == NULL) {
    1516           0 :                         bat_iterator_end(&bi);
    1517           0 :                         return NULL;
    1518             :                 }
    1519       63485 :                 Heap *dels;
    1520       63485 :                 if ((dels = GDKmalloc(sizeof(Heap))) == NULL) {
    1521           0 :                         BBPreclaim(bn);
    1522           0 :                         bat_iterator_end(&bi);
    1523           0 :                         return NULL;
    1524             :                 }
    1525      126970 :                 *dels = (Heap) {
    1526       63485 :                         .farmid = BBPselectfarm(TRANSIENT, TYPE_void, varheap),
    1527       63485 :                         .parentid = bn->batCacheid,
    1528             :                         .dirty = true,
    1529             :                         .refs = ATOMIC_VAR_INIT(1),
    1530             :                 };
    1531       63485 :                 strconcat_len(dels->filename, sizeof(dels->filename),
    1532       63485 :                               BBP_physical(bn->batCacheid), ".theap", NULL);
    1533             : 
    1534      126970 :                 if (dels->farmid < 0 ||
    1535       63485 :                     HEAPalloc(dels, cnt * 32 - bi.count
    1536             :                               + sizeof(ccand_t) / sizeof(oid), sizeof(oid)) != GDK_SUCCEED) {
    1537           0 :                         GDKfree(dels);
    1538           0 :                         BBPreclaim(bn);
    1539           0 :                         bat_iterator_end(&bi);
    1540           0 :                         return NULL;
    1541             :                 }
    1542       63485 :                 * (ccand_t *) dels->base = (ccand_t) {
    1543             :                         .type = CAND_NEGOID,
    1544             :                 };
    1545       63485 :                 dst = (oid *) (dels->base + sizeof(ccand_t));
    1546     6429172 :                 for (BUN p = 0, v = 0; p < cnt; p++, v += 32) {
    1547     6365687 :                         if ((val = src[p]) == ~UINT32_C(0))
    1548     4991842 :                                 continue;
    1549    44234482 :                         for (uint32_t i = 0; i < 32; i++) {
    1550    42922383 :                                 if ((val & (1U << i)) == 0) {
    1551    39700355 :                                         if (v + i >= b->batCount + n)
    1552             :                                                 break;
    1553    39638609 :                                         dst[n++] = tseq + v + i;
    1554             :                                 }
    1555             :                         }
    1556             :                 }
    1557       63485 :                 if (n == 0) {
    1558             :                         /* didn't need it after all */
    1559           0 :                         HEAPfree(dels, true);
    1560           0 :                         GDKfree(dels);
    1561             :                 } else {
    1562       63485 :                         dels->free = sizeof(ccand_t) + n * sizeof(oid);
    1563       63485 :                         dels->dirty = true;
    1564       63485 :                         assert(bn->tvheap == NULL);
    1565       63485 :                         bn->tvheap = dels;
    1566             :                 }
    1567       63485 :                 BATsetcount(bn, n=bi.count);
    1568       63485 :                 bn->tseqbase = tseq;
    1569             :         } else {
    1570       15423 :                 bn = COLnew(b->hseqbase, TYPE_oid, mask_cand(b) ? bi.count : 1024, TRANSIENT);
    1571       15423 :                 if (bn == NULL) {
    1572           0 :                         bat_iterator_end(&bi);
    1573           0 :                         return NULL;
    1574             :                 }
    1575       15423 :                 dst = (oid *) Tloc(bn, 0);
    1576     1842223 :                 for (BUN p = 0; p < cnt; p++) {
    1577     1826800 :                         if ((val = src[p]) == 0)
    1578     1249816 :                                 continue;
    1579    19040472 :                         for (uint32_t i = 0; i < 32; i++) {
    1580    18463488 :                                 if (val & (1U << i)) {
    1581    16719025 :                                         if (n == BATcapacity(bn)) {
    1582          36 :                                                 BATsetcount(bn, n);
    1583          36 :                                                 if (BATextend(bn, BATgrows(bn)) != GDK_SUCCEED) {
    1584           0 :                                                         BBPreclaim(bn);
    1585           0 :                                                         bat_iterator_end(&bi);
    1586           0 :                                                         return NULL;
    1587             :                                                 }
    1588          36 :                                                 dst = (oid *) Tloc(bn, 0);
    1589             :                                         }
    1590    16719025 :                                         dst[n++] = tseq + p * 32 + i;
    1591             :                                 }
    1592             :                         }
    1593             :                 }
    1594             :                 /* the last partial mask word */
    1595       15423 :                 if (rem > 0 && (val = src[cnt]) != 0) {
    1596       18563 :                         for (uint32_t i = 0; i < rem; i++) {
    1597       16459 :                                 if (val & (1U << i)) {
    1598         770 :                                         if (n == BATcapacity(bn)) {
    1599           0 :                                                 BATsetcount(bn, n);
    1600           0 :                                                 if (BATextend(bn, BATgrows(bn)) != GDK_SUCCEED) {
    1601           0 :                                                         BBPreclaim(bn);
    1602           0 :                                                         bat_iterator_end(&bi);
    1603           0 :                                                         return NULL;
    1604             :                                                 }
    1605           0 :                                                 dst = (oid *) Tloc(bn, 0);
    1606             :                                         }
    1607         770 :                                         dst[n++] = tseq + cnt * 32 + i;
    1608             :                                 }
    1609             :                         }
    1610             :                 }
    1611       15423 :                 BATsetcount(bn, n);
    1612             :         }
    1613       78908 :         bat_iterator_end(&bi);
    1614       78908 :         bn->tkey = true;
    1615       78908 :         bn->tsorted = true;
    1616       78908 :         bn->trevsorted = n <= 1;
    1617       78908 :         bn->tnil = false;
    1618       78908 :         bn->tnonil = true;
    1619       78908 :         bn = virtualize(bn);
    1620       78908 :         TRC_DEBUG(ALGO, ALGOBATFMT " -> " ALGOBATFMT "\n", ALGOBATPAR(b), ALGOBATPAR(bn));
    1621             :         return bn;
    1622             : }

Generated by: LCOV version 1.14