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 Bitvector Extensions
12 : * The current primitives are focused on the use of vectors as Candidate lists
13 : */
14 : #include "monetdb_config.h"
15 : #include "mal_client.h"
16 : #include "mal_interpreter.h"
17 : #include "bat5.h"
18 : #include "gdk_time.h"
19 : #include "mal_exception.h"
20 :
21 : /*
22 : * BAT bitvector enhancements
23 : * The code to enhance the kernel.
24 : */
25 :
26 : static str
27 0 : MSKmask(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
28 : {
29 : BAT *b, *dst;
30 : bat *bid;
31 : int *ret;
32 :
33 : (void) mb;
34 : (void) cntxt;
35 :
36 0 : ret = getArgReference_bat(stk, pci, 0);
37 0 : bid = getArgReference_bat(stk, pci, 1);
38 0 : if ((b = BATdescriptor(*bid)) == NULL)
39 0 : throw(SQL, "bat.mask", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
40 0 : if( !b->tkey || !b->tsorted ) {
41 0 : BBPunfix(b->batCacheid);
42 0 : throw(SQL, "bat.mask", SQLSTATE(HY002) "Input should be unique and in ascending order");
43 : }
44 0 : if (BATcount(b) == 0) {
45 0 : dst = COLnew(0, TYPE_msk, 0, TRANSIENT);
46 : } else {
47 : oid fst;
48 : BUN cap;
49 : BUN max = 0;
50 0 : if (b->tsorted) {
51 0 : fst = BUNtoid(b, 0);
52 0 : dst = COLnew(fst, TYPE_msk, BUNtoid(b, BUNlast(b) - 1) + 1 - fst, TRANSIENT);
53 : } else {
54 : fst = 0;
55 0 : dst = COLnew(0, TYPE_msk, BATcount(b), TRANSIENT);
56 : }
57 0 : cap = BATcapacity(b);
58 0 : if (dst) {
59 0 : memset(Tloc(dst, 0), 0, dst->theap->size);
60 0 : for (BUN p = 0; p < BATcount(b); p++) {
61 0 : oid o = BUNtoid(b, p);
62 0 : if (is_oid_nil(o)) {
63 0 : BBPunfix(b->batCacheid);
64 0 : BBPreclaim(dst);
65 0 : throw(MAL, "mask.mask", "no NULL allowed");
66 : }
67 0 : o -= fst;
68 0 : if (o >= cap) {
69 0 : if (BATextend(dst, o + 1) != GDK_SUCCEED) {
70 0 : BBPunfix(b->batCacheid);
71 0 : BBPreclaim(dst);
72 0 : throw(MAL, "mask.mask", GDK_EXCEPTION);
73 : }
74 0 : cap = BATcapacity(dst);
75 : }
76 : mskSetVal(dst, o, true);
77 : if (o > max)
78 : max = o;
79 : }
80 0 : BATsetcount(dst, max + 1);
81 0 : dst->tsorted = dst->trevsorted = false;
82 0 : dst->tkey = false;
83 0 : dst->tnil = false;
84 0 : dst->tnonil = true;
85 : }
86 : }
87 0 : BBPunfix(b->batCacheid);
88 0 : if (dst == NULL)
89 0 : throw(MAL, "mask.mask", GDK_EXCEPTION);
90 :
91 0 : *ret= dst->batCacheid;
92 0 : BBPkeepref(*ret);
93 0 : return MAL_SUCCEED;
94 : }
95 :
96 : static str
97 0 : MSKumask(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
98 : {
99 : BAT *b, *dst;
100 : bat *bid;
101 : int *ret;
102 :
103 : (void) mb;
104 : (void) cntxt;
105 :
106 0 : ret = getArgReference_bat(stk, pci, 0);
107 0 : bid = getArgReference_bat(stk, pci, 1);
108 0 : if ((b = BATdescriptor(*bid)) == NULL)
109 0 : throw(SQL, "bat.umask", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
110 0 : if (b->ttype != TYPE_msk && !mask_cand(b)) {
111 0 : BBPunfix(b->batCacheid);
112 0 : throw(MAL, "mask.umask", SQLSTATE(42000) "msk type input expected");
113 : }
114 0 : dst = BATunmask(b);
115 0 : BBPunfix(b->batCacheid);
116 0 : if (dst == NULL)
117 0 : throw(MAL, "mask.umask", GDK_EXCEPTION);
118 0 : *ret= dst->batCacheid;
119 0 : BBPkeepref(*ret);
120 0 : return MAL_SUCCEED;
121 : }
122 :
123 :
124 : #include "mel.h"
125 : mel_func batMask_init_funcs[] = {
126 : pattern("mask", "mask", MSKmask, false, "", args(1,2, batarg("r", msk), batarg("b",oid))),
127 : pattern("mask", "umask", MSKumask, false, "", args(1,2, batarg("r", oid), batarg("b",msk))),
128 : { .imp=NULL }
129 : };
130 : #include "mal_import.h"
131 : #ifdef _MSC_VER
132 : #undef read
133 : #pragma section(".CRT$XCU",read)
134 : #endif
135 257 : LIB_STARTUP_FUNC(init_batMask_mal)
136 257 : { mal_module("batMask", NULL, batMask_init_funcs); }
|