u3: adds new +mug (as u3r_gum_*)

This commit is contained in:
Joe Bryan 2020-11-25 00:42:37 -08:00
parent fc30df7401
commit 09782dcba1
3 changed files with 158 additions and 0 deletions

View File

@ -34,6 +34,22 @@
c3_o
u3r_mean(u3_noun a, ...);
/* u3r_gum_both(): Join two mugs.
*/
c3_l
u3r_gum_both(c3_l lef_l, c3_l rit_l);
/* u3r_gum_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_l
u3r_gum_bytes(const c3_y *buf_y,
c3_w len_w);
/* u3r_gum_c(): Compute the mug of `a`, LSB first.
*/
c3_l
u3r_gum_c(const c3_c* a_c);
/* u3r_mug_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_w

View File

@ -1479,6 +1479,78 @@ u3r_tape(u3_noun a)
return a_y;
}
/* u3r_gum_both(): Join two mugs.
*/
c3_l
u3r_gum_both(c3_l lef_l, c3_l rit_l)
{
c3_y len_y = 4 + ((c3_bits_word(rit_l) + 0x7) >> 3);
c3_w syd_w = 0xdeadbeef;
c3_w i_w = 0;
c3_y buf_y[8];
buf_y[0] = lef_l & 0xff;
buf_y[1] = (lef_l >> 8) & 0xff;
buf_y[2] = (lef_l >> 16) & 0xff;
buf_y[3] = (lef_l >> 24) & 0xff;
buf_y[4] = rit_l & 0xff;
buf_y[5] = (rit_l >> 8) & 0xff;
buf_y[6] = (rit_l >> 16) & 0xff;
buf_y[7] = (rit_l >> 24) & 0xff;
while ( i_w < 8 ) {
c3_w haz_w;
c3_l ham_l;
MurmurHash3_x86_32(buf_y, len_y, syd_w, &haz_w);
ham_l = (haz_w >> 31) ^ (haz_w & 0x7fffffff);
if ( 0 == ham_l ) {
syd_w++; i_w++;
}
else {
return ham_l;
}
}
return 0xfffe;
}
/* u3r_gum_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_l
u3r_gum_bytes(const c3_y *buf_y,
c3_w len_w)
{
c3_w syd_w = 0xcafebabe;
c3_w i_w = 0;
while ( i_w < 8 ) {
c3_w haz_w;
c3_l ham_l;
MurmurHash3_x86_32(buf_y, len_w, syd_w, &haz_w);
ham_l = (haz_w >> 31) ^ (haz_w & 0x7fffffff);
if ( 0 == ham_l ) {
syd_w++; i_w++;
}
else {
return ham_l;
}
}
return 0x7fff;
}
/* u3r_gum_c(): Compute the mug of `a`, LSB first.
*/
c3_l
u3r_gum_c(const c3_c* a_c)
{
return u3r_gum_bytes((c3_y*)a_c, strlen(a_c));
}
/* u3r_mug_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_w

View File

@ -192,6 +192,71 @@ _test_mug(void)
return ret_i;
}
/* _test_mug(): spot check u3r_mug hashes.
*/
static c3_i
_test_gum(void)
{
c3_i ret_i = 1;
if ( 0x4d441035 != u3r_gum_c("Hello, world!") ) {
fprintf(stderr, "fail (a)\r\n");
ret_i = 0;
}
if ( 0x79ff04e8 != u3r_mug_bytes(0, 0) ) {
fprintf(stderr, "fail (c)\r\n");
ret_i = 0;
}
{
c3_y byt_y[1] = {1};
if ( 0x715c2a60 != u3r_mug_bytes(byt_y, 1) ) {
fprintf(stderr, "fail (c)\r\n");
ret_i = 0;
}
byt_y[0] = 2;
if ( 0x718b9468 != u3r_mug_bytes(byt_y, 1) ) {
fprintf(stderr, "fail (c)\r\n");
ret_i = 0;
}
}
{
if ( 0x64dfda5c != u3r_gum_c("xxxxxxxxxxxxxxxxxxxxxxxxxxxx") ) {
fprintf(stderr, "fail (d)\r\n");
ret_i = 0;
}
}
// [0 0]
//
if ( 0x192f5588 != u3r_gum_both(0x79ff04e8, 0x79ff04e8) ) {
fprintf(stderr, "fail (e)\r\n");
ret_i = 0;
}
// [1 1]
//
if ( 0x6b32ec46 != u3r_gum_both(0x715c2a60, 0x715c2a60) ) {
fprintf(stderr, "fail (f)\r\n");
ret_i = 0;
}
// [2 2]
//
if ( 0x2effe10 != u3r_gum_both(0x718b9468, 0x718b9468) ) {
fprintf(stderr, "fail (f)\r\n");
ret_i = 0;
}
return ret_i;
}
/* main(): run all test cases.
*/
int
@ -204,6 +269,11 @@ main(int argc, char* argv[])
exit(1);
}
if ( !_test_gum() ) {
fprintf(stderr, "test_mug: failed\r\n");
exit(1);
}
// GC
//
u3m_grab(u3_none);