Changeset: caf40568cb03 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/caf40568cb03
Modified Files:
gdk/gdk_project.c
Branch: Jan2022
Log Message:
Implement timeout for BATproject.
diffs (truncated from 378 to 300 lines):
diff --git a/gdk/gdk_project.c b/gdk/gdk_project.c
--- a/gdk/gdk_project.c
+++ b/gdk/gdk_project.c
@@ -23,9 +23,9 @@
#define project1_loop(TYPE) \
static gdk_return \
project1_##TYPE(BAT *restrict bn, BAT *restrict l, BAT *restrict r1, \
- BATiter *restrict r1i) \
+ BATiter *restrict r1i, lng timeoffset) \
{ \
- BUN lo, hi; \
+ BUN lo; \
const TYPE *restrict r1t; \
TYPE *restrict bt; \
oid r1seq, r1end; \
@@ -43,13 +43,13 @@ project1_##TYPE(BAT *restrict bn, BAT *r
} \
oid off = l->tseqbase - r1seq; \
r1t += off; \
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) \
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) \
bt[lo] = r1t[lo]; \
} else { \
assert(l->ttype); \
BATiter li = bat_iterator(l); \
const oid *restrict ot = (const oid *) li.base; \
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) { \
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) { \
oid o = ot[lo]; \
if (o < r1seq || o >= r1end) { \
GDKerror("does not match always\n"); \
@@ -60,6 +60,7 @@ project1_##TYPE(BAT *restrict bn, BAT *r
} \
bat_iterator_end(&li); \
} \
+ TIMEOUT_CHECK(timeoffset, TIMEOUT_HANDLER(GDK_FAIL)); \
BATsetcount(bn, lo); \
return GDK_SUCCEED; \
}
@@ -81,9 +82,10 @@ static gdk_return
\
project_##TYPE(BAT *restrict bn, BAT *restrict l, \
struct canditer *restrict ci, \
BAT *restrict r1, BAT *restrict r2, \
- BATiter *restrict r1i, BATiter *restrict r2i) \
+ BATiter *restrict r1i, BATiter *restrict r2i, \
+ lng timeoffset) \
{ \
- BUN lo, hi; \
+ BUN lo; \
const TYPE *restrict r1t; \
const TYPE *restrict r2t; \
TYPE *restrict bt; \
@@ -94,7 +96,7 @@ project_##TYPE(BAT *restrict bn, BAT *re
if (r2 == NULL && \
(!ci || (ci->tpe == cand_dense && BATtdense(l))) && \
l->tnonil && r1->ttype && !BATtdense(r1)) \
- return project1_##TYPE(bn, l, r1, r1i); \
+ return project1_##TYPE(bn, l, r1, r1i, timeoffset); \
MT_thread_setalgorithm(__func__); \
r1t = (const TYPE *) r1i->base; \
r2t = (const TYPE *) r2i->base; /* may be NULL if r2 == NULL */ \
@@ -108,7 +110,7 @@ project_##TYPE(BAT *restrict bn, BAT *re
r2seq = r2end = r1end; \
} \
if (ci) { \
- for (lo = 0, hi = ci->ncand; lo < hi; lo++) { \
+ TIMEOUT_LOOP_IDX(lo, ci->ncand, timeoffset) { \
oid o = canditer_next(ci); \
if (o < r1seq || o >= r2end) { \
GDKerror("does not match always\n"); \
@@ -121,7 +123,7 @@ project_##TYPE(BAT *restrict bn, BAT *re
bt[lo] = v; \
} \
} else if (BATtdense(l)) { \
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) { \
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) { \
oid o = l->tseqbase + lo; \
if (o < r1seq || o >= r2end) { \
GDKerror("does not match always\n"); \
@@ -136,7 +138,7 @@ project_##TYPE(BAT *restrict bn, BAT *re
} else { \
BATiter li = bat_iterator(l); \
const oid *restrict ot = (const oid *) li.base; \
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) { \
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) { \
oid o = ot[lo]; \
if (is_oid_nil(o)) { \
bt[lo] = v = TYPE##_nil; \
@@ -155,6 +157,7 @@ project_##TYPE(BAT *restrict bn, BAT *re
} \
bat_iterator_end(&li); \
} \
+ TIMEOUT_CHECK(timeoffset, TIMEOUT_HANDLER(GDK_FAIL)); \
BATsetcount(bn, lo); \
return GDK_SUCCEED; \
}
@@ -175,9 +178,9 @@ project_loop(uuid)
static gdk_return
project_oid(BAT *restrict bn, BAT *restrict l, struct canditer *restrict lci,
BAT *restrict r1, BAT *restrict r2,
- BATiter *restrict r1i, BATiter *restrict r2i)
+ BATiter *restrict r1i, BATiter *restrict r2i, lng timeoffset)
{
- BUN lo, hi;
+ BUN lo;
oid *restrict bt;
oid r1seq, r1end;
oid r2seq, r2end;
@@ -187,9 +190,9 @@ project_oid(BAT *restrict bn, BAT *restr
if ((!lci || (lci->tpe == cand_dense && BATtdense(l))) && r1->ttype &&
!BATtdense(r1) && !r2 && l->tnonil) {
if (sizeof(oid) == sizeof(lng))
- return project1_lng(bn, l, r1, r1i);
+ return project1_lng(bn, l, r1, r1i, timeoffset);
else
- return project1_int(bn, l, r1, r1i);
+ return project1_int(bn, l, r1, r1i, timeoffset);
}
MT_thread_setalgorithm(__func__);
if (complex_cand(r1))
@@ -210,7 +213,7 @@ project_oid(BAT *restrict bn, BAT *restr
}
bt = (oid *) Tloc(bn, 0);
if (lci) {
- for (lo = 0, hi = lci->ncand; lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, lci->ncand, timeoffset) {
oid o = canditer_next(lci);
if (o < r1seq || o >= r2end) {
goto nomatch;
@@ -232,7 +235,7 @@ project_oid(BAT *restrict bn, BAT *restr
}
}
} else if (BATtdense(l)) {
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) {
oid o = l->tseqbase + lo;
if (o < r1seq || o >= r2end) {
goto nomatch;
@@ -256,7 +259,7 @@ project_oid(BAT *restrict bn, BAT *restr
} else {
BATiter li = bat_iterator(l);
const oid *ot = (const oid *) li.base;
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) {
oid o = ot[lo];
if (is_oid_nil(o)) {
bt[lo] = oid_nil;
@@ -283,6 +286,7 @@ project_oid(BAT *restrict bn, BAT *restr
}
bat_iterator_end(&li);
}
+ TIMEOUT_CHECK(timeoffset, TIMEOUT_HANDLER(GDK_FAIL));
BATsetcount(bn, lo);
return GDK_SUCCEED;
nomatch:
@@ -293,9 +297,9 @@ project_oid(BAT *restrict bn, BAT *restr
static gdk_return
project_any(BAT *restrict bn, BAT *restrict l, struct canditer *restrict ci,
BAT *restrict r1, BAT *restrict r2,
- BATiter *restrict r1i, BATiter *restrict r2i)
+ BATiter *restrict r1i, BATiter *restrict r2i, lng timeoffset)
{
- BUN lo, hi;
+ BUN lo;
const void *nil = ATOMnilptr(r1->ttype);
const void *v;
oid r1seq, r1end;
@@ -311,7 +315,7 @@ project_any(BAT *restrict bn, BAT *restr
r2seq = r2end = r1end;
}
if (ci) {
- for (lo = 0, hi = ci->ncand; lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, ci->ncand, timeoffset) {
oid o = canditer_next(ci);
if (o < r1seq || o >= r2end) {
GDKerror("does not match always\n");
@@ -326,7 +330,7 @@ project_any(BAT *restrict bn, BAT *restr
}
}
} else if (BATtdense(l)) {
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) {
oid o = l->tseqbase + lo;
if (o < r1seq || o >= r2end) {
GDKerror("does not match always\n");
@@ -344,7 +348,7 @@ project_any(BAT *restrict bn, BAT *restr
BATiter li = bat_iterator(l);
const oid *restrict ot = (const oid *) li.base;
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) {
oid o = ot[lo];
if (is_oid_nil(o)) {
v = nil;
@@ -365,6 +369,7 @@ project_any(BAT *restrict bn, BAT *restr
}
bat_iterator_end(&li);
}
+ TIMEOUT_CHECK(timeoffset, TIMEOUT_HANDLER(GDK_FAIL));
BATsetcount(bn, lo);
bn->theap->dirty = true;
return GDK_SUCCEED;
@@ -374,10 +379,10 @@ static BAT *
project_str(BAT *restrict l, struct canditer *restrict ci, int tpe,
BAT *restrict r1, BAT *restrict r2,
BATiter *restrict r1i, BATiter *restrict r2i,
- lng t0)
+ lng timeoffset, lng t0)
{
BAT *bn;
- BUN lo, hi;
+ BUN lo;
oid r1seq, r1end;
oid r2seq, r2end;
BUN h1off;
@@ -425,7 +430,7 @@ project_str(BAT *restrict l, struct cand
r2seq = r2->hseqbase;
r2end = r2seq + r2i->count;
if (ci) {
- for (lo = 0, hi = ci->ncand; lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, ci->ncand, timeoffset) {
oid o = canditer_next(ci);
if (o < r1seq || o >= r2end) {
GDKerror("does not match always\n");
@@ -472,7 +477,7 @@ project_str(BAT *restrict l, struct cand
}
}
} else if (BATtdense(l)) {
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) {
oid o = l->tseqbase + lo;
if (o < r1seq || o >= r2end) {
GDKerror("does not match always\n");
@@ -521,7 +526,7 @@ project_str(BAT *restrict l, struct cand
} else {
BATiter li = bat_iterator(l);
const oid *restrict ot = (const oid *) li.base;
- for (lo = 0, hi = BATcount(l); lo < hi; lo++) {
+ TIMEOUT_LOOP_IDX(lo, BATcount(l), timeoffset) {
oid o = ot[lo];
if (o < r1seq || o >= r2end) {
GDKerror("does not match always\n");
@@ -570,6 +575,7 @@ project_str(BAT *restrict l, struct cand
}
bat_iterator_end(&li);
}
+ TIMEOUT_CHECK(timeoffset, GOTO_LABEL_TIMEOUT_HANDLER(bailout));
BATsetcount(bn, lo);
bn->tsorted = bn->trevsorted = false;
bn->tnil = false;
@@ -582,6 +588,9 @@ project_str(BAT *restrict l, struct cand
bn && bn->ttype == TYPE_str && bn->tvheap == r1i->vh ? "
sharing string heap" : "",
GDKusec() - t0);
return bn;
+ bailout:
+ BBPreclaim(bn);
+ return NULL;
}
BAT *
@@ -606,6 +615,12 @@ BATproject2(BAT *restrict l, BAT *restri
assert(r2 == NULL || tpe == ATOMtype(r2->ttype));
assert(r2 == NULL || r1->hseqbase + r1i.count == r2->hseqbase);
+ lng timeoffset = 0;
+ QryCtx *qry_ctx = MT_thread_get_qry_ctx();
+ if (qry_ctx != NULL) {
+ timeoffset = (qry_ctx->starttime && qry_ctx->querytimeout) ?
(qry_ctx->starttime + qry_ctx->querytimeout) : 0;
+ }
+
if (r2 && r1i.count == 0) {
/* unlikely special case: r1 is empty, so we just have r2 */
r1 = r2;
@@ -694,7 +709,7 @@ BATproject2(BAT *restrict l, BAT *restri
* vheap; this also means that for this case we
* don't care about duplicate elimination: it
* will remain the same */
- bn = project_str(l, lci, tpe, r1, r2, &r1i, &r2i, t0);
+ bn = project_str(l, lci, tpe, r1, r2, &r1i, &r2i,
timeoffset, t0);
bat_iterator_end(&r1i);
bat_iterator_end(&r2i);
return bn;
@@ -749,36 +764,36 @@ BATproject2(BAT *restrict l, BAT *restri
tpe = ATOMbasetype(tpe);
switch (tpe) {
case TYPE_bte:
- res = project_bte(bn, l, lci, r1, r2, &r1i, &r2i);
+ res = project_bte(bn, l, lci, r1, r2, &r1i, &r2i, timeoffset);
break;
case TYPE_sht:
- res = project_sht(bn, l, lci, r1, r2, &r1i, &r2i);
+ res = project_sht(bn, l, lci, r1, r2, &r1i, &r2i, timeoffset);
break;
case TYPE_int:
- res = project_int(bn, l, lci, r1, r2, &r1i, &r2i);
+ res = project_int(bn, l, lci, r1, r2, &r1i, &r2i, timeoffset);
break;
case TYPE_flt:
- res = project_flt(bn, l, lci, r1, r2, &r1i, &r2i);
+ res = project_flt(bn, l, lci, r1, r2, &r1i, &r2i, timeoffset);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]