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 : /* This file is included multiple times. We expect the tokens UI, UU, UO, US
14 : * to be defined by the including file, and we expect that the
15 : * combination (UI,UU,UO,US) is unique to each inclusion. */
16 :
17 :
18 : /* ! ENSURE THAT THESE LOCAL MACROS ARE UNDEFINED AT THE END OF THIS FILE ! */
19 :
20 : /* concatenate two, three or five tokens */
21 : #define U_CONCAT_2(a,b) a##b
22 : #define U_CONCAT_3(a,b,c) a##b##c
23 : #define U_CONCAT_5(a,b,c,d,e) a##b##c##d##e
24 :
25 : /* function names, *_nil & TYPE_* macros */
26 : #define UF(p,i,o,s) U_CONCAT_5(p,i,_,o,s)
27 : #define UN(t) U_CONCAT_2(t,_nil)
28 : #define UT(t) U_CONCAT_2(TYPE_,t)
29 : #define NL(t) U_CONCAT_3(is_,t,_nil)
30 :
31 :
32 : /* scalar fuse */
33 :
34 : /* fuse two (shift-byte) in values into one (2*shift-byte) out value */
35 : /* actual implementation */
36 : static char *
37 6 : UF(UDFfuse_,UI,UO,_) ( UO *ret , UI one , UI two )
38 : {
39 6 : int shift = sizeof(UI) * 8;
40 :
41 : /* assert calling sanity */
42 6 : assert(ret != NULL);
43 :
44 6 : if (NL(UI)(one) || NL(UI)(two))
45 : /* NULL/nil in => NULL/nil out */
46 0 : *ret = UN(UO);
47 : else
48 : /* do the work; watch out for sign bits */
49 6 : *ret = ((UO) (UU) one << shift) | (UU) two;
50 :
51 6 : return MAL_SUCCEED;
52 : }
53 : /* MAL wrapper */
54 : char *
55 6 : UF(UDFfuse_,UI,UO,) ( UO *ret , const UI *one , const UI *two )
56 : {
57 : /* assert calling sanity */
58 6 : assert(ret != NULL && one != NULL && two != NULL);
59 :
60 6 : return UF(UDFfuse_,UI,UO,_) ( ret, *one, *two );
61 : }
62 :
63 : /* BAT fuse */
64 : /*
65 : * TYPE-expanded optimized version,
66 : * accessing value arrays directly.
67 : */
68 :
69 : /* type-specific core algorithm on arrays */
70 : static char *
71 8 : UF(UDFarrayfuse_,UI,UO,) ( UO *res, const UI *one, const UI *two, BUN n )
72 : {
73 8 : BUN i;
74 8 : int shift = sizeof(UI) * 8;
75 :
76 : /* assert calling sanity */
77 8 : assert(res != NULL && one != NULL && two != NULL);
78 :
79 : /* iterate over all values/tuples and do the work */
80 38 : for (i = 0; i < n; i++)
81 30 : if (NL(UI)(one[i]) || NL(UI)(two[i]))
82 : /* NULL/nil in => NULL/nil out */
83 0 : res[i] = UN(UO);
84 : else
85 : /* do the work; watch out for sign bits */
86 30 : res[i] = ((UO) (UU) one[i] << shift) | (UU) two[i];
87 :
88 8 : return MAL_SUCCEED;
89 : }
90 :
91 : /* type-specific core algorithm on BATs */
92 : static char *
93 8 : UF(UDFBATfuse_,UI,UO,) ( const BAT *bres, BAT *bone, BAT *btwo, BUN n,
94 : bit *two_tail_sorted_unsigned,
95 : bit *two_tail_revsorted_unsigned )
96 : {
97 8 : UI *one = NULL, *two = NULL;
98 8 : UO *res = NULL;
99 8 : str msg = NULL;
100 :
101 : /* assert calling sanity */
102 8 : assert(bres != NULL && bone != NULL && btwo != NULL);
103 8 : assert(BATcapacity(bres) >= n);
104 8 : assert(BATcount(bone) >= n && BATcount(btwo) >= n);
105 8 : assert(bone->ttype == UT(UI) && btwo->ttype == UT(UI));
106 8 : assert(bres->ttype == UT(UO));
107 :
108 : /* get direct access to the tail arrays */
109 8 : BATiter bonei = bat_iterator(bone);
110 8 : BATiter btwoi = bat_iterator(btwo);
111 8 : one = (UI*) bonei.base;
112 8 : two = (UI*) btwoi.base;
113 8 : res = (UO*) Tloc(bres, 0);
114 :
115 : /* call core function on arrays */
116 8 : msg = UF(UDFarrayfuse_,UI,UO,) ( res, one, two , n );
117 8 : if (msg == MAL_SUCCEED) {
118 16 : *two_tail_sorted_unsigned =
119 8 : btwoi.sorted && (two[0] >= 0 || two[n-1] < 0);
120 8 : *two_tail_revsorted_unsigned =
121 8 : btwoi.revsorted && (two[0] < 0 || two[n-1] >= 0);
122 : }
123 8 : bat_iterator_end(&bonei);
124 8 : bat_iterator_end(&btwoi);
125 8 : return msg;
126 : }
127 :
128 :
129 : /* undo local defines */
130 : #undef UT
131 : #undef UN
132 : #undef UF
133 : #undef NL
134 : #undef U_CONCAT_5
135 : #undef U_CONCAT_3
136 : #undef U_CONCAT_2
|