Changeset: a9bc9d620277 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a9bc9d620277
Modified Files:
clients/Tests/exports.stable.out
gdk/gdk.h
gdk/gdk_batop.c
monetdb5/modules/kernel/bat5.c
monetdb5/modules/kernel/bat5.h
monetdb5/modules/kernel/bat5.mal
monetdb5/modules/mal/Tests/inspect05.stable.out
Branch: default
Log Message:
Implemented bat.mergecand() and bat.intersectcand().
These functions merge/intersect two candidates lists.
diffs (truncated from 338 to 300 lines):
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
@@ -130,6 +130,7 @@ BAT *BAThash(BAT *b, BUN masksize);
BAT *BAThashjoin(BAT *l, BAT *r, BUN estimate);
BAT *BAThistogram(BAT *b);
BAT *BATins(BAT *b, BAT *c, bit force);
+BAT *BATintersectcand(BAT *a, BAT *b);
BAT *BATjoin(BAT *l, BAT *r, BUN estimate);
BAT *BATkdiff(BAT *b, BAT *c);
BAT *BATkey(BAT *b, int onoff);
@@ -144,6 +145,7 @@ BAT *BATmark_grp(BAT *b, BAT *g, oid *ba
BAT *BATmaterialize(BAT *b);
BAT *BATmaterializeh(BAT *b);
size_t BATmemsize(BAT *b, int dirty);
+BAT *BATmergecand(BAT *a, BAT *b);
BAT *BATmergejoin(BAT *l, BAT *r, BUN estimate);
int BATmmap(BAT *b, int hb, int tb, int hh, int th, int force);
BAT *BATmode(BAT *b, int onoff);
@@ -983,6 +985,7 @@ str BKCinsert_bat(int *r, int *bid, int
str BKCinsert_bat_force(int *r, int *bid, int *sid, bit *force);
char *BKCinsert_bun(int *r, int *bid, ptr h, ptr t);
char *BKCinsert_bun_force(int *r, int *bid, ptr h, ptr t, bit *force);
+str BKCintersectcand(bat *ret, bat *aid, bat *bid);
str BKCisCached(bit *res, int *bid);
str BKCisPersistent(bit *res, int *bid);
str BKCisSorted(bit *res, int *bid);
@@ -993,6 +996,7 @@ str BKCisaSet(bit *res, int *bid);
str BKCload(int *res, str *input);
str BKCmadvise(bit *res, int *bid, int *hbns, int *tbns, int *hhp, int *thp);
str BKCmadvise2(bit *res, int *bid, int *mode);
+str BKCmergecand(bat *ret, bat *aid, bat *bid);
str BKCmirror(int *ret, int *bid);
str BKCmmap(bit *res, int *bid, int *hbns, int *tbns, int *hhp, int *thp);
str BKCmmap2(bit *res, int *bid, int *bns);
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -3148,6 +3148,9 @@ gdk_export BAT *BATkunion(BAT *b, BAT *c
gdk_export BAT *BATsdiff(BAT *b, BAT *c);
gdk_export BAT *BATkdiff(BAT *b, BAT *c);
+gdk_export BAT *BATmergecand(BAT *a, BAT *b);
+gdk_export BAT *BATintersectcand(BAT *a, BAT *b);
+
#include "gdk_calc.h"
/*
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -2192,3 +2192,192 @@ BATcount_no_nil(BAT *b)
}
return cnt;
}
+
+/* merge two candidate lists and produce a new one
+ *
+ * candidate lists are VOID-headed BATs with an OID tail which is
+ * sorted and unique.
+ */
+BAT *
+BATmergecand(BAT *a, BAT *b)
+{
+ BAT *bn;
+ const oid *ap, *bp, *ape, *bpe;
+ oid *p, i;
+
+ BATcheck(a, "BATmergecand");
+ BATcheck(b, "BATmergecand");
+ assert(a->htype == TYPE_void);
+ assert(b->htype == TYPE_void);
+ assert(ATOMtype(a->htype) == TYPE_oid);
+ assert(ATOMtype(b->htype) == TYPE_oid);
+ assert(a->tsorted);
+ assert(b->tsorted);
+ assert(a->tkey);
+ assert(b->tkey);
+ assert(a->T->nonil);
+ assert(b->T->nonil);
+
+ /* XXX we could return a if b is empty (and v.v.) */
+
+ bn = BATnew(TYPE_void, TYPE_oid, BATcount(a) + BATcount(b));
+ if (bn == NULL)
+ return NULL;
+ p = (oid *) Tloc(bn, BUNfirst(bn));
+ if (a->ttype == TYPE_void && b->ttype == TYPE_void) {
+ /* both lists are VOID */
+ if (a->tseqbase > b->tseqbase) {
+ BAT *t = a;
+ a = b;
+ b = t;
+ }
+ /* a->tseqbase <= b->tseqbase */
+ for (i = a->tseqbase; i < a->tseqbase + BATcount(a); i++)
+ *p++ = i;
+ for (i = MAX(b->tseqbase, i);
+ i < b->tseqbase + BATcount(b);
+ i++)
+ *p++ = i;
+ } else if (a->ttype == TYPE_void || b->ttype == TYPE_void) {
+ if (b->ttype == TYPE_void) {
+ BAT *t = a;
+ a = b;
+ b = t;
+ }
+ /* a->ttype == TYPE_void, b->ttype == TYPE_oid */
+ bp = (const oid *) Tloc(b, BUNfirst(b));
+ bpe = bp + BATcount(b);
+ while (bp < bpe && *bp < a->tseqbase)
+ *p++ = *bp++;
+ for (i = a->tseqbase; i < a->tseqbase + BATcount(a); i++)
+ *p++ = i;
+ while (bp < bpe && *bp < i)
+ bp++;
+ while (bp < bpe)
+ *p++ = *bp++;
+ } else {
+ /* a->ttype == TYPE_oid, b->ttype == TYPE_oid */
+ ap = (const oid *) Tloc(a, BUNfirst(a));
+ ape = ap + BATcount(a);
+ bp = (const oid *) Tloc(b, BUNfirst(b));
+ bpe = bp + BATcount(b);
+ while (ap < ape && bp < bpe) {
+ if (*ap < *bp)
+ *p++ = *ap++;
+ else if (*ap > *bp)
+ *p++ = *bp++;
+ else {
+ *p++ = *ap++;
+ bp++;
+ }
+ }
+ while (ap < ape)
+ *p++ = *ap++;
+ while (bp < bpe)
+ *p++ = *bp++;
+ }
+
+ /* properties */
+ BATsetcount(bn, (BUN) (p - (oid *) Tloc(bn, BUNfirst(bn))));
+ BATseqbase(bn, 0);
+ bn->tsorted = 1;
+ bn->tkey = 1;
+ bn->T->nil = 0;
+ bn->T->nonil = 1;
+ return bn;
+}
+
+/* intersect two candidate lists and produce a new one
+ *
+ * candidate lists are VOID-headed BATs with an OID tail which is
+ * sorted and unique.
+ */
+BAT *
+BATintersectcand(BAT *a, BAT *b)
+{
+ BAT *bn;
+ const oid *ap, *bp, *ape, *bpe;
+ oid *p, i;
+
+ BATcheck(a, "BATintersectcand");
+ BATcheck(b, "BATintersectcand");
+ assert(a->htype == TYPE_void);
+ assert(b->htype == TYPE_void);
+ assert(ATOMtype(a->htype) == TYPE_oid);
+ assert(ATOMtype(b->htype) == TYPE_oid);
+ assert(a->tsorted);
+ assert(b->tsorted);
+ assert(a->tkey);
+ assert(b->tkey);
+ assert(a->T->nonil);
+ assert(b->T->nonil);
+
+ if (BATcount(a) == 0 || BATcount(b) == 0) {
+ bn = BATnew(TYPE_void, TYPE_void, 0);
+ BATseqbase(bn, 0);
+ BATseqbase(BATmirror(bn), 0);
+ return bn;
+ }
+
+ if (a->ttype == TYPE_void && b->ttype == TYPE_void) {
+ /* both lists are VOID */
+ bn = BATnew(TYPE_void, TYPE_void, 0);
+ if (bn == NULL)
+ return NULL;
+ i = MAX(a->tseqbase, b->tseqbase);
+ if (a->tseqbase + BATcount(a) <= b->tseqbase ||
+ b->tseqbase + BATcount(b) <= a->tseqbase) {
+ /* no overlap */
+ BATsetcount(bn, 0);
+ } else {
+ BATsetcount(bn, MIN(a->tseqbase + BATcount(a) - i,
+ b->tseqbase + BATcount(b) - i));
+ }
+ BATseqbase(BATmirror(bn), i);
+ return bn;
+ }
+
+ bn = BATnew(TYPE_void, TYPE_oid, MIN(BATcount(a), BATcount(b)));
+ if (bn == NULL)
+ return NULL;
+ p = (oid *) Tloc(bn, BUNfirst(bn));
+ if (a->ttype == TYPE_void || b->ttype == TYPE_void) {
+ if (b->ttype == TYPE_void) {
+ BAT *t = a;
+ a = b;
+ b = t;
+ }
+ /* a->ttype == TYPE_void, b->ttype == TYPE_oid */
+ bp = (const oid *) Tloc(b, BUNfirst(b));
+ bpe = bp + BATcount(b);
+ while (bp < bpe && *bp < a->tseqbase)
+ bp++;
+ while (bp < bpe && *bp < a->tseqbase + BATcount(a))
+ *p++ = *bp++;
+ } else {
+ /* a->ttype == TYPE_oid, b->ttype == TYPE_oid */
+ ap = (const oid *) Tloc(a, BUNfirst(a));
+ ape = ap + BATcount(a);
+ bp = (const oid *) Tloc(b, BUNfirst(b));
+ bpe = bp + BATcount(b);
+ while (ap < ape && bp < bpe) {
+ if (*ap < *bp)
+ ap++;
+ else if (*ap > *bp)
+ bp++;
+ else {
+ *p++ = *ap++;
+ bp++;
+ }
+ }
+ }
+
+ /* properties */
+ BATsetcount(bn, (BUN) (p - (oid *) Tloc(bn, BUNfirst(bn))));
+ BATseqbase(bn, 0);
+ bn->tsorted = 1;
+ bn->tkey = 1;
+ bn->T->nil = 0;
+ bn->T->nonil = 1;
+ return bn;
+}
diff --git a/monetdb5/modules/kernel/bat5.c b/monetdb5/modules/kernel/bat5.c
--- a/monetdb5/modules/kernel/bat5.c
+++ b/monetdb5/modules/kernel/bat5.c
@@ -2418,3 +2418,46 @@ BKCreuseBATmap(int *ret, int *bid, int *
return MAL_SUCCEED;
}
+str
+BKCmergecand(bat *ret, bat *aid, bat *bid)
+{
+ BAT *a, *b, *bn;
+
+ if ((a = BATdescriptor(*aid)) == NULL) {
+ throw(MAL, "bat.mergecand", RUNTIME_OBJECT_MISSING);
+ }
+ if ((b = BATdescriptor(*bid)) == NULL) {
+ BBPreleaseref(a->batCacheid);
+ throw(MAL, "bat.mergecand", RUNTIME_OBJECT_MISSING);
+ }
+ bn = BATmergecand(a, b);
+ BBPreleaseref(a->batCacheid);
+ BBPreleaseref(b->batCacheid);
+ if (bn == NULL)
+ throw(MAL, "bat.mergecand", OPERATION_FAILED);
+ *ret = bn->batCacheid;
+ BBPkeepref(*ret);
+ return MAL_SUCCEED;
+}
+
+str
+BKCintersectcand(bat *ret, bat *aid, bat *bid)
+{
+ BAT *a, *b, *bn;
+
+ if ((a = BATdescriptor(*aid)) == NULL) {
+ throw(MAL, "bat.intersectcand", RUNTIME_OBJECT_MISSING);
+ }
+ if ((b = BATdescriptor(*bid)) == NULL) {
+ BBPreleaseref(a->batCacheid);
+ throw(MAL, "bat.intersectcand", RUNTIME_OBJECT_MISSING);
+ }
+ bn = BATintersectcand(a, b);
+ BBPreleaseref(a->batCacheid);
+ BBPreleaseref(b->batCacheid);
+ if (bn == NULL)
+ throw(MAL, "bat.intersectcand", OPERATION_FAILED);
+ *ret = bn->batCacheid;
+ BBPkeepref(*ret);
+ return MAL_SUCCEED;
+}
diff --git a/monetdb5/modules/kernel/bat5.h b/monetdb5/modules/kernel/bat5.h
--- a/monetdb5/modules/kernel/bat5.h
+++ b/monetdb5/modules/kernel/bat5.h
@@ -131,4 +131,7 @@ bat5_export str BKCsetReadMode(int *res,
bat5_export str BKChasReadMode(bit *res, int *bid);
bat5_export str BKCsetAppendMode(int *res, int *bid) ;
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list