Changeset: 6408dea07135 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6408dea07135
Modified Files:
        gdk/gdk_group.c
        gdk/gdk_hash.c
Branch: linear-hashing
Log Message:

Fix some crashes.


diffs (66 lines):

diff --git a/gdk/gdk_group.c b/gdk/gdk_group.c
--- a/gdk/gdk_group.c
+++ b/gdk/gdk_group.c
@@ -1050,8 +1050,8 @@ BATgroup_internal(BAT **groups, BAT **ex
                bool gc = g != NULL && (BATordered(g) || BATordered_rev(g));
                const char *nme;
                BUN prb;
-               int bits;
-               BUN mask;
+               int bits = 0;
+               BUN nbucket;
                oid grp;
 
                GDKclrerr();    /* not interested in BAThash errors */
@@ -1073,10 +1073,27 @@ BATgroup_internal(BAT **groups, BAT **ex
                                  h ? BATgetId(h) : "NULL", h ? BATcount(h) : 0,
                                  subsorted, gc ? " (g clustered)" : "");
                nme = GDKinmemory() ? ":inmemory" : BBP_physical(b->batCacheid);
-               mask = MAX(HASHmask(cnt), 1 << 16);
-               /* mask is a power of two, so pop(mask - 1) tells us
-                * which power of two */
-               bits = 8 * SIZEOF_OID - pop(mask - 1);
+               if (grps && !gc) {
+                       /* we manipulate the hash value after having
+                        * calculated it, and when doing that, we
+                        * assume the mask (i.e. nbucket-1) is a
+                        * power-of-two minus one, so make sure it
+                        * is */
+                       nbucket = cnt | cnt >> 1;
+                       nbucket |= nbucket >> 2;
+                       nbucket |= nbucket >> 4;
+                       nbucket |= nbucket >> 8;
+                       nbucket |= nbucket >> 16;
+#if SIZEOF_BUN == 8
+                       nbucket |= nbucket >> 32;
+#endif
+                       nbucket++;
+                       /* nbucket is a power of two, so pop(nbucket - 1)
+                        * tells us which power of two */
+                       bits = 8 * SIZEOF_OID - pop(nbucket - 1);
+               } else {
+                       nbucket = MAX(HASHmask(cnt), 1 << 16);
+               }
                if ((hs = GDKzalloc(sizeof(Hash))) == NULL ||
                    (hs->heaplink.farmid = BBPselectfarm(TRANSIENT, b->ttype, 
hashheap)) < 0 ||
                    (hs->heapbckt.farmid = BBPselectfarm(TRANSIENT, b->ttype, 
hashheap)) < 0) {
@@ -1087,7 +1104,7 @@ BATgroup_internal(BAT **groups, BAT **ex
                }
                if (snprintf(hs->heaplink.filename, 
sizeof(hs->heaplink.filename), "%s.thshgrpl%x", nme, THRgettid()) >= (int) 
sizeof(hs->heaplink.filename) ||
                    snprintf(hs->heapbckt.filename, 
sizeof(hs->heapbckt.filename), "%s.thshgrpb%x", nme, THRgettid()) >= (int) 
sizeof(hs->heapbckt.filename) ||
-                   HASHnew(hs, b->ttype, BUNlast(b), mask, BUN_NONE, false) != 
GDK_SUCCEED) {
+                   HASHnew(hs, b->ttype, BUNlast(b), nbucket, BUN_NONE, false) 
!= GDK_SUCCEED) {
                        GDKfree(hs);
                        hs = NULL;
                        GDKerror("BATgroup: cannot allocate hash table\n");
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -436,6 +436,7 @@ BATcheckhash(BAT *b)
                                                    ((size_t) 1 << 24) |
 #endif
                                                    HASH_VERSION) &&
+                                           hdata[1] > 0 &&
                                            hdata[4] == (size_t) BATcount(b) &&
                                            fstat(fd, &st) == 0 &&
                                            st.st_size >= (off_t) 
(h->heapbckt.size = h->heapbckt.free = (h->nbucket = (BUN) hdata[2]) * (BUN) 
(h->width = (uint8_t) hdata[3]) + HASH_HEADER_SIZE * SIZEOF_SIZE_T) &&
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to