Changeset: 411348e37eda for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/411348e37eda
Modified Files:
gdk/gdk.h
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_logger.c
sql/storage/bat/bat_logger.c
Branch: default
Log Message:
New interface bat_iterator_hash to initialize BAT iterator with read lock on
hash.
The .hash pointer is filled in, and the hash is unlocked in
bat_iterator_end.
If .hash is NULL, there is no loaded hash, and the hashlock is not locked.
diffs (truncated from 325 to 300 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2309,6 +2309,7 @@ typedef struct BATiter {
Heap *h;
void *base;
Heap *vh;
+ Hash *hash; /* if non-NULL, there's a read lock */
BUN count;
BUN baseoff;
oid hseq;
@@ -2422,7 +2423,7 @@ bat_iterator_incref(BATiter *bi)
}
static inline BATiter
-bat_iterator(BAT *b)
+bat_iterator_internal(BAT *b, bool hash)
{
/* needs matching bat_iterator_end */
BATiter bi;
@@ -2435,6 +2436,8 @@ bat_iterator(BAT *b)
* have a parent for its vheap (which would have to be
* our own vheap parent), so lock the vheap after the
* tail */
+ if (hash)
+ MT_rwlock_rdlock(&b->thashlock);
MT_lock_set(&b->theaplock);
if (b->theap->parentid != b->batCacheid) {
pb = BBP_desc(b->theap->parentid);
@@ -2447,6 +2450,11 @@ bat_iterator(BAT *b)
MT_lock_set(&pvb->theaplock);
}
bi = bat_iterator_nolock(b);
+ if (hash &&
+ ((bi.hash = b->thash) == NULL || bi.hash == (Hash *) 1)) {
+ bi.hash = NULL;
+ MT_rwlock_rdunlock(&b->thashlock);
+ }
bat_iterator_incref(&bi);
if (pvb)
MT_lock_unset(&pvb->theaplock);
@@ -2464,6 +2472,18 @@ bat_iterator(BAT *b)
return bi;
}
+static inline BATiter
+bat_iterator(BAT *b)
+{
+ return bat_iterator_internal(b, false);
+}
+
+static inline BATiter
+bat_iterator_hash(BAT *b)
+{
+ return bat_iterator_internal(b, true);
+}
+
/* return a copy of a BATiter instance; needs to be released with
* bat_iterator_end */
static inline BATiter
@@ -2475,6 +2495,8 @@ bat_iterator_copy(const BATiter *bip)
HEAPincref(bip->h);
if (bip->vh)
HEAPincref(bip->vh);
+ if (bip->hash)
+ MT_rwlock_rdlock(&bip->b->thashlock);
return *bip;
}
@@ -2484,6 +2506,8 @@ bat_iterator_end(BATiter *bip)
/* matches bat_iterator */
assert(bip);
assert(bip->locked);
+ if (bip->hash)
+ MT_rwlock_rdunlock(&bip->b->thashlock);
if (bip->h)
HEAPdecref(bip->h, false);
if (bip->vh)
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1974,78 +1974,71 @@ BUNfnd(BAT *b, const void *v)
bat_iterator_end(&bi);
v = &off;
}
- bi = bat_iterator(b); /* outside of hashlock */
- if (BAThash(b) == GDK_SUCCEED) {
- MT_rwlock_rdlock(&b->thashlock);
- if (b->thash == NULL) {
- MT_rwlock_rdunlock(&b->thashlock);
- goto hashfnd_failed;
- }
+ (void) BAThash(b);
+ bi = bat_iterator_hash(b);
+ if (bi.hash) {
switch (ATOMbasetype(bi.type)) {
case TYPE_bte:
- HASHloop_bte(&bi, b->thash, r, v)
+ HASHloop_bte(&bi, bi.hash, r, v)
break;
break;
case TYPE_sht:
- HASHloop_sht(&bi, b->thash, r, v)
+ HASHloop_sht(&bi, bi.hash, r, v)
break;
break;
case TYPE_int:
- HASHloop_int(&bi, b->thash, r, v)
+ HASHloop_int(&bi, bi.hash, r, v)
break;
break;
case TYPE_flt:
- HASHloop_flt(&bi, b->thash, r, v)
+ HASHloop_flt(&bi, bi.hash, r, v)
break;
break;
case TYPE_dbl:
- HASHloop_dbl(&bi, b->thash, r, v)
+ HASHloop_dbl(&bi, bi.hash, r, v)
break;
break;
case TYPE_lng:
- HASHloop_lng(&bi, b->thash, r, v)
+ HASHloop_lng(&bi, bi.hash, r, v)
break;
break;
#ifdef HAVE_HGE
case TYPE_hge:
- HASHloop_hge(&bi, b->thash, r, v)
+ HASHloop_hge(&bi, bi.hash, r, v)
break;
break;
#endif
case TYPE_uuid:
- HASHloop_uuid(&bi, b->thash, r, v)
+ HASHloop_uuid(&bi, bi.hash, r, v)
break;
break;
case TYPE_inet4:
- HASHloop_inet4(&bi, b->thash, r, v)
+ HASHloop_inet4(&bi, bi.hash, r, v)
break;
break;
case TYPE_inet6:
- HASHloop_inet6(&bi, b->thash, r, v)
+ HASHloop_inet6(&bi, bi.hash, r, v)
break;
break;
case TYPE_str:
if (bi.ustr) {
- HASHloop_var_t(&bi, b->thash, r, v)
+ HASHloop_var_t(&bi, bi.hash, r, v)
break;
} else {
- HASHloop_str(&bi, b->thash, r, v)
+ HASHloop_str(&bi, bi.hash, r, v)
break;
}
break;
default:
- HASHloop(&bi, b->thash, r, v)
+ HASHloop(&bi, bi.hash, r, v)
break;
break;
}
- MT_rwlock_rdunlock(&b->thashlock);
- bat_iterator_end(&bi);
- return r;
+ } else {
+ /* can't build hash table, search the slow way */
+ GDKclrerr();
+ r = slowfnd(&bi, v);
}
- hashfnd_failed:
- /* can't build hash table, search the slow way */
- GDKclrerr();
- r = slowfnd(&bi, v);
bat_iterator_end(&bi);
return r;
}
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -3413,21 +3413,20 @@ BATcount_no_nil(BAT *b, BAT *s)
BATcheck(b, 0);
hseq = b->hseqbase;
- BATiter bi = bat_iterator(b);
+ (void) BATcheckhash(b);
+ BATiter bi = bat_iterator_hash(b);
canditer_init_bi(&ci, &bi, s);
if (bi.nonil) {
bat_iterator_end(&bi);
return ci.ncand;
}
- if (BATcheckhash(b)) {
- MT_rwlock_rdlock(&b->thashlock);
+ if (bi.hash) {
BUN p = 0;
const void *nil = b->ustr ? &(var_t){0} : ATOMnilptr(b->ttype);
cnt = ci.ncand;
- HASHloop(&bi, b->thash, p, nil)
+ HASHloop(&bi, bi.hash, p, nil)
if (canditer_contains(&ci, p + b->hseqbase))
cnt--;
- MT_rwlock_rdunlock(&b->thashlock);
bat_iterator_end(&bi);
return cnt;
}
diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -128,18 +128,16 @@ log_find(BAT *b, BAT *d, int val)
assert(b->ttype == TYPE_int);
assert(d->ttype == TYPE_oid);
- BATiter bi = bat_iterator(b);
- if (BAThash(b) == GDK_SUCCEED) {
- MT_rwlock_rdlock(&b->thashlock);
- HASHloop_int(&bi, b->thash, p, &val) {
+ (void) BAThash(b);
+ BATiter bi = bat_iterator_hash(b);
+ if (bi.hash) {
+ HASHloop_int(&bi, bi.hash, p, &val) {
oid pos = p;
if (BUNfnd(d, &pos) == BUN_NONE) {
- MT_rwlock_rdunlock(&b->thashlock);
bat_iterator_end(&bi);
return p;
}
}
- MT_rwlock_rdunlock(&b->thashlock);
} else { /* unlikely: BAThash failed */
int *t = (int *) bi.base;
@@ -163,20 +161,18 @@ internal_find_bat(logger *lg, log_id id,
BUN p;
if (BAThash(lg->catalog_id) == GDK_SUCCEED) {
- BATiter cni = bat_iterator(lg->catalog_id);
- MT_rwlock_rdlock(&cni.b->thashlock);
+ BATiter cni = bat_iterator_hash(lg->catalog_id);
if (tid < 0) {
- HASHloop_int(&cni, cni.b->thash, p, &id) {
+ HASHloop_int(&cni, cni.hash, p, &id) {
oid pos = p;
if (BUNfnd(lg->dcatalog, &pos) == BUN_NONE) {
- MT_rwlock_rdunlock(&cni.b->thashlock);
bat_iterator_end(&cni);
return *(log_bid *)
Tloc(lg->catalog_bid, p);
}
}
} else {
BUN cp = BUN_NONE;
- HASHloop_int(&cni, cni.b->thash, p, &id) {
+ HASHloop_int(&cni, cni.hash, p, &id) {
lng lid = *(lng *) Tloc(lg->catalog_lid, p);
if (lid != lng_nil && lid <= tid) {
break;
@@ -184,12 +180,10 @@ internal_find_bat(logger *lg, log_id id,
cp = p;
}
if (cp != BUN_NONE) {
- MT_rwlock_rdunlock(&cni.b->thashlock);
bat_iterator_end(&cni);
return *(log_bid *) Tloc(lg->catalog_bid, cp);
}
}
- MT_rwlock_rdunlock(&cni.b->thashlock);
bat_iterator_end(&cni);
return 0; /* not found */
}
@@ -1582,13 +1576,12 @@ log_read_transaction(logger *lg, BAT *id
case LOG_CREATE_USTR:
case LOG_DESTROY:
if (tr != NULL && updated && BAThash(lg->catalog_id) ==
GDK_SUCCEED) {
- BATiter cni = bat_iterator(lg->catalog_id);
+ BATiter cni = bat_iterator_hash(lg->catalog_id);
BUN p;
BUN posnew = BUN_NONE;
BUN posold = BUN_NONE;
BUN posustr = BUN_NONE;
- MT_rwlock_rdlock(&cni.b->thashlock);
- HASHloop_int(&cni, cni.b->thash, p, &l.id) {
+ HASHloop_int(&cni, cni.hash, p, &l.id) {
lng lid = *(lng *)
Tloc(lg->catalog_lid, p);
if (lid == lng_nil || lid > tr->tid)
posnew = p;
@@ -1601,7 +1594,6 @@ log_read_transaction(logger *lg, BAT *id
GDKwarning("should not
be possible\n");
}
}
- MT_rwlock_rdunlock(&cni.b->thashlock);
bat_iterator_end(&cni);
/* Normally at this point, posnew is the
* location of the bat that this
diff --git a/sql/storage/bat/bat_logger.c b/sql/storage/bat/bat_logger.c
--- a/sql/storage/bat/bat_logger.c
+++ b/sql/storage/bat/bat_logger.c
@@ -191,7 +191,8 @@ tabins(logger *lg, ...)
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]