Changeset: bfeeeecb69ff for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bfeeeecb69ff
Modified Files:
        gdk/gdk_atoms.c
        gdk/gdk_bat.c
        gdk/gdk_group.c
        gdk/gdk_search.c
        gdk/gdk_search.h
        gdk/gdk_select.c
        gdk/gdk_unique.c
Branch: default
Log Message:

Update of hash handling.
- the "hash" function for bte and sht are now the identity function;
- the hash mask is at least 1<<16 for anything larger than bte;
- removed unused cruft;
- in gdk_select and gdk_unique, make use of the knowledge that some
  "hash" functions are perfect (i.e. no collisions).


diffs (truncated from 410 to 300 lines):

diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c
--- a/gdk/gdk_atoms.c
+++ b/gdk/gdk_atoms.c
@@ -82,7 +82,7 @@ bteHash(const bte *v)
 static BUN
 shtHash(const sht *v)
 {
-       return (BUN) mix_sht(*(const unsigned short *) v);
+       return (BUN) *(const unsigned short *) v;
 }
 
 static BUN
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -2879,6 +2879,7 @@ BATassertHeadProps(BAT *b)
                        size_t nmelen = strlen(nme);
                        Heap *hp;
                        Hash *hs = NULL;
+                       BUN mask;
 
                        if ((hp = GDKzalloc(sizeof(Heap))) == NULL ||
                            (hp->filename = GDKmalloc(nmelen + 30)) == NULL) {
@@ -2892,10 +2893,16 @@ BATassertHeadProps(BAT *b)
                        snprintf(hp->filename, nmelen + 30,
                                 "%s.hash" SZFMT, nme, MT_getpid());
                        ext = GDKstrdup(hp->filename + nmelen + 1);
+                       if (ATOMsize(b->htype) == 1)
+                               mask = 1 << 8;
+                       else if (ATOMsize(b->htype) == 2)
+                               mask = 1 << 16;
+                       else
+                               mask = HASHmask(b->batCount);
                        if ((hp->farmid = BBPselectfarm(TRANSIENT, b->htype,
                                                        hashheap)) < 0 ||
                            (hs = HASHnew(hp, b->htype, BUNlast(b),
-                                         HASHmask(b->batCount))) == NULL) {
+                                         mask)) == NULL) {
                                GDKfree(ext);
                                GDKfree(hp->filename);
                                GDKfree(hp);
@@ -3093,16 +3100,23 @@ BATderiveHeadProps(BAT *b, int expensive
                b->H->nodense = 0;
        }
        if (expensive) {
+               BUN mask;
+
                nme = BBP_physical(b->batCacheid);
                nmelen = strlen(nme);
+               if (ATOMsize(b->htype) == 1)
+                       mask = 1 << 8;
+               else if (ATOMsize(b->htype) == 2)
+                       mask = 1 << 16;
+               else
+                       mask = HASHmask(b->batCount);
                if ((hp = GDKzalloc(sizeof(Heap))) == NULL ||
                    (hp->filename = GDKmalloc(nmelen + 30)) == NULL ||
                    (hp->farmid = BBPselectfarm(TRANSIENT, b->htype, hashheap)) 
< 0 ||
                    snprintf(hp->filename, nmelen + 30,
                             "%s.hash" SZFMT, nme, MT_getpid()) < 0 ||
                    (ext = GDKstrdup(hp->filename + nmelen + 1)) == NULL ||
-                   (hs = HASHnew(hp, b->htype, BUNlast(b),
-                                 HASHmask(b->batCount))) == NULL) {
+                   (hs = HASHnew(hp, b->htype, BUNlast(b), mask)) == NULL) {
                        if (hp) {
                                if (hp->filename)
                                        GDKfree(hp->filename);
diff --git a/gdk/gdk_group.c b/gdk/gdk_group.c
--- a/gdk/gdk_group.c
+++ b/gdk/gdk_group.c
@@ -186,7 +186,6 @@
        /* KEEP   */    pv = v                                  \
        )
 
-
 /* If a hash table exists on b we use it.
  *
  * The algorithm is simple.  We go through b and for each value we
@@ -283,7 +282,7 @@
                                     hb != HASHnil(hs) &&               \
                                      grps[hb - r] == grps[p - r];      \
                                     hb = HASHgetlink(hs,hb)) {         \
-                                       assert( HASHgetlink(hs,hb) == 
HASHnil(hs) \
+                                       assert(HASHgetlink(hs,hb) == 
HASHnil(hs) \
                                               || HASHgetlink(hs,hb) < hb); \
                                        if (COMP) {             \
                                                oid grp = ngrps[hb - r]; \
@@ -302,7 +301,7 @@
                                        hb = HASHnil(hs);               \
                                }                                       \
                        } else if (grps) {                              \
-                               prb = ((prb << bits) ^ (BUN) grps[p-r]) & 
hs->mask; \
+                               prb = (prb ^ (BUN) grps[p-r] << bits) & 
hs->mask; \
                                for (hb = HASHget(hs,prb);              \
                                     hb != HASHnil(hs);                 \
                                     hb = HASHgetlink(hs,hb)) {         \
@@ -833,6 +832,16 @@ BATgroup_internal(BAT **groups, BAT **ex
                                  subsorted, gc ? " (g clustered)" : "");
                nme = BBP_physical(b->batCacheid);
                nmelen = strlen(nme);
+               if (ATOMsize(t) == 1) {
+                       mask = 1 << 16;
+                       bits = 8;
+               } else if (ATOMsize(t) == 2) {
+                       mask = 1 << 16;
+                       bits = 8;
+               } else {
+                       mask = HASHmask(b->batCount);
+                       bits = 0;
+               }
                if ((hp = GDKzalloc(sizeof(Heap))) == NULL ||
                    (hp->farmid = BBPselectfarm(TRANSIENT, b->ttype, hashheap)) 
< 0 ||
                    (hp->filename = GDKmalloc(nmelen + 30)) == NULL ||
@@ -840,7 +849,7 @@ BATgroup_internal(BAT **groups, BAT **ex
                             "%s.hash" SZFMT, nme, MT_getpid()) < 0 ||
                    (ext = GDKstrdup(hp->filename + nmelen + 1)) == NULL ||
                    (hs = HASHnew(hp, b->ttype, BUNlast(b),
-                                 HASHmask(b->batCount))) == NULL) {
+                                 MAX(HASHmask(b->batCount), 1 << 16))) == 
NULL) {
                        if (hp) {
                                if (hp->filename)
                                        GDKfree(hp->filename);
diff --git a/gdk/gdk_search.c b/gdk/gdk_search.c
--- a/gdk/gdk_search.c
+++ b/gdk/gdk_search.c
@@ -98,7 +98,7 @@ HASHwidth(BUN hashsize)
 BUN
 HASHmask(BUN cnt)
 {
-       BUN m = 8;              /* minimum size */
+       BUN m = 1 << 8;         /* minimum size */
 
        while (m + m < cnt)
                m += m;
@@ -263,7 +263,7 @@ BAThash(BAT *b, BUN masksize)
                } else if (ATOMsize(tpe) == 1) {
                        mask = (1 << 8);
                } else if (ATOMsize(tpe) == 2) {
-                       mask = (1 << 12);
+                       mask = (1 << 16);
                } else if (b->tkey) {
                        mask = HASHmask(cnt);
                } else {
@@ -278,8 +278,6 @@ BAThash(BAT *b, BUN masksize)
                                p = q;
                }
 
-               if (mask < 1024)
-                       mask = 1024;
                t0 = GDKusec();
                do {
                        BUN nslots = mask >> 3; /* 1/8 full is too full */
diff --git a/gdk/gdk_search.h b/gdk/gdk_search.h
--- a/gdk/gdk_search.h
+++ b/gdk/gdk_search.h
@@ -128,14 +128,13 @@ gdk_export BUN HASHlist(Hash *h, BUN i);
        } while (0)
 #endif
 
-#define mix_sht(X)     (((X)>>7)^(X))
 #define mix_int(X)     (((X)>>7)^((X)>>13)^((X)>>21)^(X))
 #define hash_loc(H,V)  hash_any(H,V)
 #define hash_var(H,V)  hash_any(H,V)
 #define hash_any(H,V)  (ATOMhash((H)->type, (V)) & (H)->mask)
 #define heap_hash_any(hp,H,V)  ((hp) && (hp)->hashash ? ((BUN *) (V))[-1] & 
(H)->mask : hash_any(H,V))
-#define hash_bte(H,V)  ((BUN) (*(const unsigned char*) (V)) & (H)->mask)
-#define hash_sht(H,V)  ((BUN) mix_sht(*((const unsigned short*) (V))) & 
(H)->mask)
+#define hash_bte(H,V)  (assert(((H)->mask & 0xFF) == 0xFF), (BUN) *(const 
unsigned char*) (V))
+#define hash_sht(H,V)  (assert(((H)->mask & 0xFFFF) == 0xFFFF), (BUN) *(const 
unsigned short*) (V))
 #define hash_int(H,V)  ((BUN) mix_int(*((const unsigned int*) (V))) & 
