Changeset: a376ea7469e7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a376ea7469e7 Modified Files: gdk/gdk_batop.c Branch: Nov2019 Log Message:
Fix race condition during order index creation in BATsort. (grafted from 88a501afbec3b1a8e5fd4e0a468c9606f9d4bff0) diffs (93 lines): diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c --- a/gdk/gdk_batop.c +++ b/gdk/gdk_batop.c @@ -1398,6 +1398,7 @@ BATsort(BAT **sorted, BAT **order, BAT * oid *restrict grps, *restrict ords, prev; BUN p, q, r; lng t0 = 0; + bool mkorderidx, orderidxlock = false; ALGODEBUG t0 = GDKusec(); @@ -1429,7 +1430,7 @@ BATsort(BAT **sorted, BAT **order, BAT * b->trevsorted = !b->trevsorted; b->batDirtydesc = true; } - if (b->tkey != BATtdense(b)) { + if (b->tkey != !is_oid_nil(b->tseqbase)) { b->tkey = !b->tkey; b->batDirtydesc = true; } @@ -1535,8 +1536,26 @@ BATsort(BAT **sorted, BAT **order, BAT * } else { pb = b; } + /* 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)) { + MT_lock_set(&GDKhashLock(pb->batCacheid)); + 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 */ + mkorderidx = false; + } + if (!orderidxlock) + MT_lock_unset(&GDKhashLock(pb->batCacheid)); + } else { + mkorderidx = false; + } if (g == NULL && o == NULL && !reverse && !nilslast && - pb != NULL && BATcheckorderidx(pb) && + 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])) { @@ -1730,12 +1749,10 @@ BATsort(BAT **sorted, BAT **order, BAT * Heap *m = NULL; /* only invest in creating an order index if the BAT * is persistent */ - if (!reverse && - !nilslast && - pb != NULL && - (ords != NULL || !pb->batTransient) && - (m = createOIDXheap(pb, stable)) != NULL) { - if (ords == NULL) { + if (mkorderidx) { + assert(orderidxlock); + if ((m = createOIDXheap(pb, stable)) != NULL && + ords == NULL) { ords = (oid *) m->base + ORDERIDXOFF; if (o && o->ttype != TYPE_void) memcpy(ords, Tloc(o, 0), BATcount(o) * sizeof(oid)); @@ -1759,12 +1776,14 @@ BATsort(BAT **sorted, BAT **order, BAT * HEAPfree(m, true); GDKfree(m); } + if (orderidxlock) + MT_lock_unset(&GDKhashLock(pb->batCacheid)); goto error; } bn->tsorted = !reverse && !nilslast; bn->trevsorted = reverse && nilslast; if (m != NULL) { - MT_lock_set(&GDKhashLock(pb->batCacheid)); + assert(orderidxlock); if (pb->torderidx == NULL) { pb->batDirtydesc = true; if (ords != (oid *) m->base + ORDERIDXOFF) { @@ -1778,9 +1797,10 @@ BATsort(BAT **sorted, BAT **order, BAT * HEAPfree(m, true); GDKfree(m); } - MT_lock_unset(&GDKhashLock(pb->batCacheid)); } } + if (orderidxlock) + MT_lock_unset(&GDKhashLock(pb->batCacheid)); bn->theap.dirty = true; bn->tnosorted = 0; bn->tnorevsorted = 0; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list