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 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | #include "monetdb_config.h" |
10 | #include "gdk.h" |
11 | #include "gdk_private.h" |
12 | |
13 | /* Calculate a cross product between bats l and r with optional |
14 | * candidate lists sl for l and sr for r. |
15 | * The result is two bats r1 and r2 which contain the OID (head |
16 | * values) of the input bats l and r. */ |
17 | gdk_return |
18 | BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr) |
19 | { |
20 | BAT *bn1, *bn2; |
21 | struct canditer ci1, ci2; |
22 | BUN cnt1, cnt2; |
23 | oid *restrict p; |
24 | BUN i, j; |
25 | |
26 | cnt1 = canditer_init(&ci1, l, sl); |
27 | cnt2 = canditer_init(&ci2, r, sr); |
28 | |
29 | bn1 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT); |
30 | bn2 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT); |
31 | if (bn1 == NULL || bn2 == NULL) { |
32 | BBPreclaim(bn1); |
33 | BBPreclaim(bn2); |
34 | return GDK_FAIL; |
35 | } |
36 | if (cnt1 > 0 && cnt2 > 0) { |
37 | BATsetcount(bn1, cnt1 * cnt2); |
38 | bn1->tsorted = true; |
39 | bn1->trevsorted = cnt1 <= 1; |
40 | bn1->tkey = cnt2 <= 1; |
41 | bn1->tnil = false; |
42 | bn1->tnonil = true; |
43 | p = (oid *) Tloc(bn1, 0); |
44 | for (i = 0; i < cnt1; i++) { |
45 | oid x = canditer_next(&ci1); |
46 | for (j = 0; j < cnt2; j++) { |
47 | *p++ = x; |
48 | } |
49 | } |
50 | BATtseqbase(bn1, cnt2 == 1 ? *(oid *) Tloc(bn1, 0) : oid_nil); |
51 | |
52 | BATsetcount(bn2, cnt1 * cnt2); |
53 | bn2->tsorted = cnt1 <= 1 || cnt2 <= 1; |
54 | bn2->trevsorted = cnt2 <= 1; |
55 | bn2->tkey = cnt1 <= 1; |
56 | bn2->tnil = false; |
57 | bn2->tnonil = true; |
58 | p = (oid *) Tloc(bn2, 0); |
59 | for (i = 0; i < cnt1; i++) { |
60 | for (j = 0; j < cnt2; j++) { |
61 | *p++ = canditer_next(&ci2); |
62 | } |
63 | canditer_reset(&ci2); |
64 | } |
65 | BATtseqbase(bn2, cnt1 == 1 ? *(oid *) Tloc(bn2, 0) : oid_nil); |
66 | } |
67 | *r1p = bn1; |
68 | *r2p = bn2; |
69 | ALGODEBUG fprintf(stderr, "#BATsubcross()=(" ALGOBATFMT "," ALGOBATFMT ")\n" , ALGOBATPAR(bn1), ALGOBATPAR(bn2)); |
70 | return GDK_SUCCEED; |
71 | } |
72 | |