Changeset: 3964ff1b8b99 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3964ff1b8b99
Modified Files:
gdk/gdk_aggr.c
gdk/gdk_align.c
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_bbp.c
gdk/gdk_group.c
gdk/gdk_hash.c
gdk/gdk_select.c
gdk/gdk_unique.c
Branch: Jul2021
Log Message:
Use heap lock to protect extra properties.
Also use index lock instead of heap lock to lock out concurrent scans
in BATordered and BATordered_rev.
And also reduce number of times we acquire a lock by doing multiple
calls to nolock functions inside one critical section.
diffs (truncated from 822 to 300 lines):
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -3614,7 +3614,7 @@ void *
BATmin_skipnil(BAT *b, void *aggr, bit skipnil)
{
const ValRecord *prop;
- const void *res;
+ const void *res = NULL;
size_t s;
lng t0 = 0;
@@ -3628,9 +3628,18 @@ BATmin_skipnil(BAT *b, void *aggr, bit s
}
if (BATcount(b) == 0) {
res = ATOMnilptr(b->ttype);
- } else if ((prop = BATgetprop(b, GDK_MIN_VALUE)) != NULL) {
- res = VALptr(prop);
} else {
+ MT_lock_set(&b->theaplock);
+ if ((prop = BATgetprop_nolock(b, GDK_MIN_VALUE)) != NULL)
+ res = VALptr(prop);
+ else if ((prop = BATgetprop_nolock(b, GDK_MIN_POS)) != NULL) {
+ BATiter bi = bat_iterator_nolock(b);
+ if ((prop = BATsetprop_nolock(b, GDK_MIN_VALUE,
b->ttype, BUNtail(bi, prop->val.oval))) != NULL)
+ res = VALptr(prop);
+ }
+ MT_lock_unset(&b->theaplock);
+ }
+ if (res == NULL) {
oid pos;
BAT *pb = NULL;
@@ -3691,11 +3700,12 @@ BATmin_skipnil(BAT *b, void *aggr, bit s
if (is_oid_nil(pos)) {
res = ATOMnilptr(b->ttype);
} else {
- BATiter bi = bat_iterator(b);
+ MT_lock_set(&b->theaplock);
+ BATiter bi = bat_iterator_nolock(b);
res = BUNtail(bi, pos - b->hseqbase);
- BATsetprop(b, GDK_MIN_VALUE, b->ttype, res);
- BATsetprop(b, GDK_MIN_POS, TYPE_oid, &(oid){pos -
b->hseqbase});
- bat_iterator_end(&bi);
+ BATsetprop_nolock(b, GDK_MIN_VALUE, b->ttype, res);
+ BATsetprop_nolock(b, GDK_MIN_POS, TYPE_oid, &(oid){pos
- b->hseqbase});
+ MT_lock_unset(&b->theaplock);
}
}
if (aggr == NULL) {
@@ -3729,7 +3739,7 @@ void *
BATmax_skipnil(BAT *b, void *aggr, bit skipnil)
{
const ValRecord *prop;
- const void *res;
+ const void *res = NULL;
size_t s;
BATiter bi;
lng t0 = 0;
@@ -3742,9 +3752,18 @@ BATmax_skipnil(BAT *b, void *aggr, bit s
}
if (BATcount(b) == 0) {
res = ATOMnilptr(b->ttype);
- } else if ((prop = BATgetprop(b, GDK_MAX_VALUE)) != NULL) {
- res = VALptr(prop);
} else {
+ MT_lock_set(&b->theaplock);
+ if ((prop = BATgetprop_nolock(b, GDK_MAX_VALUE)) != NULL)
+ res = VALptr(prop);
+ else if ((prop = BATgetprop_nolock(b, GDK_MAX_POS)) != NULL) {
+ BATiter bi = bat_iterator_nolock(b);
+ if ((prop = BATsetprop_nolock(b, GDK_MAX_VALUE,
b->ttype, BUNtail(bi, prop->val.oval))) != NULL)
+ res = VALptr(prop);
+ }
+ MT_lock_unset(&b->theaplock);
+ }
+ if (res == NULL) {
oid pos;
BAT *pb = NULL;
@@ -3796,13 +3815,14 @@ BATmax_skipnil(BAT *b, void *aggr, bit s
if (is_oid_nil(pos)) {
res = ATOMnilptr(b->ttype);
} else {
- bi = bat_iterator(b);
+ MT_lock_set(&b->theaplock);
+ bi = bat_iterator_nolock(b);
res = BUNtail(bi, pos - b->hseqbase);
if (b->tnonil) {
- BATsetprop(b, GDK_MAX_VALUE, b->ttype, res);
- BATsetprop(b, GDK_MAX_POS, TYPE_oid, &(oid){pos
- b->hseqbase});
+ BATsetprop_nolock(b, GDK_MAX_VALUE, b->ttype,
res);
+ BATsetprop_nolock(b, GDK_MAX_POS, TYPE_oid,
&(oid){pos - b->hseqbase});
}
- bat_iterator_end(&bi);
+ MT_lock_unset(&b->theaplock);
}
}
if (aggr == NULL) {
diff --git a/gdk/gdk_align.c b/gdk/gdk_align.c
--- a/gdk/gdk_align.c
+++ b/gdk/gdk_align.c
@@ -254,12 +254,12 @@ BATmaterialize(BAT *b)
b->theap = tail;
b->tbaseoff = 0;
b->theap->dirty = true;
+ BATsetprop_nolock(b, GDK_NUNIQUE, TYPE_oid, &(oid){is_oid_nil(t) ? 1 :
b->batCount});
MT_lock_unset(&b->theaplock);
b->ttype = TYPE_oid;
BATsetdims(b);
b->batDirtydesc = true;
BATsetcount(b, b->batCount);
- BATsetprop(b, GDK_NUNIQUE, TYPE_oid, &(oid){is_oid_nil(t) ? 1 :
b->batCount});
return GDK_SUCCEED;
}
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -661,14 +661,21 @@ BATfree(BAT *b)
if (b->tident && !default_ident(b->tident))
GDKfree(b->tident);
b->tident = BATstring_t;
+ MT_rwlock_rdlock(&b->thashlock);
+ BUN nunique = BUN_NONE, nbucket = BUN_NONE;
if (b->thash && b->thash != (Hash *) 1) {
- BATsetprop(b, GDK_NUNIQUE, TYPE_oid, &(oid){b->thash->nunique});
- BATsetprop(b, GDK_HASH_BUCKETS, TYPE_oid,
&(oid){b->thash->nbucket});
+ nunique = b->thash->nunique;
+ nbucket = b->thash->nbucket;
}
+ MT_rwlock_rdunlock(&b->thashlock);
HASHfree(b);
IMPSfree(b);
OIDXfree(b);
MT_lock_set(&b->theaplock);
+ if (nunique != BUN_NONE) {
+ BATsetprop_nolock(b, GDK_NUNIQUE, TYPE_oid, &(oid){nunique});
+ BATsetprop_nolock(b, GDK_HASH_BUCKETS, TYPE_oid,
&(oid){nbucket});
+ }
if (b->theap) {
assert(ATOMIC_GET(&b->theap->refs) == 1);
assert(b->theap->parentid == b->batCacheid);
@@ -1249,16 +1256,24 @@ BUNdelete(BAT *b, oid o)
val = BUNtail(bi, p);
if (ATOMlinear(b->ttype) &&
ATOMcmp(b->ttype, ATOMnilptr(b->ttype), val) != 0) {
- if ((prop = BATgetprop(b, GDK_MAX_VALUE)) != NULL
- && ATOMcmp(b->ttype, VALptr(prop), val) >= 0) {
- BATrmprop(b, GDK_MAX_VALUE);
- BATrmprop(b, GDK_MAX_POS);
+ MT_lock_set(&b->theaplock);
+ if ((prop = BATgetprop_nolock(b, GDK_MAX_VALUE)) != NULL) {
+ if (ATOMcmp(b->ttype, VALptr(prop), val) >= 0) {
+ BATrmprop_nolock(b, GDK_MAX_VALUE);
+ BATrmprop_nolock(b, GDK_MAX_POS);
+ }
+ } else {
+ BATrmprop_nolock(b, GDK_MAX_POS);
}
- if ((prop = BATgetprop(b, GDK_MIN_VALUE)) != NULL
- && ATOMcmp(b->ttype, VALptr(prop), val) <= 0) {
- BATrmprop(b, GDK_MIN_VALUE);
- BATrmprop(b, GDK_MIN_POS);
+ if ((prop = BATgetprop_nolock(b, GDK_MIN_VALUE)) != NULL) {
+ if (ATOMcmp(b->ttype, VALptr(prop), val) <= 0) {
+ BATrmprop_nolock(b, GDK_MIN_VALUE);
+ BATrmprop_nolock(b, GDK_MIN_POS);
+ }
+ } else {
+ BATrmprop_nolock(b, GDK_MIN_POS);
}
+ MT_lock_unset(&b->theaplock);
}
if (ATOMunfix(b->ttype, val) != GDK_SUCCEED)
return GDK_FAIL;
@@ -1294,6 +1309,7 @@ BUNdelete(BAT *b, oid o)
b->tnorevsorted = 0;
MT_lock_set(&b->theaplock);
b->batCount--;
+ BATrmprop_nolock(b, GDK_UNIQUE_ESTIMATE);
MT_lock_unset(&b->theaplock);
if (b->batCount <= 1) {
/* some trivial properties */
@@ -1307,7 +1323,6 @@ BUNdelete(BAT *b, oid o)
}
IMPSdestroy(b);
OIDXdestroy(b);
- BATrmprop(b, GDK_UNIQUE_ESTIMATE);
return GDK_SUCCEED;
}
@@ -1358,41 +1373,47 @@ BUNinplacemulti(BAT *b, const oid *posit
if (b->ttype != TYPE_void && ATOMlinear(b->ttype)) {
const ValRecord *prop;
- if ((prop = BATgetprop(b, GDK_MAX_VALUE)) != NULL) {
+ MT_lock_set(&b->theaplock);
+ if ((prop = BATgetprop_nolock(b, GDK_MAX_VALUE)) !=
NULL) {
if (ATOMcmp(b->ttype, t, ATOMnilptr(b->ttype))
!= 0 &&
ATOMcmp(b->ttype, VALptr(prop), t) < 0) {
/* new value is larger than previous
* largest */
- BATsetprop(b, GDK_MAX_VALUE, b->ttype,
t);
- BATsetprop(b, GDK_MAX_POS, TYPE_oid,
&(oid){p});
+ BATsetprop_nolock(b, GDK_MAX_VALUE,
b->ttype, t);
+ BATsetprop_nolock(b, GDK_MAX_POS,
TYPE_oid, &(oid){p});
} else if (ATOMcmp(b->ttype, t, val) != 0 &&
ATOMcmp(b->ttype, VALptr(prop), val)
== 0) {
/* old value is equal to largest and
* new value is smaller (see above),
* so we don't know anymore which is
* the largest */
- BATrmprop(b, GDK_MAX_VALUE);
- BATrmprop(b, GDK_MAX_POS);
+ BATrmprop_nolock(b, GDK_MAX_VALUE);
+ BATrmprop_nolock(b, GDK_MAX_POS);
}
+ } else {
+ BATrmprop_nolock(b, GDK_MAX_POS);
}
- if ((prop = BATgetprop(b, GDK_MIN_VALUE)) != NULL) {
+ if ((prop = BATgetprop_nolock(b, GDK_MIN_VALUE)) !=
NULL) {
if (ATOMcmp(b->ttype, t, ATOMnilptr(b->ttype))
!= 0 &&
ATOMcmp(b->ttype, VALptr(prop), t) > 0) {
/* new value is smaller than previous
* smallest */
- BATsetprop(b, GDK_MIN_VALUE, b->ttype,
t);
- BATsetprop(b, GDK_MIN_POS, TYPE_oid,
&(oid){p});
+ BATsetprop_nolock(b, GDK_MIN_VALUE,
b->ttype, t);
+ BATsetprop_nolock(b, GDK_MIN_POS,
TYPE_oid, &(oid){p});
} else if (ATOMcmp(b->ttype, t, val) != 0 &&
ATOMcmp(b->ttype, VALptr(prop), val)
<= 0) {
/* old value is equal to smallest and
* new value is larger (see above), so
* we don't know anymore which is the
* smallest */
- BATrmprop(b, GDK_MIN_VALUE);
- BATrmprop(b, GDK_MIN_POS);
+ BATrmprop_nolock(b, GDK_MIN_VALUE);
+ BATrmprop_nolock(b, GDK_MIN_POS);
}
+ } else {
+ BATrmprop_nolock(b, GDK_MIN_POS);
}
- BATrmprop(b, GDK_UNIQUE_ESTIMATE);
+ BATrmprop_nolock(b, GDK_UNIQUE_ESTIMATE);
+ MT_lock_unset(&b->theaplock);
} else {
PROPdestroy(b);
}
@@ -2354,6 +2375,9 @@ BATassertProps(BAT *b)
int cmp;
const void *prev = NULL, *valp, *nilp;
+ /* do the complete check within a lock */
+ MT_lock_set(&b->theaplock);
+
/* general BAT sanity */
assert(b != NULL);
assert(b->batCacheid > 0);
@@ -2447,14 +2471,11 @@ BATassertProps(BAT *b)
assert(b->tkey);
assert(b->tnonil);
}
+ MT_lock_unset(&b->theaplock);
return;
}
- /* do the rest on a view in case some other thread changes b */
- BAT *v = VIEWcreate(b->hseqbase, b);
- if (v == NULL)
- return;
- b = v;
- BATiter bi = bat_iterator_nolock(b);
+
+ BATiter bi = bat_iterator_nolock(b);
if (BATtdense(b)) {
assert(b->tseqbase + b->batCount <= GDK_oid_max);
@@ -2468,7 +2489,7 @@ BATassertProps(BAT *b)
for (p = 1; p < q; p++)
assert(o[p - 1] + 1 == o[p]);
}
- BBPunfix(b->batCacheid);
+ MT_lock_unset(&b->theaplock);
return;
}
assert(1 << b->tshift == b->twidth);
@@ -2513,7 +2534,7 @@ BATassertProps(BAT *b)
if (!b->tkey && !b->tsorted && !b->trevsorted &&
!b->tnonil && !b->tnil) {
/* nothing more to prove */
- BBPunfix(b->batCacheid);
+ MT_lock_unset(&b->theaplock);
return;
}
@@ -2524,11 +2545,11 @@ BATassertProps(BAT *b)
bool seenmax = false, seenmin = false;
bool seennil = false;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list