(H)->mask)
 /* XXX return size_t-sized value for 8-byte oid? */
 #define hash_lng(H,V)  ((BUN) mix_int((unsigned int) (*(const lng *)(V) ^ 
(*(const lng *)(V) >> 32))) & (H)->mask)
@@ -226,109 +225,26 @@ gdk_export BUN HASHlist(Hash *h, BUN i);
 #define HASHfnd_any(x,y,z)     HASHfnd(x,y,z)
 /*
  * A new entry is added with HASHins using the BAT, the BUN index, and
- * a pointer to the value to be stored. An entry is removed by HASdel.
- */
-#define HASHins_TYPE(h, i, v, TYPE)            \
-       do {                                    \
-               BUN _c = hash_##TYPE(h,v);      \
-               HASHputall(h,i,_c);             \
-       } while (0)
-
-#define HASHins_str(h,i,v)                     \
-       do {                                    \
-               BUN _c;                         \
-               GDK_STRHASH(v,_c);              \
-               _c &= (h)->mask;                \
-               HASHputall(h,i,_c);             \
-       } while (0)
-#define HASHins_str_hv(h,i,v)                          \
-       do {                                            \
-               BUN _c = ((BUN *) v)[-1] & (h)->mask;   \
-               HASHputall(h,i,_c);             \
-       } while (0)
-
-#define HASHins_any(h,i,v)                     \
-       do {                                    \
-               BUN _c = HASHprobe(h, v);       \
-               HASHputall(h,i,_c);             \
-       } while (0)
-
-/* HASHins receives a BAT* param and is adaptive, killing wrongly
+ * a pointer to the value to be stored.
+ *
+ * HASHins receives a BAT* param and is adaptive, killing wrongly
  * configured hash tables.
  * Use HASHins_any or HASHins_<tpe> instead if you know what you're
  * doing or want to keep the hash. */
 #define HASHins(b,i,v)                                                 \
        do {                                                            \
-               if (((i) & 1023) == 1023 && HASHgonebad((b),(v)))       \
+               if (((i) & 1023) == 1023 && HASHgonebad((b), (v)))      \
                        HASHremove(b);                                  \
-               else                                                    \
-                       HASHins_any((b)->T->hash,(i),(v));              \
+               else {                                                  \
+                       BUN _c = HASHprobe((b)->T->hash, (v));          \
+                       HASHputall((b)->T->hash, (i), _c);              \
+               }                                                       \
        } while (0)
 
