LCOV - code coverage report
Current view: top level - gdk - gdk_cross.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 108 124 87.1 %
Date: 2024-04-25 20:03:45 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "gdk.h"
      15             : #include "gdk_private.h"
      16             : 
      17             : /* Calculate a cross product between bats l and r with optional
      18             :  * candidate lists sl for l and sr for r.
      19             :  * The result is two bats r1 and r2 which contain the OID (head
      20             :  * values) of the input bats l and r.
      21             :  * If max_one is set, r can have at most one row. */
      22             : static gdk_return
      23       26567 : BATcrossci(BAT **r1p, BAT **r2p, struct canditer *ci1, struct canditer *ci2)
      24             : {
      25       26567 :         BAT *bn1, *bn2 = NULL;
      26       26567 :         oid *restrict p;
      27       26567 :         BUN i, j;
      28             : 
      29       26567 :         lng timeoffset = 0;
      30       26567 :         QryCtx *qry_ctx = MT_thread_get_qry_ctx();
      31       26567 :         if (qry_ctx != NULL) {
      32       26024 :                 timeoffset = (qry_ctx->starttime && qry_ctx->querytimeout) ? (qry_ctx->starttime + qry_ctx->querytimeout) : 0;
      33             :         }
      34             : 
      35             :         /* first some special cases */
      36       26567 :         if (ci1->ncand == 0 || ci2->ncand == 0) {
      37        9652 :                 if ((bn1 = BATdense(0, 0, 0)) == NULL)
      38             :                         return GDK_FAIL;
      39        9654 :                 if (r2p) {
      40        9145 :                         if ((bn2 = BATdense(0, 0, 0)) == NULL) {
      41           0 :                                 BBPreclaim(bn1);
      42           0 :                                 return GDK_FAIL;
      43             :                         }
      44        9144 :                         *r2p = bn2;
      45             :                 }
      46        9653 :                 *r1p = bn1;
      47        9653 :                 return GDK_SUCCEED;
      48             :         }
      49       16915 :         if (ci2->ncand == 1) {
      50       10498 :                 if ((bn1 = canditer_slice(ci1, 0, ci1->ncand)) == NULL)
      51             :                         return GDK_FAIL;
      52       10497 :                 if (r2p) {
      53       10063 :                         if (ci1->ncand == 1) {
      54        3150 :                                 bn2 = canditer_slice(ci2, 0, ci2->ncand);
      55             :                         } else {
      56        6913 :                                 bn2 = BATconstant(0, TYPE_oid, &ci2->seq, ci1->ncand, TRANSIENT);
      57             :                         }
      58       10064 :                         if (bn2 == NULL) {
      59           0 :                                 BBPreclaim(bn1);
      60           0 :                                 return GDK_FAIL;
      61             :                         }
      62       10064 :                         *r2p = bn2;
      63             :                 }
      64       10498 :                 *r1p = bn1;
      65       10498 :                 return GDK_SUCCEED;
      66             :         }
      67        6417 :         if (ci1->ncand == 1) {
      68        1618 :                 bn1 = BATconstant(0, TYPE_oid, &ci1->seq, ci2->ncand, TRANSIENT);
      69        1618 :                 if (bn1 == NULL)
      70             :                         return GDK_FAIL;
      71        1618 :                 if (r2p) {
      72        1490 :                         bn2 = canditer_slice(ci2, 0, ci2->ncand);
      73        1490 :                         if (bn2 == NULL) {
      74           0 :                                 BBPreclaim(bn1);
      75           0 :                                 return GDK_FAIL;
      76             :                         }
      77        1490 :                         *r2p = bn2;
      78             :                 }
      79        1618 :                 *r1p = bn1;
      80        1618 :                 return GDK_SUCCEED;
      81             :         }
      82             : 
      83        4799 :         bn1 = COLnew(0, TYPE_oid, ci1->ncand * ci2->ncand, TRANSIENT);
      84        4799 :         if (r2p)
      85        4496 :                 bn2 = COLnew(0, TYPE_oid, ci1->ncand * ci2->ncand, TRANSIENT);
      86        4798 :         if (bn1 == NULL || (r2p && bn2 == NULL)) {
      87           0 :                 BBPreclaim(bn1);
      88           0 :                 BBPreclaim(bn2);
      89           0 :                 return GDK_FAIL;
      90             :         }
      91        4798 :         if (ci1->ncand > 0 && ci2->ncand > 0) {
      92        4798 :                 BATsetcount(bn1, ci1->ncand * ci2->ncand);
      93        4797 :                 bn1->tsorted = true;
      94        4797 :                 bn1->trevsorted = ci1->ncand <= 1;
      95        4797 :                 bn1->tkey = ci2->ncand <= 1;
      96        4797 :                 bn1->tnil = false;
      97        4797 :                 bn1->tnonil = true;
      98        4797 :                 p = (oid *) Tloc(bn1, 0);
      99      277015 :                 for (i = 0; i < ci1->ncand; i++) {
     100      272216 :                         GDK_CHECK_TIMEOUT_BODY(timeoffset, GOTO_LABEL_TIMEOUT_HANDLER(bailout));
     101      272212 :                         oid x = canditer_next(ci1);
     102     8769367 :                         for (j = 0; j < ci2->ncand; j++) {
     103     8224937 :                                 *p++ = x;
     104             :                         }
     105             :                 }
     106        4799 :                 BATtseqbase(bn1, ci2->ncand == 1 ? *(oid *) Tloc(bn1, 0) : oid_nil);
     107             : 
     108        4799 :                 if (bn2) {
     109        4496 :                         BATsetcount(bn2, ci1->ncand * ci2->ncand);
     110        4496 :                         bn2->tsorted = ci1->ncand <= 1 || ci2->ncand <= 1;
     111        4496 :                         bn2->trevsorted = ci2->ncand <= 1;
     112        4496 :                         bn2->tkey = ci1->ncand <= 1;
     113        4496 :                         bn2->tnil = false;
     114        4496 :                         bn2->tnonil = true;
     115        4496 :                         p = (oid *) Tloc(bn2, 0);
     116      241297 :                         for (i = 0; i < ci1->ncand; i++) {
     117      236801 :                                 GDK_CHECK_TIMEOUT_BODY(timeoffset, GOTO_LABEL_TIMEOUT_HANDLER(bailout));
     118     2339580 :                                 for (j = 0; j < ci2->ncand; j++) {
     119     2102796 :                                         *p++ = canditer_next(ci2);
     120             :                                 }
     121      236784 :                                 canditer_reset(ci2);
     122             :                         }
     123        4496 :                         BATtseqbase(bn2, ci1->ncand == 1 ? *(oid *) Tloc(bn2, 0) : oid_nil);
     124             :                 }
     125             :         }
     126        4799 :         *r1p = bn1;
     127        4799 :         if (r2p)
     128        4496 :                 *r2p = bn2;
     129        4799 :         if (r2p)
     130        4496 :                 TRC_DEBUG(ALGO, "BATsubcross()=(" ALGOBATFMT "," ALGOBATFMT ")\n", ALGOBATPAR(bn1), ALGOBATPAR(bn2));
     131             :         else
     132         303 :                 TRC_DEBUG(ALGO, "BATsubcross()=(" ALGOBATFMT ")\n", ALGOBATPAR(bn1));
     133             :         return GDK_SUCCEED;
     134             : 
     135           0 :   bailout:
     136           0 :         BBPreclaim(bn1);
     137           0 :         BBPreclaim(bn2);
     138             :         return GDK_FAIL;
     139             : }
     140             : 
     141             : gdk_return
     142       26294 : BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, bool max_one)
     143             : {
     144       26294 :         struct canditer ci1, ci2;
     145             : 
     146       26294 :         canditer_init(&ci1, l, sl);
     147       26293 :         canditer_init(&ci2, r, sr);
     148       26292 :         if (max_one && ci1.ncand > 0 && ci2.ncand > 1) {
     149          76 :                 GDKerror("more than one match");
     150          76 :                 return GDK_FAIL;
     151             :         }
     152       26216 :         return BATcrossci(r1p, r2p, &ci1, &ci2);
     153             : }
     154             : 
     155             : /* [left] outer cross */
     156             : gdk_return
     157         396 : BAToutercross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, bool max_one)
     158             : {
     159         396 :         struct canditer ci1, ci2;
     160             : 
     161         396 :         canditer_init(&ci1, l, sl);
     162         396 :         canditer_init(&ci2, r, sr);
     163         396 :         if (max_one && ci1.ncand > 0 && ci2.ncand > 1) {
     164           0 :                 GDKerror("more than one match");
     165           0 :                 return GDK_FAIL;
     166             :         }
     167             : 
     168         396 :         if (ci1.ncand == 0) {
     169          14 :                 BAT *bn = COLnew(0, TYPE_void, 0, TRANSIENT);
     170          14 :                 if (bn == NULL)
     171             :                         return GDK_FAIL;
     172          14 :                 BATtseqbase(bn, oid_nil);
     173          14 :                 *r1p = bn;
     174          14 :                 if (r2p) {
     175          14 :                         bn = COLnew(0, TYPE_void, 0, TRANSIENT);
     176          14 :                         if (bn == NULL) {
     177           0 :                                 BBPreclaim(*r1p);
     178           0 :                                 return GDK_FAIL;
     179             :                         }
     180          14 :                         BATtseqbase(bn, oid_nil);
     181          14 :                         *r2p = bn;
     182             :                 }
     183          14 :                 return GDK_SUCCEED;
     184             :         }
     185         382 :         if (ci2.ncand == 0) {
     186          31 :                 BAT *bn = canditer_slice(&ci1, 0, ci1.ncand);
     187          31 :                 if (bn == NULL)
     188             :                         return GDK_FAIL;
     189          31 :                 *r1p = bn;
     190          31 :                 if (r2p) {
     191          31 :                         BAT *bn = COLnew(0, TYPE_void, ci1.ncand, TRANSIENT);
     192          31 :                         if (bn == NULL)
     193             :                                 return GDK_FAIL;
     194          31 :                         BATtseqbase(bn, oid_nil);
     195          31 :                         BATsetcount(bn, ci1.ncand);
     196          31 :                         *r2p = bn;
     197             :                 }
     198          31 :                 return GDK_SUCCEED;
     199             :         }
     200         351 :         return BATcrossci(r1p, r2p, &ci1, &ci2);
     201             : }

Generated by: LCOV version 1.14