diff --git a/f/loom.c b/f/loom.c index 91349d61b..86c94cfd5 100644 --- a/f/loom.c +++ b/f/loom.c @@ -1195,7 +1195,7 @@ _mur_fmix(c3_w h_w) /* u2_mur_words(): MurmurHash3 on raw words. */ c3_w -u2_mur_words(c3_w* key_w, c3_w len_w, c3_w syd_w) +u2_mur_words(c3_w syd_w, c3_w len_w, c3_w* key_w) { c3_w goc_w = syd_w; c3_w lig_w = 0xcc9e2d51; @@ -1219,6 +1219,22 @@ u2_mur_words(c3_w* key_w, c3_w len_w, c3_w syd_w) return goc_w; } +/* u2_muz_words(): 31-bit nonzero MurmurHash3 on raw words. +*/ +c3_w +u2_muz_words(c3_w len_w, c3_w* key_w) +{ + c3_w syd_w = 0xcafebabe; + + while ( 1 ) { + c3_w haz_w = u2_mur_words(syd_w, len_w, key_w); + c3_w ham_w = (haz_w >> 31) ^ (haz_w & 0x7fffffff); + + if ( 0 != ham_w ) return ham_w; + else syd_w++; + } +} + /* u2_mug(): ** ** Compute and/or recall the mug (31-bit FNV1a hash) of (a). @@ -1400,6 +1416,34 @@ _mug_words_buf(c3_w off_w, c3_w nwd_w, u2_noun veb) } } +/* u2_mum(): MurmurHash3 on a noun. +*/ +c3_w +u2_mum(u2_noun veb) +{ + if ( u2_fly_is_cat(veb) ) { + return u2_muz_words((0 == veb) ? 0 : 1, &veb); + } + else { + if ( u2_dog_is_pom(veb) ) { + c3_w ham_w = u2_mum(u2h(veb)) ^ (0x7fffffff ^ u2_mum(u2t(veb))); + + return u2_muz_words((0 == ham_w) ? 0 : 1, &ham_w); + } + else { + c3_w len_w = u2_met(5, veb); + c3_w* buf_w = malloc(4 * len_w); + c3_w ham_w; + + u2_words(0, len_w, buf_w, veb); + ham_w = u2_muz_words(len_w, buf_w); + + free(buf_w); + return ham_w; + } + } +} + c3_w u2_mug(u2_noun veb) { @@ -1471,6 +1515,7 @@ u2_mug_cell(u2_noun hed, return u2_mug_both(lus_w, biq_w); } + /* u2_mug_trel(): ** ** Compute the mug of `[a b c]`. diff --git a/gen164/3/mur.c b/gen164/3/mur.c index 02a0e6260..a2caa9e6d 100644 --- a/gen164/3/mur.c +++ b/gen164/3/mur.c @@ -8,20 +8,44 @@ /* functions */ u2_weak // transfer - j2_mbc(Pt3, mur)(u2_wire wir_r, - u2_atom key, // retain - u2_atom syd) // retain + j2_mb(Pt3, mum)(u2_wire wir_r, + u2_noun cor) // retain + { + u2_noun sam; + + if ( u2_none == (sam = u2_frag(u2_cv_sam, cor)) ) { + return u2_bl_bail(wir_r, c3__exit); + } else { + return u2_mum(sam); + } + } + +/* structures +*/ + u2_ho_jet + j2_mbj(Pt3, mum)[] = { + { ".2", c3__lite, j2_mb(Pt3, mum), + u2_jet_test | u2_jet_live, u2_none, u2_none }, + { } + }; + + +/* functions +*/ + u2_weak // transfer + j2_mbc(Pt3, mur)(u2_wire wir_r, + u2_atom syd, // retain + u2_atom key) // retain { - c3_w len_w = u2_cr_met(5, key); c3_w syd_w = u2_cr_word(0, syd); + c3_w len_w = u2_cr_met(5, key); { c3_w* key_w = alloca(4 * len_w); c3_w goc_w; u2_cr_words(0, len_w, key_w, key); - goc_w = u2_mur_words(key_w, len_w, syd_w); + goc_w = u2_mur_words(syd_w, len_w, key_w); - fprintf(stderr, "goc_w %x\r\n", goc_w); return u2_ci_words(1, &goc_w); } } diff --git a/gen164/watt.c b/gen164/watt.c index 7ee06ca8d..408ea136c 100644 --- a/gen164/watt.c +++ b/gen164/watt.c @@ -63,6 +63,7 @@ extern u2_ho_jet j2_mbj(Pt3, met)[]; extern u2_ho_jet j2_mbj(Pt3, mix)[]; extern u2_ho_jet j2_mbj(Pt3, mug)[]; + extern u2_ho_jet j2_mbj(Pt3, mum)[]; extern u2_ho_jet j2_mbj(Pt3, mur)[]; extern u2_ho_jet j2_mbj(Pt3, peg)[]; extern u2_ho_jet j2_mbj(Pt3, rap)[]; @@ -212,6 +213,7 @@ { j2_sb(Pt3, met), j2_mbj(Pt3, met), 0, 0, u2_none }, { j2_sb(Pt3, mix), j2_mbj(Pt3, mix), 0, 0, u2_none }, { j2_sb(Pt3, mug), j2_mbj(Pt3, mug), 0, 0, u2_none }, + { j2_sb(Pt3, mum), j2_mbj(Pt3, mum), 0, 0, u2_none }, { j2_sb(Pt3, mur), j2_mbj(Pt3, mur), 0, 0, u2_none }, { j2_sb(Pt3, peg), j2_mbj(Pt3, peg), 0, 0, u2_none }, { j2_sb(Pt3, rap), j2_mbj(Pt3, rap), 0, 0, u2_none }, diff --git a/include/f/loom.h b/include/f/loom.h index 7cc2e7451..22b82f176 100644 --- a/include/f/loom.h +++ b/include/f/loom.h @@ -555,10 +555,17 @@ c3_w u2_mug(u2_noun a); + /* u2_mug(): + ** + ** Compute and/or recall the mug (31-bit hash) of (a). + */ + c3_w + u2_mum(u2_noun a); + /* u2_mur_words(): MurmurHash3 on raw words. */ c3_w - u2_mur_words(c3_w* key_w, c3_w len_w, c3_w syd_w); + u2_mur_words(c3_w syd_w, c3_w len_w, c3_w* key_w); /* u2_mug_string(): **