Changeset: 09d3014231d5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/09d3014231d5
Modified Files:
gdk/gdk.h
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_group.c
gdk/gdk_hash.c
gdk/gdk_join.c
gdk/gdk_select.c
monetdb5/mal/mal_profiler.c
Branch: default
Log Message:
Protect access to minpos/maxpos/unique_est properties.
diffs (truncated from 717 to 300 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -925,6 +925,7 @@ typedef struct BATiter {
oid tseq;
BUN hfree, vhfree;
BUN minpos, maxpos;
+ double unique_est;
union {
oid tvid;
bool tmsk;
@@ -953,6 +954,7 @@ bat_iterator_nolock(BAT *b)
.vhfree = b->tvheap ? b->tvheap->free : 0,
.minpos = b->tminpos,
.maxpos = b->tmaxpos,
+ .unique_est = b->tunique_est,
#ifndef NDEBUG
.locked = false,
#endif
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -589,9 +589,6 @@ BATclear(BAT *b, bool force)
IMPSdestroy(b);
OIDXdestroy(b);
PROPdestroy(b);
- b->tminpos = BUN_NONE;
- b->tmaxpos = BUN_NONE;
- b->tunique_est = 0.0;
/* we must dispose of all inserted atoms */
MT_lock_set(&b->theaplock);
@@ -650,6 +647,9 @@ BATclear(BAT *b, bool force)
BATsettrivprop(b);
b->tnosorted = b->tnorevsorted = 0;
b->tnokey[0] = b->tnokey[1] = 0;
+ b->tminpos = BUN_NONE;
+ b->tmaxpos = BUN_NONE;
+ b->tunique_est = 0.0;
MT_lock_unset(&b->theaplock);
return GDK_SUCCEED;
}
@@ -771,7 +771,6 @@ wrongtype(int t1, int t2)
* is bat[void,T] for a simple fixed-size type T. In that case we
* do inline array[T] inserts.
*/
-/* TODO make it simpler, ie copy per column */
BAT *
COLcopy(BAT *b, int tt, bool writable, role_t role)
{
@@ -933,9 +932,9 @@ COLcopy(BAT *b, int tt, bool writable, r
bn->tnosorted = b->tnosorted;
bn->tnonil = b->tnonil;
bn->tnil = b->tnil;
- bn->tminpos = b->tminpos;
- bn->tmaxpos = b->tmaxpos;
- bn->tunique_est = b->tunique_est;
+ bn->tminpos = bi.minpos;
+ bn->tmaxpos = bi.maxpos;
+ bn->tunique_est = bi.unique_est;
} else if (ATOMstorage(tt) == ATOMstorage(b->ttype) &&
ATOMcompare(tt) == ATOMcompare(b->ttype)) {
BUN h = BUNlast(b);
@@ -961,9 +960,9 @@ COLcopy(BAT *b, int tt, bool writable, r
} else {
bn->tnokey[0] = bn->tnokey[1] = 0;
}
- bn->tminpos = b->tminpos;
- bn->tmaxpos = b->tmaxpos;
- bn->tunique_est = b->tunique_est;
+ bn->tminpos = bi.minpos;
+ bn->tmaxpos = bi.maxpos;
+ bn->tunique_est = bi.unique_est;
} else {
bn->tsorted = bn->trevsorted = false; /* set based on count
later */
bn->tnonil = bn->tnil = false;
@@ -1050,8 +1049,11 @@ BUNappendmulti(BAT *b, const void *value
return rc;
}
- if (count > BATcount(b) / GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
+ if (count > BATcount(b) / GDK_UNIQUE_ESTIMATE_KEEP_FRACTION) {
+ MT_lock_set(&b->theaplock);
b->tunique_est = 0;
+ MT_lock_unset(&b->theaplock);
+ }
b->theap->dirty = true;
const void *t = b->ttype == TYPE_msk ? &(msk){false} :
ATOMnilptr(b->ttype);
if (b->ttype == TYPE_oid) {
@@ -1150,6 +1152,10 @@ BUNappendmulti(BAT *b, const void *value
}
int (*atomcmp) (const void *, const void *) = ATOMcompare(b->ttype);
const void *atomnil = ATOMnilptr(b->ttype);
+ MT_lock_set(&b->theaplock);
+ BUN minpos = b->tminpos;
+ BUN maxpos = b->tmaxpos;
+ MT_lock_unset(&b->theaplock);
MT_rwlock_wrlock(&b->thashlock);
if (values && b->ttype) {
if (b->tvarsized) {
@@ -1165,21 +1171,21 @@ BUNappendmulti(BAT *b, const void *value
}
if (atomcmp(t, atomnil) != 0) {
if (p == 0) {
- b->tminpos = b->tmaxpos = 0;
+ minpos = maxpos = 0;
} else {
BATiter bi =
bat_iterator_nolock(b);
- if (b->tminpos != BUN_NONE &&
- atomcmp(BUNtvar(bi,
b->tminpos), t) > 0)
- b->tminpos = p;
- if (b->tmaxpos != BUN_NONE &&
- atomcmp(BUNtvar(bi,
b->tmaxpos), t) < 0)
- b->tmaxpos = p;
+ if (minpos != BUN_NONE &&
+ atomcmp(BUNtvar(bi,
minpos), t) > 0)
+ minpos = p;
+ if (maxpos != BUN_NONE &&
+ atomcmp(BUNtvar(bi,
maxpos), t) < 0)
+ maxpos = p;
}
}
p++;
}
} else if (ATOMstorage(b->ttype) == TYPE_msk) {
- b->tminpos = b->tmaxpos = BUN_NONE;
+ minpos = maxpos = BUN_NONE;
for (BUN i = 0; i < count; i++) {
t = (void *) ((char *) values + (i <<
b->tshift));
mskSetVal(b, p, *(msk *) t);
@@ -1198,15 +1204,15 @@ BUNappendmulti(BAT *b, const void *value
}
if (atomcmp(t, atomnil) != 0) {
if (p == 0) {
- b->tminpos = b->tmaxpos = 0;
+ minpos = maxpos = 0;
} else {
BATiter bi =
bat_iterator_nolock(b);
- if (b->tminpos != BUN_NONE &&
- atomcmp(BUNtloc(bi,
b->tminpos), t) > 0)
- b->tminpos = p;
- if (b->tmaxpos != BUN_NONE &&
- atomcmp(BUNtloc(bi,
b->tmaxpos), t) < 0)
- b->tmaxpos = p;
+ if (minpos != BUN_NONE &&
+ atomcmp(BUNtloc(bi,
minpos), t) > 0)
+ minpos = p;
+ if (maxpos != BUN_NONE &&
+ atomcmp(BUNtloc(bi,
maxpos), t) < 0)
+ maxpos = p;
}
}
p++;
@@ -1226,6 +1232,10 @@ BUNappendmulti(BAT *b, const void *value
}
}
MT_rwlock_wrunlock(&b->thashlock);
+ MT_lock_set(&b->theaplock);
+ b->tminpos = minpos;
+ b->tmaxpos = maxpos;
+ MT_lock_unset(&b->theaplock);
BATsetcount(b, p);
IMPSdestroy(b); /* no support for inserts in imprints yet */
@@ -1260,10 +1270,15 @@ BUNdelete(BAT *b, oid o)
}
b->batDirtydesc = true;
val = BUNtail(bi, p);
+ /* writing the values should be locked, reading could be done
+ * unlocked (since we're the only thread that should be changing
+ * anything) */
+ MT_lock_set(&b->theaplock);
if (b->tmaxpos == p)
b->tmaxpos = BUN_NONE;
if (b->tminpos == p)
b->tminpos = BUN_NONE;
+ MT_lock_unset(&b->theaplock);
if (ATOMunfix(b->ttype, val) != GDK_SUCCEED)
return GDK_FAIL;
HASHdelete(b, p, val);
@@ -1287,10 +1302,12 @@ BUNdelete(BAT *b, oid o)
HASHdelete(b, BUNlast(b) - 1, val);
memcpy(Tloc(b, p), val, Tsize(b));
HASHinsert(b, p, val);
+ MT_lock_set(&b->theaplock);
if (b->tminpos == BUNlast(b) - 1)
b->tminpos = p;
if (b->tmaxpos == BUNlast(b) - 1)
b->tmaxpos = p;
+ MT_lock_unset(&b->theaplock);
}
/* no longer sorted */
b->tsorted = b->trevsorted = false;
@@ -1347,12 +1364,18 @@ BUNinplacemulti(BAT *b, const oid *posit
BATgetId(b));
return GDK_FAIL;
}
+ MT_lock_set(&b->theaplock);
if (b->ttype == TYPE_void) {
PROPdestroy(b);
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
b->tunique_est = 0.0;
+ } else if (count > BATcount(b) / GDK_UNIQUE_ESTIMATE_KEEP_FRACTION) {
+ b->tunique_est = 0;
}
+ BUN minpos = b->tminpos;
+ BUN maxpos = b->tmaxpos;
+ MT_lock_unset(&b->theaplock);
MT_rwlock_wrlock(&b->thashlock);
for (BUN i = 0; i < count; i++) {
BUN p = autoincr ? positions[0] - b->hseqbase + i :
positions[i] - b->hseqbase;
@@ -1392,40 +1415,38 @@ BUNinplacemulti(BAT *b, const oid *posit
b->tnil = false;
}
if (b->ttype != TYPE_void) {
- if (b->tmaxpos != BUN_NONE) {
- if (!isnil && ATOMcmp(b->ttype,
BUNtail(bi, b->tmaxpos), t) < 0) {
+ if (maxpos != BUN_NONE) {
+ if (!isnil && ATOMcmp(b->ttype,
BUNtail(bi, maxpos), t) < 0) {
/* new value is larger
* than previous
* largest */
- b->tmaxpos = p;
- } else if (b->tmaxpos == p &&
ATOMcmp(b->ttype, BUNtail(bi, b->tmaxpos), t) != 0) {
+ maxpos = p;
+ } else if (maxpos == p &&
ATOMcmp(b->ttype, BUNtail(bi, maxpos), t) != 0) {
/* old value is equal to
* largest and new value
* is smaller or nil (see
* above), so we don't
* know anymore which is
* the largest */
- b->tmaxpos = BUN_NONE;
+ maxpos = BUN_NONE;
}
}
- if (b->tminpos != BUN_NONE) {
- if (!isnil && ATOMcmp(b->ttype,
BUNtail(bi, b->tminpos), t) > 0) {
+ if (minpos != BUN_NONE) {
+ if (!isnil && ATOMcmp(b->ttype,
BUNtail(bi, minpos), t) > 0) {
/* new value is smaller
* than previous
* smallest */
- b->tminpos = p;
- } else if (b->tminpos == p &&
ATOMcmp(b->ttype, BUNtail(bi, b->tminpos), t) != 0) {
+ minpos = p;
+ } else if (minpos == p &&
ATOMcmp(b->ttype, BUNtail(bi, minpos), t) != 0) {
/* old value is equal to
* smallest and new value
* is larger or nil (see
* above), so we don't
* know anymore which is
* the largest */
- b->tminpos = BUN_NONE;
+ minpos = BUN_NONE;
}
}
- if (count > BATcount(b) /
GDK_UNIQUE_ESTIMATE_KEEP_FRACTION)
- b->tunique_est = 0;
}
HASHdelete_locked(b, p, val); /* first delete old
value from hash */
} else {
@@ -1437,9 +1458,11 @@ BUNinplacemulti(BAT *b, const oid *posit
b->thash = NULL;
doHASHdestroy(b, hs);
}
- b->tminpos = BUN_NONE;
- b->tmaxpos = BUN_NONE;
+ MT_lock_set(&b->theaplock);
+ minpos = BUN_NONE;
+ maxpos = BUN_NONE;
b->tunique_est = 0.0;
+ MT_lock_unset(&b->theaplock);
}
OIDXdestroy(b);
IMPSdestroy(b);
@@ -1581,6 +1604,10 @@ BUNinplacemulti(BAT *b, const oid *posit
b->tnonil = t && ATOMcmp(b->ttype, t,
ATOMnilptr(b->ttype)) != 0;
}
MT_rwlock_wrunlock(&b->thashlock);
+ MT_lock_set(&b->theaplock);
+ b->tminpos = minpos;
+ b->tmaxpos = maxpos;
+ MT_lock_unset(&b->theaplock);
b->theap->dirty = true;
if (b->tvheap)
b->tvheap->dirty = true;
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -694,6 +694,7 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool
IMPSdestroy(b); /* imprints do not support updates yet */
OIDXdestroy(b);
+ MT_lock_set(&b->theaplock);
if (BATcount(b) == 0 || b->tmaxpos != BUN_NONE) {
if (ni.maxpos != BUN_NONE) {
BATiter bi = bat_iterator_nolock(b);
@@ -722,8 +723,10 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list