Changeset: c834858ede28 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c834858ede28
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
        clients/Tests/exports.stable.out
        gdk/ChangeLog.Jun2020
        gdk/gdk.h
        gdk/gdk_project.c
        monetdb5/modules/kernel/algebra.c
        monetdb5/modules/kernel/algebra.h
        monetdb5/modules/kernel/algebra.mal
Branch: Jun2020
Log Message:

New function BATproject2, aka algebra.projection2.
This function has two "right" arguments which should follow each other.


diffs (truncated from 672 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -611,6 +611,7 @@ stdout of test 'MAL-signatures` in direc
 [ "algebra",   "outerjoin",    "command algebra.outerjoin(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) 
(X_0:bat[:oid], X_1:bat[:oid]) ",   "ALGouterjoin;",        "Left outer join 
with candidate lists"  ]
 [ "algebra",   "project",      "pattern algebra.project(b:bat[:any_1], 
v:any_3):bat[:any_3] ", "ALGprojecttail;",      "Fill the tail with a constant" 
]
 [ "algebra",   "projection",   "command algebra.projection(left:bat[:oid], 
right:bat[:any_3]):bat[:any_3] ",   "ALGprojection;",       "Project left input 
onto right input."  ]
+[ "algebra",   "projection2",  "command algebra.projection2(left:bat[:oid], 
right1:bat[:any_3], right2:bat[:any_3]):bat[:any_3] ",     "ALGprojection2;",   
   "Project left input onto right inputs which should be consecutive."     ]
 [ "algebra",   "projectionpath",       "pattern 
algebra.projectionpath(l:bat[:any]...):bat[:any] ",    "ALGprojectionpath;",   
"Routine to handle join paths.  The type analysis is rather tricky."    ]
 [ "algebra",   "rangejoin",    "command algebra.rangejoin(l:bat[:any_1], 
r1:bat[:any_1], r2:bat[:any_1], sl:bat[:oid], sr:bat[:oid], li:bit, hi:bit, 
anti:bit, symmetric:bit, estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ",  
"ALGrangejoin;",        "Range join: values in l and r1/r2 match if r1 <[=] l 
<[=] r2"  ]
 [ "algebra",   "reuse",        "command 
algebra.reuse(b:bat[:any_1]):bat[:any_1] ",    "ALGreuse;",    "Reuse a 
temporary BAT if you can. Otherwise,\n\tallocate enough storage to accept 
result of an\n \toperation (not involving the heap)" ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -720,6 +720,7 @@ stdout of test 'MAL-signatures` in direc
 [ "algebra",   "outerjoin",    "command algebra.outerjoin(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) 
(X_0:bat[:oid], X_1:bat[:oid]) ",   "ALGouterjoin;",        "Left outer join 
with candidate lists"  ]
 [ "algebra",   "project",      "pattern algebra.project(b:bat[:any_1], 
v:any_3):bat[:any_3] ", "ALGprojecttail;",      "Fill the tail with a constant" 
]
 [ "algebra",   "projection",   "command algebra.projection(left:bat[:oid], 
right:bat[:any_3]):bat[:any_3] ",   "ALGprojection;",       "Project left input 
onto right input."  ]
+[ "algebra",   "projection2",  "command algebra.projection2(left:bat[:oid], 
right1:bat[:any_3], right2:bat[:any_3]):bat[:any_3] ",     "ALGprojection2;",   
   "Project left input onto right inputs which should be consecutive."     ]
 [ "algebra",   "projectionpath",       "pattern 
algebra.projectionpath(l:bat[:any]...):bat[:any] ",    "ALGprojectionpath;",   
"Routine to handle join paths.  The type analysis is rather tricky."    ]
 [ "algebra",   "rangejoin",    "command algebra.rangejoin(l:bat[:any_1], 
r1:bat[:any_1], r2:bat[:any_1], sl:bat[:oid], sr:bat[:oid], li:bit, hi:bit, 
anti:bit, symmetric:bit, estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ",  
"ALGrangejoin;",        "Range join: values in l and r1/r2 match if r1 <[=] l 
<[=] r2"  ]
 [ "algebra",   "reuse",        "command 
algebra.reuse(b:bat[:any_1]):bat[:any_1] ",    "ALGreuse;",    "Reuse a 
temporary BAT if you can. Otherwise,\n\tallocate enough storage to accept 
result of an\n \toperation (not involving the heap)" ]
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -169,7 +169,8 @@ gdk_return BATouterjoin(BAT **r1p, BAT *
 gdk_return BATprint(stream *s, BAT *b);
 gdk_return BATprintcolumns(stream *s, int argc, BAT *argv[]);
 gdk_return BATprod(void *res, int tp, BAT *b, BAT *s, bool skip_nils, bool 
abort_on_error, bool nil_if_empty);
-BAT *BATproject(BAT *l, BAT *r);
+BAT *BATproject(BAT *restrict l, BAT *restrict r);
+BAT *BATproject2(BAT *restrict l, BAT *restrict r1, BAT *restrict r2);
 BAT *BATprojectchain(BAT **bats);
 gdk_return BATrangejoin(BAT **r1p, BAT **r2p, BAT *l, BAT *rl, BAT *rh, BAT 
*sl, BAT *sr, bool li, bool hi, bool anti, bool symmetric, BUN estimate) 
__attribute__((__warn_unused_result__));
 gdk_return BATreplace(BAT *b, BAT *p, BAT *n, bool force) 
__attribute__((__warn_unused_result__));
@@ -820,6 +821,7 @@ str ALGminany(ptr result, const bat *bid
 str ALGminany_skipnil(ptr result, const bat *bid, const bit *skipnil);
 str ALGouterjoin(bat *r1, bat *r2, const bat *l, const bat *r, const bat *sl, 
const bat *sr, const bit *nil_matches, const lng *estimate);
 str ALGprojection(bat *result, const bat *lid, const bat *rid);
+str ALGprojection2(bat *result, const bat *lid, const bat *r1id, const bat 
*r2id);
 str ALGprojectionpath(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
 str ALGprojecttail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
 str ALGrangejoin(bat *r1, bat *r2, const bat *lid, const bat *rlid, const bat 
*rhid, const bat *slid, const bat *srid, const bit *li, const bit *hi, const 
bit *anti, const bit *symmetric, const lng *estimate);
diff --git a/gdk/ChangeLog.Jun2020 b/gdk/ChangeLog.Jun2020
--- a/gdk/ChangeLog.Jun2020
+++ b/gdk/ChangeLog.Jun2020
@@ -1,6 +1,10 @@
 # ChangeLog file for GDK
 # This file is updated with Maddlog
 
+* Mon Mar 30 2020 Sjoerd Mullender <[email protected]>
+- Implemented a version of BATproject, called BATproject2, with two
+  "right" arguments which conceptually follow each other.
+
 * Wed Mar 25 2020 Sjoerd Mullender <[email protected]>
 - Removed MT_mmap and MT_munmap from the list of exported functions.
   Use GDKmmap and GDKmunmap with the same parameters instead.
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2066,7 +2066,8 @@ gdk_export gdk_return BATbandjoin(BAT **
        __attribute__((__warn_unused_result__));
 gdk_export gdk_return BATrangejoin(BAT **r1p, BAT **r2p, BAT *l, BAT *rl, BAT 
*rh, BAT *sl, BAT *sr, bool li, bool hi, bool anti, bool symmetric, BUN 
estimate)
        __attribute__((__warn_unused_result__));
-gdk_export BAT *BATproject(BAT *l, BAT *r);
+gdk_export BAT *BATproject(BAT *restrict l, BAT *restrict r);
+gdk_export BAT *BATproject2(BAT *restrict l, BAT *restrict r1, BAT *restrict 
r2);
 gdk_export BAT *BATprojectchain(BAT **bats);
 
 gdk_export BAT *BATslice(BAT *b, BUN low, BUN high);
diff --git a/gdk/gdk_project.c b/gdk/gdk_project.c
--- a/gdk/gdk_project.c
+++ b/gdk/gdk_project.c
@@ -14,30 +14,48 @@
  * BATproject returns a BAT aligned with the left input whose values
  * are the values from the right input that were referred to by the
  * OIDs in the left input.
+ *
+ * BATproject2 is similar, except instead of a single right input
+ * there are two of which the second's hseqbase is equal to the first
+ * hseqbase + its batCount.
  */
 
 #define project_loop(TYPE)                                             \
 static gdk_return                                                      \
-project_##TYPE(BAT *bn, BAT *l, struct canditer *restrict ci, BAT *r)  \
+project_##TYPE(BAT *restrict bn, BAT *restrict l,                      \
+              struct canditer *restrict ci,                            \
+              BAT *restrict r1, BAT *restrict r2)                      \
 {                                                                      \
        BUN lo, hi;                                                     \
-       const TYPE *restrict rt;                                        \
+       const TYPE *restrict r1t;                                       \
+       const TYPE *restrict r2t;                                       \
        TYPE *restrict bt;                                              \
        TYPE v;                                                         \
-       oid rseq, rend;                                                 \
+       oid r1seq, r1end;                                               \
+       oid r2seq, r2end;                                               \
                                                                        \
-       rt = (const TYPE *) Tloc(r, 0);                                 \
+       r1t = (const TYPE *) Tloc(r1, 0);                               \
+       r2t = r2 ? (const TYPE *) Tloc(r2, 0) : NULL;                   \
        bt = (TYPE *) Tloc(bn, 0);                                      \
-       rseq = r->hseqbase;                                             \
-       rend = rseq + BATcount(r);                                      \
+       r1seq = r1->hseqbase;                                           \
+       r1end = r1seq + BATcount(r1);                                   \
+       if (r2) {                                                       \
+               r2seq = r2->hseqbase;                                   \
+               r2end = r2seq + BATcount(r2);                           \
+       } else {                                                        \
+               r2seq = r2end = r1end;                                  \
+       }                                                               \
        if (ci) {                                                       \
                for (lo = 0, hi = ci->ncand; lo < hi; lo++) {           \
                        oid o = canditer_next(ci);                      \
-                       if (o < rseq || o >= rend) {                    \
+                       if (o < r1seq || o >= r2end) {                  \
                                GDKerror("BATproject: does not match 
always\n"); \
                                return GDK_FAIL;                        \
                        }                                               \
-                       v = rt[o - rseq];                               \
+                       if (o < r1end)                                  \
+                               v = r1t[o - r1seq];                     \
+                       else                                            \
+                               v = r2t[o - r2seq];                     \
                        bt[lo] = v;                                     \
                }                                                       \
        } else {                                                        \
@@ -46,11 +64,14 @@ project_##TYPE(BAT *bn, BAT *l, struct c
                        if (is_oid_nil(o[lo])) {                        \
                                bt[lo] = v = TYPE##_nil;                \
                                bn->tnil = true;                        \
-                       } else if (o[lo] < rseq || o[lo] >= rend) {     \
+                       } else if (o[lo] < r1seq || o[lo] >= r2end) {   \
                                GDKerror("BATproject: does not match 
always\n"); \
                                return GDK_FAIL;                        \
+                       } else if (o[lo] < r1end) {                     \
+                               v = r1t[o[lo] - r1seq];                 \
+                               bt[lo] = v;                             \
                        } else {                                        \
-                               v = rt[o[lo] - rseq];                   \
+                               v = r2t[o[lo] - r2seq];                 \
                                bt[lo] = v;                             \
                        }                                               \
                }                                                       \
@@ -72,83 +93,82 @@ project_loop(hge)
 #endif
 
 static gdk_return
-project_void(BAT *bn, BAT *l, struct canditer *restrict ci, BAT *r)
+project_oid(BAT *restrict bn, BAT *restrict l, struct canditer *restrict lci,
+           BAT *restrict r1, BAT *restrict r2)
 {
        BUN lo, hi;
        oid *restrict bt;
-       oid rseq, rend;
+       oid r1seq, r1end;
+       oid r2seq, r2end;
+       const oid *restrict r1t = NULL;
+       const oid *restrict r2t = NULL;
+       struct canditer r1ci = {0}, r2ci = {0};
 
-       assert(BATtdense(r));
-       rseq = r->hseqbase;
-       rend = rseq + BATcount(r);
+       if (r1->ttype == TYPE_void && r1->tvheap != NULL)
+               canditer_init(&r1ci, NULL, r1);
+       else if (!BATtdense(r1))
+               r1t = (const oid *) Tloc(r1, 0);
+       r1seq = r1->hseqbase;
+       r1end = r1seq + BATcount(r1);
+       if (r2) {
+               if (r2->ttype == TYPE_void && r2->tvheap != NULL)
+                       canditer_init(&r2ci, NULL, r2);
+               else if (!BATtdense(r2))
+                       r2t = (const oid *) Tloc(r2, 0);
+               r2seq = r2->hseqbase;
+               r2end = r2seq + BATcount(r2);
+       } else {
+               r2seq = r2end = r1end;
+       }
        bt = (oid *) Tloc(bn, 0);
-       bn->tnonil = true;
-       if (ci) {
-               for (lo = 0, hi = ci->ncand; lo < hi; lo++) {
-                       oid o = canditer_next(ci);
-                       if (o < rseq || o >= rend) {
+       if (lci) {
+               for (lo = 0, hi = lci->ncand; lo < hi; lo++) {
+                       oid o = canditer_next(lci);
+                       if (o < r1seq || o >= r2end) {
                                GDKerror("BATproject: does not match always\n");
                                return GDK_FAIL;
                        }
-                       bt[lo] = o - rseq + r->tseqbase;
-               }
-       } else {
-               const oid *o = (const oid *) Tloc(l, 0);
-               for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
-                       if (o[lo] < rseq || o[lo] >= rend) {
-                               if (is_oid_nil(o[lo])) {
-                                       bt[lo] = oid_nil;
-                                       bn->tnonil = false;
-                                       bn->tnil = true;
-                               } else {
-                                       GDKerror("BATproject: does not match 
always\n");
-                                       return GDK_FAIL;
-                               }
+                       if (o < r1end) {
+                               if (r1ci.s)
+                                       bt[lo] = canditer_idx(&r1ci, o - r1seq);
+                               else if (r1t)
+                                       bt[lo] = r1t[o - r1seq];
+                               else
+                                       bt[lo] = o - r1seq + r1->tseqbase;
                        } else {
-                               bt[lo] = o[lo] - rseq + r->tseqbase;
+                               if (r2ci.s)
+                                       bt[lo] = canditer_idx(&r2ci, o - r2seq);
+                               else if (r2t)
+                                       bt[lo] = r2t[o - r2seq];
+                               else
+                                       bt[lo] = o - r2seq + r2->tseqbase;
                        }
                }
-       }
-       BATsetcount(bn, lo);
-       return GDK_SUCCEED;
-}
-
-static gdk_return
-project_cand(BAT *bn, BAT *l, struct canditer *restrict lci, BAT *r)
-{
-       BUN lo, hi;
-       oid *restrict bt;
-       oid rseq, rend;
-       struct canditer rci;
-
-       rseq = r->hseqbase;
-       rend = rseq + BATcount(r);
-       canditer_init(&rci, NULL, r);
-       bt = (oid *) Tloc(bn, 0);
-       bn->tnonil = true;
-       if (lci) {
-               for (lo = 0, hi = lci->ncand; lo < hi; lo++) {
-                       oid o = canditer_next(lci);
-                       if (o < rseq || o >= rend) {
+       } else {
+               const oid *ot = (const oid *) Tloc(l, 0);
+               for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+                       oid o = ot[lo];
+                       if (is_oid_nil(o)) {
+                               bt[lo] = oid_nil;
+                               bn->tnonil = false;
+                               bn->tnil = true;
+                       } else if (o < r1seq || o >= r2end) {
                                GDKerror("BATproject: does not match always\n");
                                return GDK_FAIL;
-                       }
-                       bt[lo] = canditer_idx(&rci, o - rseq);
-               }
-       } else {
-               const oid *o = (const oid *) Tloc(l, 0);
-               for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
-                       if (o[lo] < rseq || o[lo] >= rend) {
-                               if (is_oid_nil(o[lo])) {
-                                       bt[lo] = oid_nil;
-                                       bn->tnonil = false;
-                                       bn->tnil = true;
-                               } else {
-                                       GDKerror("BATproject: does not match 
always\n");
-                                       return GDK_FAIL;
-                               }
+                       } else if (o < r1end) {
+                               if (r1ci.s)
+                                       bt[lo] = canditer_idx(&r1ci, o - r1seq);
+                               else if (r1t)
+                                       bt[lo] = r1t[o - r1seq];
+                               else
+                                       bt[lo] = o - r1seq + r1->tseqbase;
                        } else {
-                               bt[lo] = canditer_idx(&rci, o[lo] - rseq);
+                               if (r2ci.s)
+                                       bt[lo] = canditer_idx(&r2ci, o - r2seq);
+                               else if (r2t)
+                                       bt[lo] = r2t[o - r2seq];
+                               else
+                                       bt[lo] = o - r2seq + r2->tseqbase;
                        }
                }
        }
@@ -157,25 +177,37 @@ project_cand(BAT *bn, BAT *l, struct can
 }
 
 static gdk_return
-project_any(BAT *bn, BAT *l, struct canditer *restrict ci, BAT *r)
+project_any(BAT *restrict bn, BAT *restrict l, struct canditer *restrict ci,
+           BAT *restrict r1, BAT *restrict r2)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to