LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - batExtensions.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 113 154 73.4 %
Date: 2021-10-27 03:06:47 Functions: 9 10 90.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * M.L.Kersten
      11             :  * BAT Algebra Extensions
      12             :  * The kernel libraries are unaware of the MAL runtime semantics.
      13             :  * This calls for declaring some operations in the MAL module section
      14             :  * and register them in the kernel modules explicitly.
      15             :  *
      16             :  * A good example of this borderline case are BAT creation operations,
      17             :  * which require a mapping of the type identifier to the underlying
      18             :  * implementation type.
      19             :  *
      20             :  * Another example concerns the (un)pack operations, which direct
      21             :  * access the runtime stack to (push)pull the values needed.
      22             :  */
      23             : #include "monetdb_config.h"
      24             : #include "mal_client.h"
      25             : #include "mal_interpreter.h"
      26             : #include "bat5.h"
      27             : #include "gdk_time.h"
      28             : #include "mal_instruction.h"
      29             : #include "mal_exception.h"
      30             : 
      31             : /*
      32             :  * BAT enhancements
      33             :  * The code to enhance the kernel.
      34             :  */
      35             : 
      36             : static str
      37      164742 : CMDBATnew(Client cntxt, MalBlkPtr m, MalStkPtr s, InstrPtr p){
      38             :         int tt;
      39             :         role_t kind = TRANSIENT;
      40      164742 :         BUN cap = 0;
      41             :         bat *res;
      42             : 
      43             :         (void) cntxt;
      44      164742 :         res = getArgReference_bat(s, p, 0);
      45      164742 :         tt = getArgType(m, p, 1);
      46      164742 :         if (p->argc > 2) {
      47             :                 lng lcap;
      48             : 
      49           2 :                 if (getArgType(m, p, 2) == TYPE_lng)
      50           0 :                         lcap = *getArgReference_lng(s, p, 2);
      51           2 :                 else if (getArgType(m, p, 2) == TYPE_int)
      52           2 :                         lcap = (lng) *getArgReference_int(s, p, 2);
      53             :                 else
      54           0 :                         throw(MAL, "bat.new", ILLEGAL_ARGUMENT " Incorrect type for size");
      55           2 :                 if (lcap < 0)
      56           0 :                         throw(MAL, "bat.new", POSITIVE_EXPECTED);
      57           2 :                 if (lcap > (lng) BUN_MAX)
      58           0 :                         throw(MAL, "bat.new", ILLEGAL_ARGUMENT " Capacity too large");
      59           2 :                 cap = (BUN) lcap;
      60           2 :                 if( p->argc == 4 && getVarConstant(m,getArg(p,3)).val.ival)
      61             :                         kind = PERSISTENT;
      62             :         }
      63             : 
      64      164742 :         if (tt == TYPE_any || isaBatType(tt))
      65           0 :                 throw(MAL, "bat.new", SEMANTIC_TYPE_ERROR);
      66      164743 :         return (str) BKCnewBAT(res,  &tt, &cap, kind);
      67             : }
      68             : 
      69             : static str
      70         410 : CMDBATdup(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      71             : {
      72             :         BAT *b, *i;
      73         410 :         bat *ret= getArgReference_bat(stk, pci, 0);
      74         410 :         int tt = getArgType(mb, pci, 1);
      75         410 :         bat input = *getArgReference_bat(stk, pci, 2);
      76             : 
      77             :         (void)cntxt;
      78         410 :         if ((i = BBPquickdesc(input)) == NULL)
      79           0 :                 throw(MAL, "bat.new", INTERNAL_BAT_ACCESS);
      80         410 :         b = COLnew(i->hseqbase, tt, BATcount(i), TRANSIENT);
      81         410 :         if (b == 0)
      82           0 :                 throw(MAL,"bat.new", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      83         410 :         *ret = b->batCacheid;
      84         410 :         BATsettrivprop(b);
      85         410 :         BBPretain(b->batCacheid);
      86         410 :         BBPunfix(b->batCacheid);
      87         410 :         return MAL_SUCCEED;
      88             : }
      89             : 
      90             : static str
      91        5850 : CMDBATsingle(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      92             : {
      93             :         BAT *b;
      94        5850 :         int * ret= getArgReference_bat(stk,pci,0);
      95        5850 :         void *u =(void*) getArgReference(stk,pci,1);
      96             : 
      97             :         (void)cntxt;
      98             : 
      99        5851 :         b = COLnew(0,getArgType(mb,pci,1),0, TRANSIENT);
     100        5850 :         if( b == 0)
     101           0 :                 throw(MAL,"bat.single", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     102        5850 :         if (ATOMextern(b->ttype))
     103        1558 :                 u = (ptr) *(str *)u;
     104        5850 :         if (BUNappend(b, u, false) != GDK_SUCCEED) {
     105           0 :                 BBPreclaim(b);
     106           0 :                 throw(MAL, "bat.single", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     107             :         }
     108        5846 :         BBPkeepref(*ret = b->batCacheid);
     109        5850 :         return MAL_SUCCEED;
     110             : }
     111             : 
     112             : /* If the optimizer has not determined the partition bounds we derive one here.  */
     113             : static str
     114           2 : CMDBATpartition(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     115             : {
     116             :         BAT *b,*bn;
     117             :         bat *ret;
     118             :         int i;
     119             :         bat bid;
     120             :         oid lval,hval=0, step;
     121             : 
     122             :         (void) mb;
     123             :         (void) cntxt;
     124           2 :         bid = *getArgReference_bat(stk, pci, pci->retc);
     125             : 
     126           2 :         if ((b = BATdescriptor(bid)) == NULL) {
     127           0 :                 throw(MAL, "bat.partition", INTERNAL_BAT_ACCESS);
     128             :         }
     129           2 :         step = BATcount(b) / pci->retc + 1;
     130             : 
     131             :         /* create the slices slightly overshoot to make sure it all is taken*/
     132           5 :         for(i=0; i<pci->retc; i++){
     133           3 :                 lval = i*step;
     134           3 :                 hval = lval + step;
     135           3 :                 if (i == pci->retc-1)
     136           2 :                         hval = BATcount(b);
     137           3 :                 bn =  BATslice(b, lval,hval);
     138           3 :                 if (bn== NULL){
     139           0 :                         BBPunfix(b->batCacheid);
     140           0 :                         throw(MAL, "bat.partition", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     141             :                 }
     142           3 :                 BAThseqbase(bn, lval);
     143           3 :                 stk->stk[getArg(pci,i)].val.bval = bn->batCacheid;
     144           3 :                 ret= getArgReference_bat(stk,pci,i);
     145           3 :                 BBPkeepref(*ret = bn->batCacheid);
     146             :         }
     147           2 :         BBPunfix(b->batCacheid);
     148           2 :         return MAL_SUCCEED;
     149             : }
     150             : 
     151             : static str
     152           9 : CMDBATpartition2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     153             : {
     154             :         BAT *b,*bn;
     155             :         bat *ret,bid;
     156           9 :         int pieces= *getArgReference_int(stk, pci, 2);
     157           9 :         int idx = *getArgReference_int(stk, pci, 3);
     158             :         oid lval,hval=0, step;
     159             : 
     160             :         (void) mb;
     161             :         (void) cntxt;
     162           9 :         if ( pieces <=0 )
     163           0 :                 throw(MAL, "bat.partition", POSITIVE_EXPECTED);
     164           9 :         if ( idx >= pieces || idx <0 )
     165           1 :                 throw(MAL, "bat.partition", ILLEGAL_ARGUMENT " Illegal piece index");
     166             : 
     167           8 :         bid = *getArgReference_bat(stk, pci, pci->retc);
     168             : 
     169           8 :         if ((b = BATdescriptor(bid)) == NULL) {
     170           0 :                 throw(MAL, "bat.partition", INTERNAL_BAT_ACCESS);
     171             :         }
     172           8 :         step = BATcount(b) / pieces;
     173             : 
     174           8 :         lval = idx * step;
     175           8 :         if ( idx == pieces-1)
     176             :                 hval = BATcount(b);
     177             :         else
     178           4 :                 hval = lval+step;
     179           8 :         bn =  BATslice(b, lval,hval);
     180           8 :         BAThseqbase(bn, lval + b->hseqbase);
     181           8 :         BBPunfix(b->batCacheid);
     182           8 :         if (bn== NULL){
     183           0 :                 throw(MAL, "bat.partition",  INTERNAL_OBJ_CREATE);
     184             :         }
     185           8 :         ret= getArgReference_bat(stk,pci,0);
     186           8 :         BBPkeepref(*ret = bn->batCacheid);
     187           8 :         return MAL_SUCCEED;
     188             : }
     189             : 
     190             : static str
     191           1 : CMDBATimprints(void *ret, bat *bid)
     192             : {
     193             :         BAT *b;
     194             :         gdk_return r;
     195             : 
     196             :         (void) ret;
     197           1 :         if ((b = BATdescriptor(*bid)) == NULL)
     198           0 :                 throw(MAL, "bat.imprints", INTERNAL_BAT_ACCESS);
     199             : 
     200           1 :         r = BATimprints(b);
     201           1 :         BBPunfix(b->batCacheid);
     202           1 :         if (r != GDK_SUCCEED)
     203           0 :                 throw(MAL, "bat.imprints", GDK_EXCEPTION);
     204             :         return MAL_SUCCEED;
     205             : }
     206             : 
     207             : static str
     208           0 : CMDBATimprintsize(lng *ret, bat *bid)
     209             : {
     210             :         BAT *b;
     211             : 
     212           0 :         if ((b = BATdescriptor(*bid)) == NULL)
     213           0 :                 throw(MAL, "bat.imprints", INTERNAL_BAT_ACCESS);
     214             : 
     215           0 :         *ret = IMPSimprintsize(b);
     216           0 :         BBPunfix(b->batCacheid);
     217           0 :         return MAL_SUCCEED;
     218             : }
     219             : 
     220             : static str
     221        7000 : CMDBATappend_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     222             : {
     223        7000 :         bat *r = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 1);
     224        7000 :         bit force = *getArgReference_bit(stk, pci, 2);
     225             :         BAT *b;
     226        7000 :         BUN inputs = (BUN)(pci->argc - 3), number_existing = 0, total = 0;
     227             : 
     228             :         (void) cntxt;
     229        7000 :         if ((b = BATdescriptor(*bid)) == NULL)
     230           0 :                 throw(MAL, "bat.append_bulk", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     231             : 
     232        6998 :         if (inputs > 0) {
     233        6998 :                 number_existing = BATcount(b);
     234             : 
     235        6998 :                 if (isaBatType(getArgType(mb, pci, 3))) { /* use BATappend for the bulk case */
     236             :                         gdk_return rt;
     237           7 :                         for (int i = 3, args = pci->argc; i < args; i++) {
     238           5 :                                 BAT *d = BATdescriptor(*getArgReference_bat(stk, pci, i));
     239           5 :                                 if (!d) {
     240           0 :                                         BBPunfix(b->batCacheid);
     241           0 :                                         throw(MAL, "bat.append_bulk", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     242             :                                 }
     243           5 :                                 if (mask_cand(d)) {
     244             :                                         BAT *du = d;
     245           0 :                                         d = BATunmask(d);
     246           0 :                                         BBPunfix(du->batCacheid);
     247           0 :                                         if (!d) {
     248           0 :                                                 BBPunfix(b->batCacheid);
     249           0 :                                                 throw(MAL, "bat.append_bulk", GDK_EXCEPTION);
     250             :                                         }
     251             :                                 }
     252           5 :                                 rt = BATappend(b, d, NULL, force);
     253           5 :                                 BBPunfix(d->batCacheid);
     254           5 :                                 if (rt != GDK_SUCCEED) {
     255           0 :                                         BBPunfix(b->batCacheid);
     256           0 :                                         throw(MAL,"bat.append_bulk", GDK_EXCEPTION);
     257             :                                 }
     258             :                         }
     259             :                 } else {
     260        6996 :                         bool external = ATOMextern(b->ttype);
     261        6996 :                         total = number_existing + inputs;
     262        6996 :                         if (BATextend(b, total) != GDK_SUCCEED) {
     263           0 :                                 BBPunfix(b->batCacheid);
     264           0 :                                 throw(MAL,"bat.append_bulk", GDK_EXCEPTION);
     265             :                         }
     266      316298 :                         for (int i = 3, args = pci->argc; i < args; i++) {
     267      309300 :                                 ptr u = getArgReference(stk,pci,i);
     268      304150 :                                 if (external)
     269      124613 :                                         u = (ptr) *(ptr *) u;
     270      304150 :                                 if (BUNappend(b, u, force) != GDK_SUCCEED) {
     271           0 :                                         BBPunfix(b->batCacheid);
     272           0 :                                         throw(MAL,"bat.append_bulk", GDK_EXCEPTION);
     273             :                                 }
     274             :                         }
     275             :                 }
     276             :         }
     277             : 
     278        7000 :         *r = b->batCacheid;
     279        7000 :         BATsettrivprop(b);
     280        6999 :         BBPretain(b->batCacheid);
     281        7000 :         BBPunfix(b->batCacheid);
     282        7000 :         return MAL_SUCCEED;
     283             : }
     284             : 
     285             : static str
     286           1 : CMDBATvacuum(bat *r, const bat *bid)
     287             : {
     288             :         BAT *b, *bn;
     289             : 
     290           1 :         if ((b = BATdescriptor(*bid)) == NULL)
     291           0 :                 throw(MAL, "bat.vacuum", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     292           1 :         if ((bn = COLcopy(b, b->ttype, true, b->batRole)) == NULL) {
     293           0 :                 BBPunfix(b->batCacheid);
     294           0 :                 throw(MAL, "bat.vacuum", GDK_EXCEPTION);
     295             :         }
     296             : 
     297           1 :         BBPkeepref(*r = bn->batCacheid);
     298           1 :         BBPunfix(b->batCacheid);
     299           1 :         return MAL_SUCCEED;
     300             : }
     301             : 
     302             : #include "mel.h"
     303             : mel_func batExtensions_init_funcs[] = {
     304             :  pattern("bat", "new", CMDBATnew, false, "", args(1,2, batargany("",1),argany("tt",1))),
     305             :  pattern("bat", "new", CMDBATnew, false, "", args(1,3, batargany("",1),argany("tt",1),arg("size",int))),
     306             :  pattern("bat", "new", CMDBATnew, false, "", args(1,4, batargany("",1),argany("tt",1),arg("size",lng),arg("persist",bit))),
     307             :  pattern("bat", "new", CMDBATnew, false, "", args(1,4, batargany("",1),argany("tt",1),arg("size",int),arg("persist",bit))),
     308             :  pattern("bat", "new", CMDBATnew, false, "Creates a new empty transient BAT, with tail-types as indicated.", args(1,3, batargany("",1),argany("tt",1),arg("size",lng))),
     309             :  pattern("bat", "new", CMDBATdup, false, "Creates a new empty transient BAT, with tail-type tt and hseqbase and size from the input bat argument.", args(1,3, batargany("",1), argany("tt",1),batargany("i",2))),
     310             :  pattern("bat", "single", CMDBATsingle, false, "Create a BAT with a single elemenet", args(1,2, batargany("",1),argany("val",1))),
     311             :  pattern("bat", "partition", CMDBATpartition, false, "Create a serie of slices over the BAT argument. The BUNs are distributed evenly.", args(1,2, batvarargany("",1),batargany("b",1))),
     312             :  pattern("bat", "partition", CMDBATpartition2, false, "Create the n-th slice over the BAT broken into several pieces.", args(1,4, batargany("",1),batargany("b",1),arg("pieces",int),arg("n",int))),
     313             :  command("bat", "imprints", CMDBATimprints, false, "", args(1,2, arg("",void),batarg("b",bte))),
     314             :  command("bat", "imprints", CMDBATimprints, false, "", args(1,2, arg("",void),batarg("b",sht))),
     315             :  command("bat", "imprints", CMDBATimprints, false, "", args(1,2, arg("",void),batarg("b",int))),
     316             :  command("bat", "imprints", CMDBATimprints, false, "", args(1,2, arg("",void),batarg("b",lng))),
     317             :  command("bat", "imprints", CMDBATimprints, false, "", args(1,2, arg("",void),batarg("b",flt))),
     318             :  command("bat", "imprints", CMDBATimprints, false, "Check for existence or create an imprint index on the BAT.", args(1,2, arg("",void),batarg("b",dbl))),
     319             :  command("bat", "imprintsize", CMDBATimprintsize, false, "", args(1,2, arg("",lng),batarg("b",bte))),
     320             :  command("bat", "imprintsize", CMDBATimprintsize, false, "", args(1,2, arg("",lng),batarg("b",sht))),
     321             :  command("bat", "imprintsize", CMDBATimprintsize, false, "", args(1,2, arg("",lng),batarg("b",int))),
     322             :  command("bat", "imprintsize", CMDBATimprintsize, false, "", args(1,2, arg("",lng),batarg("b",lng))),
     323             :  command("bat", "imprintsize", CMDBATimprintsize, false, "", args(1,2, arg("",lng),batarg("b",flt))),
     324             :  command("bat", "imprintsize", CMDBATimprintsize, false, "Return the storage size of the imprints index structure.", args(1,2, arg("",lng),batarg("b",dbl))),
     325             : #ifdef HAVE_HGE
     326             :  command("bat", "imprints", CMDBATimprints, false, "", args(0,1, batarg("b",hge))),
     327             :  command("bat", "imprintsize", CMDBATimprintsize, false, "", args(1,2, arg("",lng),batarg("b",hge))),
     328             : #endif
     329             :  pattern("bat", "appendBulk", CMDBATappend_bulk, false, "append the arguments ins to i", args(1,4, batargany("",1), batargany("i",1),arg("force",bit),varargany("ins",1))),
     330             :  pattern("bat", "appendBulk", CMDBATappend_bulk, false, "append the arguments ins to i", args(1,4, batargany("",1), batargany("i",1),arg("force",bit),batvarargany("ins",1))),
     331             :  command("bat", "vacuum", CMDBATvacuum, false, "", args(1,2, batarg("",str),batarg("b",str))),
     332             :  { .imp=NULL }
     333             : };
     334             : #include "mal_import.h"
     335             : #ifdef _MSC_VER
     336             : #undef read
     337             : #pragma section(".CRT$XCU",read)
     338             : #endif
     339         257 : LIB_STARTUP_FUNC(init_batExtensions_mal)
     340         257 : { mal_module("batExtensions", NULL, batExtensions_init_funcs); }

Generated by: LCOV version 1.14