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