-#if SIZEOF_VOID_P == SIZEOF_INT
-#define HASHins_ptr(h,i,v)     HASHins_int(h,i,v)
-#else /* SIZEOF_VOID_P == SIZEOF_LNG */
-#define HASHins_ptr(h,i,v)     HASHins_lng(h,i,v)
-#endif
-#define HASHins_bit(h,i,v)     HASHins_bte(h,i,v)
-#if SIZEOF_OID == SIZEOF_INT   /* OIDDEPEND */
-#define HASHins_oid(h,i,v)     HASHins_int(h,i,v)
-#else
-#define HASHins_oid(h,i,v)     HASHins_lng(h,i,v)
-#endif
-#define HASHins_flt(h,i,v)     HASHins_int(h,i,v)
-#define HASHins_dbl(h,i,v)     HASHins_lng(h,i,v)
-#define HASHinsvar(h,i,v)      HASHins_any(h,i,v)
-#define HASHinsloc(h,i,v)      HASHins_any(h,i,v)
-
-#define HASHins_bte(h,i,v)     HASHins_TYPE(h,i,v,bte)
-#define HASHins_sht(h,i,v)     HASHins_TYPE(h,i,v,sht)
-#define HASHins_int(h,i,v)     HASHins_TYPE(h,i,v,int)
-#define HASHins_lng(h,i,v)     HASHins_TYPE(h,i,v,lng)
-#ifdef HAVE_HGE
-#define HASHins_hge(h,i,v)     HASHins_TYPE(h,i,v,hge)
-#endif
-
-#define HASHdel(h, i, v, next)                                         \
-       do {                                                            \
-               if (next && HASHgetlink(h, i+1) == i) {                 \
-                       HASHputlink(h,i+1,HASHgetlink(h,i));            \
-               } else {                                                \
-                       BUN _c = HASHprobe(h, v);                       \
-                       if (HASHget(h,_c) == i) {                       \
-                               HASHput(h,_c, HASHgetlink(h,i));        \
-                       } else {                                        \
-                               for(_c = HASHget(h,_c); _c != HASHnil(h); \
-                                   _c = HASHgetlink(h,_c)) {           \
-                                       if (HASHgetlink(h,_c) == i) {   \
-                                               HASHputlink(h,_c, 
HASHgetlink(h,i)); \
-                                               break;                  \
-                                       }                               \
-                               }                                       \
-                       }                                               \
-               }                                                       \
-               HASHputlink(h,i,HASHnil(h));                            \
-       } while (0)
-
-#define HASHmove(h, i, j, v, next)                                     \
-       do {                                                            \
-               if (next && HASHgetlink(h,i+1) == i) {                  \
-                       HASHputlink(h,i+1,j);                           \
-               } else {                                                \
-                       BUN _c = HASHprobe(h, v);                       \
-                       if (HASHget(h,_c) == i) {                       \
-                               HASHput(h,_c,j);                        \
-                       } else {                                        \
-                               for(_c = HASHget(h,_c) ; _c != HASHnil(h); \
-                                   _c = HASHgetlink(h,_c)) {           \
-                                       if (HASHgetlink(h,_c) == i) {   \
-                                               HASHputlink(h,_c,j);    \
-                                               break;                  \
-                                       }                               \
-                               }                                       \
-                       }                                               \
-               }                                                       \
-               HASHputlink(h,j, HASHgetlink(h,i));                     \
+#define HASHins_oid(h,i,v)                     \
+       do {                                    \
+               BUN _c = hash_oid(h,v);         \
+               HASHputall(h,i,_c);             \
        } while (0)
 
 /* Functions to perform a binary search on a sorted BAT.
diff --git a/gdk/gdk_select.c b/gdk/gdk_select.c
--- a/gdk/gdk_select.c
+++ b/gdk/gdk_select.c
@@ -152,12 +152,13 @@ doubleslice(BAT *b, BUN l1, BUN h1, BUN 
        return virtualize(bn);
 }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to