Changeset: 29bd1b903d37 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/29bd1b903d37
Modified Files:
clients/Tests/exports.stable.out
gdk/gdk.h
gdk/gdk_aggr.c
gdk/gdk_batop.c
gdk/gdk_orderidx.c
gdk/gdk_search.c
gdk/gdk_select.c
Branch: Jul2021
Log Message:
Use heap reference counting for the order index heap.
diffs (truncated from 738 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
@@ -384,9 +384,9 @@ void MT_thread_setworking(const char *wo
void OIDXdestroy(BAT *b);
ssize_t OIDfromStr(const char *src, size_t *len, oid **dst, bool external);
ssize_t OIDtoStr(str *dst, size_t *len, const oid *src, bool external);
-BUN ORDERfnd(BAT *b, const void *v);
-BUN ORDERfndfirst(BAT *b, const void *v);
-BUN ORDERfndlast(BAT *b, const void *v);
+BUN ORDERfnd(BAT *b, Heap *oidxh, const void *v);
+BUN ORDERfndfirst(BAT *b, Heap *oidxh, const void *v);
+BUN ORDERfndlast(BAT *b, Heap *oidxh, const void *v);
BUN SORTfnd(BAT *b, const void *v);
BUN SORTfndfirst(BAT *b, const void *v);
BUN SORTfndlast(BAT *b, const void *v);
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -1105,9 +1105,9 @@ gdk_export BUN SORTfnd(BAT *b, const voi
gdk_export BUN SORTfndfirst(BAT *b, const void *v);
gdk_export BUN SORTfndlast(BAT *b, const void *v);
-gdk_export BUN ORDERfnd(BAT *b, const void *v);
-gdk_export BUN ORDERfndfirst(BAT *b, const void *v);
-gdk_export BUN ORDERfndlast(BAT *b, const void *v);
+gdk_export BUN ORDERfnd(BAT *b, Heap *oidxh, const void *v);
+gdk_export BUN ORDERfndfirst(BAT *b, Heap *oidxh, const void *v);
+gdk_export BUN ORDERfndlast(BAT *b, Heap *oidxh, const void *v);
gdk_export BUN BUNfnd(BAT *b, const void *right);
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -3642,19 +3642,36 @@ BATmin_skipnil(BAT *b, void *aggr, bit s
if (res == NULL) {
oid pos;
BAT *pb = NULL;
-
- if (BATcheckorderidx(b) ||
- (/* DISABLES CODE */ (0) &&
- VIEWtparent(b) &&
- (pb = BBP_cache(VIEWtparent(b))) != NULL &&
- pb->tbaseoff == b->tbaseoff &&
- BATcount(pb) == BATcount(b) &&
- pb->hseqbase == b->hseqbase &&
- BATcheckorderidx(pb))) {
- const oid *ords = (const oid *) (pb ?
pb->torderidx->base : b->torderidx->base) + ORDERIDXOFF;
+ Heap *oidxh = NULL;
+
+ if (BATcheckorderidx(b)) {
+ MT_lock_set(&b->batIdxLock);
+ oidxh = b->torderidx;
+ if (oidxh != NULL)
+ HEAPincref(oidxh);
+ MT_lock_unset(&b->batIdxLock);
+ }
+ if (oidxh == NULL &&
+ VIEWtparent(b) &&
+ (pb = BBP_cache(VIEWtparent(b))) != NULL &&
+ BATcheckorderidx(pb)) {
+ /* no lock on b needed since it's a view */
+ MT_lock_set(&pb->batIdxLock);
+ MT_lock_set(&pb->theaplock);
+ if (pb->tbaseoff == b->tbaseoff &&
+ BATcount(pb) == BATcount(b) &&
+ pb->hseqbase == b->hseqbase &&
+ (oidxh = pb->torderidx) != NULL) {
+ HEAPincref(oidxh);
+ }
+ MT_lock_unset(&pb->batIdxLock);
+ MT_lock_unset(&pb->theaplock);
+ }
+ if (oidxh != NULL) {
+ const oid *ords = (const oid *) oidxh->base +
ORDERIDXOFF;
BUN r;
if (!b->tnonil) {
- MT_thread_setalgorithm(pb ? "binsearch on
parent oidx" : "binsearch on oids");
+ MT_thread_setalgorithm(pb ? "binsearch on
parent oidx" : "binsearch on oidx");
BATiter bi = bat_iterator(b);
r = binsearch(ords, 0, b->ttype, bi.base,
bi.vh ? bi.vh->base : NULL,
@@ -3672,9 +3689,10 @@ BATmin_skipnil(BAT *b, void *aggr, bit s
/* no non-nil values */
pos = oid_nil;
} else {
- MT_thread_setalgorithm(pb ? "using parent oidx"
: "using oids");
+ MT_thread_setalgorithm(pb ? "using parent oidx"
: "using oidx");
pos = ords[r];
}
+ HEAPdecref(oidxh, false);
} else if ((VIEWtparent(b) == 0 ||
(/* DISABLES CODE */ (0) &&
BATcount(b) ==
BATcount(BBP_cache(VIEWtparent(b))))) &&
@@ -3766,16 +3784,33 @@ BATmax_skipnil(BAT *b, void *aggr, bit s
if (res == NULL) {
oid pos;
BAT *pb = NULL;
-
- if (BATcheckorderidx(b) ||
- (/* DISABLES CODE */ (0) &&
- VIEWtparent(b) &&
- (pb = BBP_cache(VIEWtparent(b))) != NULL &&
- pb->tbaseoff == b->tbaseoff &&
- BATcount(pb) == BATcount(b) &&
- pb->hseqbase == b->hseqbase &&
- BATcheckorderidx(pb))) {
- const oid *ords = (const oid *) (pb ?
pb->torderidx->base : b->torderidx->base) + ORDERIDXOFF;
+ Heap *oidxh = NULL;
+
+ if (BATcheckorderidx(b)) {
+ MT_lock_set(&b->batIdxLock);
+ oidxh = b->torderidx;
+ if (oidxh != NULL)
+ HEAPincref(oidxh);
+ MT_lock_unset(&b->batIdxLock);
+ }
+ if (oidxh == NULL &&
+ VIEWtparent(b) &&
+ (pb = BBP_cache(VIEWtparent(b))) != NULL &&
+ BATcheckorderidx(pb)) {
+ /* no lock on b needed since it's a view */
+ MT_lock_set(&pb->batIdxLock);
+ MT_lock_set(&pb->theaplock);
+ if (pb->tbaseoff == b->tbaseoff &&
+ BATcount(pb) == BATcount(b) &&
+ pb->hseqbase == b->hseqbase &&
+ (oidxh = pb->torderidx) != NULL) {
+ HEAPincref(oidxh);
+ }
+ MT_lock_unset(&pb->batIdxLock);
+ MT_lock_unset(&pb->theaplock);
+ }
+ if (oidxh != NULL) {
+ const oid *ords = (const oid *) oidxh->base +
ORDERIDXOFF;
MT_thread_setalgorithm(pb ? "using parent oidx" :
"using oids");
pos = ords[BATcount(b) - 1];
@@ -3790,6 +3825,7 @@ BATmax_skipnil(BAT *b, void *aggr, bit s
pos = z;
bat_iterator_end(&bi);
}
+ HEAPdecref(oidxh, false);
} else if ((VIEWtparent(b) == 0 ||
(/* DISABLES CODE */ (0) &&
BATcount(b) ==
BATcount(BBP_cache(VIEWtparent(b))))) &&
@@ -4069,6 +4105,7 @@ doBATgroupquantile(BAT *b, BAT *g, BAT *
BUN index, r, p = BATcount(b);
BAT *pb = NULL;
const oid *ords;
+ Heap *oidxh = NULL;
bn = COLnew(0, average ? TYPE_dbl : tp, 1, TRANSIENT);
if (bn == NULL)
@@ -4076,16 +4113,32 @@ doBATgroupquantile(BAT *b, BAT *g, BAT *
t1 = NULL;
- if (BATcheckorderidx(b) ||
- (/* DISABLES CODE */ (0) &&
- VIEWtparent(b) &&
- (pb = BBP_cache(VIEWtparent(b))) != NULL &&
- pb->tbaseoff == b->tbaseoff &&
- BATcount(pb) == BATcount(b) &&
- pb->hseqbase == b->hseqbase &&
- BATcheckorderidx(pb))) {
+ if (BATcheckorderidx(b)) {
+ MT_lock_set(&b->batIdxLock);
+ oidxh = b->torderidx;
+ if (oidxh != NULL)
+ HEAPincref(oidxh);
+ MT_lock_unset(&b->batIdxLock);
+ }
+ if (oidxh == NULL &&
+ VIEWtparent(b) &&
+ (pb = BBP_cache(VIEWtparent(b))) != NULL &&
+ BATcheckorderidx(pb)) {
+ /* no lock on b needed since it's a view */
+ MT_lock_set(&pb->batIdxLock);
+ MT_lock_set(&pb->theaplock);
+ if (pb->tbaseoff == b->tbaseoff &&
+ BATcount(pb) == BATcount(b) &&
+ pb->hseqbase == b->hseqbase &&
+ (oidxh = pb->torderidx) != NULL) {
+ HEAPincref(oidxh);
+ }
+ MT_lock_unset(&pb->batIdxLock);
+ MT_lock_unset(&pb->theaplock);
+ }
+ if (oidxh != NULL) {
MT_thread_setalgorithm(pb ? "using parent oidx" :
"using oids");
- ords = (const oid *) (pb ? pb->torderidx->base :
b->torderidx->base) + ORDERIDXOFF;
+ ords = (const oid *) oidxh->base + ORDERIDXOFF;
} else {
if (BATsort(NULL, &t1, NULL, b, NULL, g, false, false,
false) != GDK_SUCCEED)
goto bunins_failed;
@@ -4153,10 +4206,13 @@ doBATgroupquantile(BAT *b, BAT *g, BAT *
v = BUNtail(bi, index);
nils += (*atomcmp)(v, dnil) == 0;
}
- bat_iterator_end(&bi);
+ if (oidxh != NULL)
+ HEAPdecref(oidxh, false);
if (t1)
BBPunfix(t1->batCacheid);
- if (BUNappend(bn, v, false) != GDK_SUCCEED)
+ gdk_return rc = BUNappend(bn, v, false);
+ bat_iterator_end(&bi);
+ if (rc != GDK_SUCCEED)
goto bunins_failed;
}
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -2202,6 +2202,7 @@ BATsort(BAT **sorted, BAT **order, BAT *
BUN p, q, r;
lng t0 = GDKusec();
bool mkorderidx, orderidxlock = false;
+ Heap *oidxh = NULL;
/* we haven't implemented NILs as largest value for stable
* sort, so NILs come first for ascending and last for
@@ -2338,33 +2339,32 @@ BATsort(BAT **sorted, BAT **order, BAT *
}
/* when we will create an order index if it doesn't already exist */
mkorderidx = (g == NULL && !reverse && !nilslast && pb != NULL &&
(order || !pb->batTransient));
- if (g == NULL && !reverse && !nilslast &&
- pb != NULL && !BATcheckorderidx(pb)) {
+ if (g == NULL && !reverse && !nilslast && pb != NULL) {
+ (void) BATcheckorderidx(pb);
MT_lock_set(&pb->batIdxLock);
- if (pb->torderidx == NULL) {
- /* no index created while waiting for lock */
- if (mkorderidx) /* keep lock when going to create */
- orderidxlock = true;
- } else {
- /* no need to create an index: it already exists */
+ if (pb->torderidx) {
+ if (!stable || ((oid *) pb->torderidx->base)[2]) {
+ /* we can use the order index */
+ oidxh = pb->torderidx;
+ HEAPincref(oidxh);
+ }
mkorderidx = false;
+ } else if (mkorderidx) {
+ /* keep lock when going to create */
+ orderidxlock = true;
}
if (!orderidxlock)
MT_lock_unset(&pb->batIdxLock);
- } else {
- mkorderidx = false;
}
- if (g == NULL && o == NULL && !reverse && !nilslast &&
- pb != NULL && pb->torderidx != NULL &&
- /* if we want a stable sort, the order index must be
- * stable, if we don't want stable, we don't care */
- (!stable || ((oid *) pb->torderidx->base)[2])) {
+ if (g == NULL && o == NULL && !reverse && !nilslast && oidxh != NULL) {
/* there is an order index that we can use */
on = COLnew(pb->hseqbase, TYPE_oid, BATcount(pb), TRANSIENT);
if (on == NULL)
goto error;
- memcpy(Tloc(on, 0), (oid *) pb->torderidx->base + ORDERIDXOFF,
BATcount(pb) * sizeof(oid));
+ memcpy(Tloc(on, 0), (oid *) oidxh->base + ORDERIDXOFF,
BATcount(pb) * sizeof(oid));
BATsetcount(on, BATcount(b));
+ HEAPdecref(oidxh, false);
+ oidxh = NULL;
on->tkey = true;
on->tnil = false;
on->tnonil = true;
@@ -2412,6 +2412,9 @@ BATsort(BAT **sorted, BAT **order, BAT *
ALGOOPTBATPAR(bn), ALGOOPTBATPAR(gn),
ALGOOPTBATPAR(on), GDKusec() - t0);
return GDK_SUCCEED;
+ } else if (oidxh) {
+ HEAPdecref(oidxh, false);
+ oidxh = NULL;
}
if (o) {
bn = BATproject(o, b);
@@ -2576,8 +2579,6 @@ BATsort(BAT **sorted, BAT **order, BAT *
HEAPfree(m, true);
GDKfree(m);
}
- if (orderidxlock)
- MT_lock_unset(&pb->batIdxLock);
goto error;
}
bn->tsorted = !reverse && !nilslast;
@@ -2591,6 +2592,7 @@ BATsort(BAT **sorted, BAT **order, BAT *
ords,
BATcount(pb) * sizeof(oid));
}
+ ATOMIC_INIT(&m->refs, 1);
pb->torderidx = m;
persistOIDX(pb);
} else {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list