Changeset: ab10c261371e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ab10c261371e
Modified Files:
        gdk/gdk_hash.c
        gdk/gdk_private.h
        gdk/gdk_string.c
Branch: ustr
Log Message:

Reduce the number of function calls made when inserting ustr data.


diffs (123 lines):

diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -416,7 +416,8 @@ HASHgrowbucket(BAT *b)
                        HASHput(h, old, BUN_NONE);
                else
                        HASHputlink(h, lold, BUN_NONE);
-       } while (h->nunique >= (nbucket = h->nbucket) * 7 / 8);
+               nbucket = h->nbucket;
+       } while (h->nunique >= nbucket * 3 / 4);
        TRC_DEBUG_IF(ACCELERATOR) if (h->nbucket > onbucket) {
                TRC_DEBUG_ENDIF(ACCELERATOR, ALGOBATFMT " " BUNFMT
                        " -> " BUNFMT " buckets (" LLFMT " usec)\n",
@@ -436,7 +437,7 @@ HASHgrowbucket(BAT *b)
  * maintained here, in the HASHdestroy and HASHfree functions, and in
  * BBPdiskscan during initialization. */
 bool
-BATcheckhash(BAT *b)
+BATcheckhash_locked(BAT *b)
 {
        if (b->ttype == TYPE_void)
                return false;
@@ -444,13 +445,10 @@ BATcheckhash(BAT *b)
        lng t = 0;
        Hash *h;
 
-       MT_rwlock_rdlock(&b->thashlock);
        h = b->thash;
-       MT_rwlock_rdunlock(&b->thashlock);
        if (h == (Hash *) 1) {
                /* but when we want to change it, we need the lock */
                TRC_DEBUG_IF(ACCELERATOR) t = GDKusec();
-               MT_rwlock_wrlock(&b->thashlock);
                TRC_DEBUG_IF(ACCELERATOR) t = GDKusec() - t;
                /* if still 1 now that we have the lock, we can update */
                if (b->thash == (Hash *) 1) {
@@ -522,7 +520,6 @@ BATcheckhash(BAT *b)
                                                                
h->heaplink.hasfile = true;
                                                                
TRC_DEBUG(ACCELERATOR,
                                                                          
ALGOBATFMT ": reusing persisted hash\n", ALGOBATPAR(b));
-                                                               
MT_rwlock_wrunlock(&b->thashlock);
                                                                return true;
                                                        }
                                                        /* if h->nbucket
@@ -561,7 +558,6 @@ BATcheckhash(BAT *b)
                        GDKclrerr();    /* we're not currently interested in 
errors */
                }
                h = b->thash;
-               MT_rwlock_wrunlock(&b->thashlock);
        }
        if (h != NULL) {
                TRC_DEBUG(ACCELERATOR, ALGOBATFMT ": already has hash, waited " 
LLFMT " usec\n", ALGOBATPAR(b), t);
@@ -569,6 +565,25 @@ BATcheckhash(BAT *b)
        return h != NULL;
 }
 
+bool
+BATcheckhash(BAT *b)
+{
+       if (b->ttype == TYPE_void)
+               return false;
+
+       MT_rwlock_rdlock(&b->thashlock);
+       Hash *h = b->thash;
+       MT_rwlock_rdunlock(&b->thashlock);
+       if (h == NULL)
+               return false;
+       if (h != (Hash *) 1)
+               return true;
+       MT_rwlock_wrlock(&b->thashlock);
+       bool ret = BATcheckhash_locked(b);
+       MT_rwlock_wrunlock(&b->thashlock);
+       return ret;
+}
+
 /* figure out size of the hash (sum of the sizes of the two hash files)
  * without loading them */
 size_t
@@ -1182,12 +1197,14 @@ HASHappend_locked_hashval(BATiter *bi, B
                GDKclrerr();
                return;
        }
-       if (HASHwidth(i + 1) > h->width &&
-            HASHupgradehashheap(b) != GDK_SUCCEED) {
+       if (h->width < SIZEOF_BUN &&
+           HASHwidth(i + 1) > h->width &&
+           HASHupgradehashheap(b) != GDK_SUCCEED) {
                GDKclrerr();
                return;
        }
        if ((ATOMsize(b->ttype) > 2 &&
+            h->nunique >= h->nbucket * 7 / 8 &&
             HASHgrowbucket(b) != GDK_SUCCEED) ||
            ((i + 1) * h->width > h->heaplink.size &&
             HEAPextend(&h->heaplink,
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -45,6 +45,8 @@ void ATOMunknown_clean(void)
        __attribute__((__visibility__("hidden")));
 bool BATcheckhash(BAT *b)
        __attribute__((__visibility__("hidden")));
+bool BATcheckhash_locked(BAT *b)
+       __attribute__((__visibility__("hidden")));
 gdk_return BATcheckmodes(BAT *b, bool persistent)
        __attribute__((__warn_unused_result__))
        __attribute__((__visibility__("hidden")));
diff --git a/gdk/gdk_string.c b/gdk/gdk_string.c
--- a/gdk/gdk_string.c
+++ b/gdk/gdk_string.c
@@ -185,10 +185,11 @@ ustrPut(BAT *b, var_t *dst, const char *
        /* this function is the ONLY place where ustrbat may be changed
         * (inserted into), and we're holding the ustrbat->theaplock, so we are
         * totally save looking at the heaps */
-       (void) BATcheckhash(ustrbat); /* load hash table */
        MT_rwlock_wrlock(&ustrbat->thashlock);
        MT_lock_set(&ustrbat->theaplock);
        assert(ustrbat->tvkey);
+       if (b->thash == (Hash *) 1)
+               (void) BATcheckhash_locked(ustrbat); /* load hash table */
 
        Heap *h = ustrbat->tvheap;
        BUN p = BUN_NONE;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to