github.com/sandwich-go/boost@v1.3.29/xhash/nhash/jenkins/hash.go (about) 1 // Copyright © 2014 Lawrence E. Bakst. All rights reserved. 2 3 // This package contains various transliteration of Jenkins hash funcions. 4 // This includes lookup3.c and some other Jenkins functions that appear to be based on lookup2.c. 5 // See http://burtleburtle.net/bob/c/lookup3.c and http://burtleburtle.net/bob/hash/evahash.html 6 7 package jenkins 8 9 import ( 10 "fmt" 11 "github.com/sandwich-go/boost/xhash/nhash" 12 "hash" 13 "unsafe" 14 ) 15 16 // Make sure interfaces are correctly implemented. Stolen from another implementation. 17 // I did something similar in another package to verify the interface but didn't know you could elide the variable in a var. 18 // What a cute wart it is. 19 var ( 20 //_ hash.Hash = new(Digest) 21 _ hash.Hash32 = new(State332c) 22 _ nhash.HashF32 = new(State332c) 23 ) 24 25 /* 26 uint32_t jenkins_one_at_a_time_hash(char *key, size_t len) 27 { 28 uint32_t hash, i; 29 for(hash = i = 0; i < len; ++i) 30 { 31 hash += key[i]; 32 hash += (hash << 10); 33 hash ^= (hash >> 6); 34 } 35 hash += (hash << 3); 36 hash ^= (hash >> 11); 37 hash += (hash << 15); 38 return hash; 39 } 40 */ 41 42 // This function mixes the state 43 func mix32(a, b, c uint32) (uint32, uint32, uint32) { 44 a = a - b 45 a = a - c 46 a = a ^ (c >> 13) 47 b = b - c 48 b = b - a 49 b = b ^ (a << 8) 50 c = c - a 51 c = c - b 52 c = c ^ (b >> 13) 53 a = a - b 54 a = a - c 55 a = a ^ (c >> 12) 56 b = b - c 57 b = b - a 58 b = b ^ (a << 16) 59 c = c - a 60 c = c - b 61 c = c ^ (b >> 5) 62 a = a - b 63 a = a - c 64 a = a ^ (c >> 3) 65 b = b - c 66 b = b - a 67 b = b ^ (a << 10) 68 c = c - a 69 c = c - b 70 c = c ^ (b >> 15) 71 return a, b, c 72 } 73 74 func mix32a(a, b, c uint32) (uint32, uint32, uint32) { 75 a = a - b - c ^ (c >> 13) 76 b = b - c - a ^ (a << 8) 77 c = c - a - b ^ (b >> 13) 78 a = a - b - c ^ (c >> 12) 79 b = b - c - a ^ (a << 16) 80 c = c - a - b ^ (b >> 5) 81 a = a - b - c ^ (c >> 3) 82 b = b - c - a ^ (a << 10) 83 c = c - a - b ^ (b >> 15) 84 return a, b, c 85 } 86 87 func Check() { 88 var a, b, c uint32 89 var init = func() { 90 a, b, c = 0x12345678, 0x87654321, 0xdeadbeef 91 } 92 93 init() 94 a = a - b 95 a = a - c 96 fmt.Printf("a=0x%08x\n", a) 97 a = a ^ (c >> 13) 98 fmt.Printf("a=0x%08x\n", a) 99 fmt.Printf("a=0x%08x, b=0x%08x, c=0x%08x\n", a, b, c) 100 init() 101 a = ((a - b) - c) 102 fmt.Printf("a=0x%08x\n", a) 103 a = a ^ (c >> 13) 104 fmt.Printf("a=0x%08x\n", a) 105 fmt.Printf("a=0x%08x, b=0x%08x, c=0x%08x\n", a, b, c) 106 } 107 108 // This makes a new slice of uint64 that points to the same slice passed in as []byte. 109 // We should check alignment for architectures that don't handle unaligned reads. 110 // Fallback to a copy or maybe use encoding/binary? 111 // Not sure what the right thing to do is for little vs big endian? 112 // What are the right test vevtors for big-endian machines. 113 func sliceUI32(in []byte) []uint32 { 114 return (*(*[]uint32)(unsafe.Pointer(&in)))[:len(in)/4] 115 } 116 117 // Jenkin's second generation 32 bit hash. 118 // Benchmarked with 4 byte key, inlining, and no store of hash at: 119 // benchmark32: 55 Mhashes/sec 120 // benchmark32: 219 MB/sec 121 func Hash232(k []byte, seed uint32) uint32 { 122 var fast = true // fast is really much faster 123 l := uint32(len(k)) 124 a := uint32(0x9e3779b9) // the golden ratio; an arbitrary value 125 b := a 126 c := seed // variable initialization of internal state 127 128 if fast { 129 k32 := sliceUI32(k) 130 cnt := 0 131 for ; l >= 12; l -= 12 { 132 a += k32[0+cnt] 133 b += k32[1+cnt] 134 c += k32[2+cnt] 135 a, b, c = mix32(a, b, c) 136 k = k[12:] 137 cnt += 3 138 } 139 } else { 140 for ; l >= 12; l -= 12 { 141 a += uint32(k[0]) + uint32(k[1])<<8 + uint32(k[2])<<16 + uint32(k[3])<<24 142 b += uint32(k[4]) + uint32(k[5])<<8 + uint32(k[6])<<16 + uint32(k[7])<<24 143 c += uint32(k[8]) + uint32(k[9])<<8 + uint32(k[10])<<16 + uint32(k[11])<<24 144 a, b, c = mix32(a, b, c) 145 k = k[12:] 146 } 147 } 148 149 c += l 150 switch l { 151 case 11: 152 c += uint32(k[10]) << 24 153 fallthrough 154 case 10: 155 c += uint32(k[9]) << 16 156 fallthrough 157 case 9: 158 c += uint32(k[8]) << 8 159 fallthrough 160 case 8: 161 b += uint32(k[7]) << 24 // the first byte of c is reserved for the length 162 fallthrough 163 case 7: 164 b += uint32(k[6]) << 16 165 fallthrough 166 case 6: 167 b += uint32(k[5]) << 8 168 fallthrough 169 case 5: 170 b += uint32(k[4]) 171 fallthrough 172 case 4: 173 a += uint32(k[3]) << 24 174 fallthrough 175 case 3: 176 a += uint32(k[2]) << 16 177 fallthrough 178 case 2: 179 a += uint32(k[1]) << 8 180 fallthrough 181 case 1: 182 c += uint32(k[0]) 183 fallthrough 184 case 0: 185 break 186 default: 187 panic("HashWords32") 188 } 189 a, b, c = mix32(a, b, c) 190 return c 191 } 192 193 // original mix function 194 func mix64(a, b, c uint64) (uint64, uint64, uint64) { 195 a = a - b 196 a = a - c 197 a = a ^ (c >> 43) 198 b = b - c 199 b = b - a 200 b = b ^ (a << 9) 201 c = c - a 202 c = c - b 203 c = c ^ (b >> 8) 204 a = a - b 205 a = a - c 206 a = a ^ (c >> 38) 207 b = b - c 208 b = b - a 209 b = b ^ (a << 23) 210 c = c - a 211 c = c - b 212 c = c ^ (b >> 5) 213 a = a - b 214 a = a - c 215 a = a ^ (c >> 35) 216 b = b - c 217 b = b - a 218 b = b ^ (a << 49) 219 c = c - a 220 c = c - b 221 c = c ^ (b >> 11) 222 a = a - b 223 a = a - c 224 a = a ^ (c >> 12) 225 b = b - c 226 b = b - a 227 b = b ^ (a << 18) 228 c = c - a 229 c = c - b 230 c = c ^ (b >> 22) 231 return a, b, c 232 } 233 234 // restated mix function better for gofmt 235 func mix64alt(a, b, c uint64) (uint64, uint64, uint64) { 236 a -= b - c ^ (c >> 43) 237 b -= c - a ^ (a << 9) 238 c -= a - b ^ (b >> 8) 239 a -= b - c ^ (c >> 38) 240 b -= c - a ^ (a << 23) 241 c -= a - b ^ (b >> 5) 242 a -= b - c ^ (c >> 35) 243 b -= c - a ^ (a << 49) 244 c -= a - b ^ (b >> 11) 245 a -= b - c ^ (c >> 12) 246 b -= c - a ^ (a << 18) 247 c -= a - b ^ (b >> 22) 248 return a, b, c 249 } 250 251 // the following functions can be inlined 252 func mix64a(a, b, c uint64) (uint64, uint64, uint64) { 253 a -= b - c ^ (c >> 43) 254 b -= c - a ^ (a << 9) 255 return a, b, c 256 } 257 258 func mix64b(a, b, c uint64) (uint64, uint64, uint64) { 259 c -= a - b ^ (b >> 8) 260 a -= b - c ^ (c >> 38) 261 return a, b, c 262 } 263 264 func mix64c(a, b, c uint64) (uint64, uint64, uint64) { 265 b -= c - a ^ (a << 23) 266 c -= a - b ^ (b >> 5) 267 return a, b, c 268 } 269 270 func mix64d(a, b, c uint64) (uint64, uint64, uint64) { 271 a -= b - c ^ (c >> 35) 272 b -= c - a ^ (a << 49) 273 return a, b, c 274 } 275 276 func mix64e(a, b, c uint64) (uint64, uint64, uint64) { 277 c -= a - b ^ (b >> 11) 278 a -= b - c ^ (c >> 12) 279 return a, b, c 280 } 281 282 func mix64f(a, b, c uint64) (uint64, uint64, uint64) { 283 b -= c - a ^ (a << 18) 284 c -= a - b ^ (b >> 22) 285 return a, b, c 286 } 287 288 // This makes a new slice of uint64 that points to the same slice passed in as []byte. 289 // We should check alignment for architectures that don't handle unaligned reads. 290 // Fallback to a copy or maybe use encoding/binary? 291 // Not sure what the right thing to do is for little vs big endian? 292 // What are the right test vevtors for big-endian machines. 293 func sliceUI64(in []byte) []uint64 { 294 return (*(*[]uint64)(unsafe.Pointer(&in)))[:len(in)/8] 295 } 296 297 // Jenkin's second generation 64 bit hash. 298 // Benchmarked with 24 byte key, inlining, store of hash in memory (cache miss every 4 hashes) and fast=true at: 299 // benchmark64: 26 Mhashes/sec 300 // benchmark64: 623 MB/sec 301 func Hash264(k []byte, seed uint64) uint64 { 302 var fast = true // fast is really much faster 303 //fmt.Printf("k=%v\n", k) 304 //fmt.Printf("length=%d, len(k)=%d\n", length, len(k)) 305 306 //The 64-bit golden ratio is 0x9e3779b97f4a7c13LL 307 length := uint64(len(k)) 308 a := uint64(0x9e3779b97f4a7c13) 309 b := a 310 c := seed 311 if fast { 312 k64 := sliceUI64(k) 313 cnt := 0 314 for i := length; i >= 24; i -= 24 { 315 a += k64[0+cnt] 316 b += k64[1+cnt] 317 c += k64[2+cnt] 318 // inlining is slightly faster 319 a, b, c = mix64a(a, b, c) 320 a, b, c = mix64b(a, b, c) 321 a, b, c = mix64c(a, b, c) 322 a, b, c = mix64d(a, b, c) 323 a, b, c = mix64e(a, b, c) 324 a, b, c = mix64f(a, b, c) 325 k = k[24:] 326 cnt += 3 327 length -= 24 328 } 329 } else { 330 for i := length; i >= 24; i -= 24 { 331 a += uint64(k[0]) | uint64(k[1])<<8 | uint64(k[2])<<16 | uint64(k[3])<<24 | uint64(k[4])<<32 | uint64(k[5])<<40 | uint64(k[6])<<48 | uint64(k[7])<<56 332 b += uint64(k[8]) | uint64(k[9])<<8 | uint64(k[10])<<16 | uint64(k[11])<<24 | uint64(k[12])<<32 | uint64(k[13])<<40 | uint64(k[14])<<48 | uint64(k[15])<<56 333 c += uint64(k[16]) | uint64(k[17])<<8 | uint64(k[18])<<16 | uint64(k[19])<<24 | uint64(k[20])<<32 | uint64(k[21])<<40 | uint64(k[22])<<48 | uint64(k[23])<<56 334 a, b, c = mix64alt(a, b, c) 335 k = k[24:] 336 length -= 24 337 } 338 } 339 c += length 340 if len(k) > 23 { 341 panic("Hash264") 342 } 343 switch length { 344 case 23: 345 c += uint64(k[22]) << 56 346 fallthrough 347 case 22: 348 c += uint64(k[21]) << 48 349 fallthrough 350 case 21: 351 c += uint64(k[20]) << 40 352 fallthrough 353 case 20: 354 c += uint64(k[19]) << 32 355 fallthrough 356 case 19: 357 c += uint64(k[18]) << 24 358 fallthrough 359 case 18: 360 c += uint64(k[17]) << 16 361 fallthrough 362 case 17: 363 c += uint64(k[16]) << 8 364 fallthrough 365 case 16: 366 b += uint64(k[15]) << 56 // the first byte of c is reserved for the length 367 fallthrough 368 case 15: 369 b += uint64(k[14]) << 48 370 fallthrough 371 case 14: 372 b += uint64(k[13]) << 40 373 fallthrough 374 case 13: 375 b += uint64(k[12]) << 32 376 fallthrough 377 case 12: 378 b += uint64(k[11]) << 24 379 fallthrough 380 case 11: 381 b += uint64(k[10]) << 16 382 fallthrough 383 case 10: 384 b += uint64(k[9]) << 8 385 fallthrough 386 case 9: 387 b += uint64(k[8]) 388 fallthrough 389 case 8: 390 a += uint64(k[7]) << 56 391 fallthrough 392 case 7: 393 a += uint64(k[6]) << 48 394 fallthrough 395 case 6: 396 a += uint64(k[5]) << 40 397 fallthrough 398 case 5: 399 a += uint64(k[4]) << 32 400 fallthrough 401 case 4: 402 a += uint64(k[3]) << 24 403 fallthrough 404 case 3: 405 a += uint64(k[2]) << 16 406 fallthrough 407 case 2: 408 a += uint64(k[1]) << 8 409 fallthrough 410 case 1: 411 a += uint64(k[0]) 412 case 0: 413 break 414 default: 415 panic("HashWords64") 416 } 417 a, b, c = mix64alt(a, b, c) 418 return c 419 } 420 421 /* 422 func omix(a, b, c uint32) (uint32, uint32, uint32) { 423 a -= c; a ^= rot(c, 4); c += b; 424 b -= a; b ^= rot(a, 6); a += c; 425 c -= b; c ^= rot(b, 8); b += a; 426 a -= c; a ^= rot(c,16); c += b; 427 b -= a; b ^= rot(a,19); a += c; 428 c -= b; c ^= rot(b, 4); b += a; 429 return a, b, c 430 } 431 432 func ofinal(a, b, c uint32) (uint32, uint32, uint32) { 433 c ^= b; c -= rot(b,14); 434 a ^= c; a -= rot(c,11); 435 b ^= a; b -= rot(a,25); 436 c ^= b; c -= rot(b,16); 437 a ^= c; a -= rot(c,4); 438 b ^= a; b -= rot(a,14); 439 c ^= b; c -= rot(b,24); 440 return a, b, c 441 } 442 443 444 func mix(a, b, c uint32) (uint32, uint32, uint32) { 445 a -= c; a ^= c << 4 | c >> (32 - 4); c += b; 446 b -= a; b ^= a << 6 | a >> (32 - 6); a += c; 447 c -= b; c ^= b << 8 | b >> (32 - 8); b += a; 448 a -= c; a ^= c << 16 | c >> (32 - 16); c += b; 449 b -= a; b ^= a << 19 | a >> (32 - 19); a += c; 450 c -= b; c ^= b << 4 | b >> (32 - 4); b += a; 451 return a, b, c 452 } 453 454 455 func final(a, b, c uint32) (uint32, uint32, uint32) { 456 c ^= b; c -= b << 14 | b >> (32 - 14); 457 a ^= c; a -= c << 11 | c >> (32 - 11); 458 b ^= a; b -= a << 25 | a >> (32 - 25); 459 c ^= b; c -= b << 16 | b >> (32 - 16); 460 a ^= c; a -= c << 4 | c >> (32 - 4); 461 b ^= a; b -= a << 14 | a >> (32 - 14); 462 c ^= b; c -= b << 24 | b >> (32 - 24); 463 return a, b, c 464 } 465 */ 466 467 //var a, b, c uint32 468 469 func rot(x, k uint32) uint32 { 470 return x<<k | x>>(32-k) 471 } 472 473 // current gc compilers can't inline long functions so we have to split mix into 2 474 func mix1(a, b, c uint32) (uint32, uint32, uint32) { 475 a -= c 476 a ^= rot(c, 4) 477 c += b 478 b -= a 479 b ^= rot(a, 6) 480 a += c 481 c -= b 482 c ^= rot(b, 8) 483 b += a 484 //a -= c; a ^= c << 4 | c >> (32 - 4); c += b; 485 //b -= a; b ^= a << 6 | a >> (32 - 6); a += c; 486 return a, b, c 487 } 488 489 func mix2(a, b, c uint32) (uint32, uint32, uint32) { 490 a -= c 491 a ^= rot(c, 16) 492 c += b 493 b -= a 494 b ^= rot(a, 19) 495 a += c 496 c -= b 497 c ^= rot(b, 4) 498 b += a 499 // c -= b; c ^= b << 8 | b >> (32 - 8); b += a; 500 // a -= c; a ^= c << 16 | c >> (32 - 16); c += b; 501 return a, b, c 502 } 503 504 /* 505 func mix3(a, b, c uint32) (uint32, uint32, uint32) { 506 b -= a; b ^= a << 19 | a >> (32 - 19); a += c; 507 c -= b; c ^= b << 4 | b >> (32 - 4); b += a; 508 return a, b, c 509 } 510 */ 511 512 func final1(a, b, c uint32) (uint32, uint32, uint32) { 513 c ^= b 514 c -= rot(b, 14) 515 a ^= c 516 a -= rot(c, 11) 517 b ^= a 518 b -= rot(a, 25) 519 c ^= b 520 c -= rot(b, 16) 521 //c ^= b; c -= b << 14 | b >> (32 - 14); 522 //a ^= c; a -= c << 11 | c >> (32 - 11); 523 //b ^= a; b -= a << 25 | a >> (32 - 25); 524 //c ^= b; c -= b << 16 | b >> (32 - 16); 525 return a, b, c 526 } 527 528 func final2(a, b, c uint32) (uint32, uint32, uint32) { 529 a ^= c 530 a -= rot(c, 4) 531 b ^= a 532 b -= rot(a, 14) 533 c ^= b 534 c -= rot(b, 24) 535 //a ^= c; a -= c << 4 | c >> (32 - 4); 536 //b ^= a; b -= a << 14 | a >> (32 - 14); 537 //c ^= b; c -= b << 24 | b >> (32 - 24); 538 return a, b, c 539 } 540 541 func HashWords332(k []uint32, seed uint32) uint32 { 542 var a, b, c uint32 543 544 length := uint32(len(k)) 545 a = 0xdeadbeef + length<<2 + seed 546 b, c = a, a 547 548 i := 0 549 for ; length > 3; length -= 3 { 550 a += k[i+0] 551 b += k[i+1] 552 c += k[i+2] 553 a, b, c = mix1(a, b, c) 554 a, b, c = mix2(a, b, c) 555 i += 3 556 } 557 558 switch length { 559 case 3: 560 c += k[i+2] 561 fallthrough 562 case 2: 563 b += k[i+1] 564 fallthrough 565 case 1: 566 a += k[i+0] 567 a, b, c = final1(a, b, c) 568 a, b, c = final2(a, b, c) 569 case 0: 570 break 571 } 572 return c 573 } 574 575 func HashWordsLen(k []uint32, length int, seed uint32) uint32 { 576 var a, b, c uint32 577 578 //fmt.Printf("k=%v\n", k) 579 //fmt.Printf("length=%d, len(k)=%d\n", length, len(k)) 580 if length > len(k)*4 { 581 fmt.Printf("length=%d, len(k)=%d\n", length, len(k)) 582 panic("HashWords") 583 } 584 585 ul := uint32(len(k)) 586 a = 0xdeadbeef + ul<<2 + seed 587 b, c = a, a 588 589 i := 0 590 //length := 0 591 for ; length > 3; length -= 3 { 592 a += k[i+0] 593 b += k[i+1] 594 c += k[i+2] 595 a, b, c = mix1(a, b, c) 596 a, b, c = mix2(a, b, c) 597 //a, b, c = mix3(a, b, c) 598 i += 3 599 } 600 601 //fmt.Printf("remaining length=%d, len(k)=%d, i=%d, k[i + 2]=%d, k[i + 1]=%d, k[i + 0]=%d\n", length, len(k), i, k[i + 2], k[i + 1], k[i + 0]) 602 switch length { 603 case 3: 604 c += k[i+2] 605 fallthrough 606 case 2: 607 b += k[i+1] 608 fallthrough 609 case 1: 610 a += k[i+0] 611 a, b, c = final1(a, b, c) 612 a, b, c = final2(a, b, c) 613 case 0: 614 break 615 } 616 //fmt.Printf("end\n") 617 return c 618 } 619 620 // This is an example of how I could like to code hash functions like this. 621 // Using closures over the state and expecting thme to be inlined 622 func XHashWords(k []uint32, length int, seed uint32) uint32 { 623 var a, b, c uint32 624 var rot = func(x, k uint32) uint32 { 625 return x<<k | x>>(32-k) 626 } 627 var mix = func() { 628 a -= c 629 a ^= rot(c, 4) 630 c += b 631 b -= a 632 b ^= rot(a, 6) 633 a += c 634 c -= b 635 c ^= rot(b, 8) 636 b += a 637 a -= c 638 a ^= rot(c, 16) 639 c += b 640 b -= a 641 b ^= rot(a, 19) 642 a += c 643 c -= b 644 c ^= rot(b, 4) 645 b += a 646 } 647 var final = func() { 648 c ^= b 649 c -= rot(b, 14) 650 a ^= c 651 a -= rot(c, 11) 652 b ^= a 653 b -= rot(a, 25) 654 c ^= b 655 c -= rot(b, 16) 656 a ^= c 657 a -= rot(c, 4) 658 b ^= a 659 b -= rot(a, 14) 660 c ^= b 661 c -= rot(b, 24) 662 } 663 ul := uint32(len(k)) 664 a = 0xdeadbeef + ul<<2 + seed 665 b, c = a, a 666 667 i := 0 668 //length := 0 669 for length = len(k); length > 3; length -= 3 { 670 a += k[i+0] 671 b += k[i+1] 672 c += k[i+2] 673 mix() 674 i += 3 675 } 676 677 switch length { 678 case 3: 679 c += k[i+2] 680 fallthrough 681 case 2: 682 b += k[i+1] 683 fallthrough 684 case 1: 685 a += k[i+0] 686 final() 687 case 0: 688 break 689 } 690 return c 691 } 692 693 // jenkins364: return 2 32-bit hash values. 694 // Returns two 32-bit hash values instead of just one. 695 // This is good enough for hash table lookup with 2^^64 buckets, 696 // or if you want a second hash if you're not happy with the first, 697 // or if you want a probably-unique 64-bit ID for the key. 698 // *pc is better mixed than *pb, so use *pc first. 699 // If you want a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)" 700 func Jenkins364(k []byte, length int, pc, pb uint32) (rpc, rpb uint32) { 701 var a, b, c uint32 702 703 //fmt.Printf("Jenkins364: k=%v, len(k)=%d\n", k, len(k)) 704 if length == 0 { 705 length = len(k) 706 } 707 /* 708 var rot = func(x, k uint32) uint32 { 709 return x << k | x >> (32 - k) 710 } 711 712 var mix = func() { 713 a -= c; a ^= rot(c, 4); c += b; 714 b -= a; b ^= rot(a, 6); a += c; 715 c -= b; c ^= rot(b, 8); b += a; 716 a -= c; a ^= rot(c,16); c += b; 717 b -= a; b ^= rot(a,19); a += c; 718 c -= b; c ^= rot(b, 4); b += a; 719 } 720 var final = func() { 721 c ^= b; c -= rot(b,14); 722 a ^= c; a -= rot(c,11); 723 b ^= a; b -= rot(a,25); 724 c ^= b; c -= rot(b,16); 725 a ^= c; a -= rot(c,4); 726 b ^= a; b -= rot(a,14); 727 c ^= b; c -= rot(b,24); 728 } 729 */ 730 ul := uint32(len(k)) 731 732 /* Set up the internal state */ 733 a = 0xdeadbeef + ul + pc 734 b, c = a, a 735 c += pb 736 737 for ; length > 12; length -= 12 { 738 //fmt.Printf("k=%q, length=%d\n", k, length) 739 a += *(*uint32)(unsafe.Pointer(&k[0])) 740 b += *(*uint32)(unsafe.Pointer(&k[4])) 741 c += *(*uint32)(unsafe.Pointer(&k[8])) 742 a, b, c = mix1(a, b, c) 743 a, b, c = mix2(a, b, c) 744 k = k[12:] 745 } 746 //fmt.Printf("k=%q, length=%d\n", k, length) 747 748 /* handle the last (probably partial) block */ 749 /* 750 * "k[2]&0xffffff" actually reads beyond the end of the string, but 751 * then masks off the part it's not allowed to read. Because the 752 * string is aligned, the masked-off tail is in the same word as the 753 * rest of the string. Every machine with memory protection I've seen 754 * does it on word boundaries, so is OK with this. But VALGRIND will 755 * still catch it and complain. The masking trick does make the hash 756 * noticably faster for short strings (like English words). 757 */ 758 759 //fmt.Printf("length now=%d\n", length) 760 switch length { 761 case 12: 762 a += *(*uint32)(unsafe.Pointer(&k[0])) 763 b += *(*uint32)(unsafe.Pointer(&k[4])) 764 c += *(*uint32)(unsafe.Pointer(&k[8])) 765 case 11: 766 c += uint32(k[10]) << 16 767 fallthrough 768 case 10: 769 c += uint32(k[9]) << 8 770 fallthrough 771 case 9: 772 c += uint32(k[8]) 773 fallthrough 774 case 8: 775 a += *(*uint32)(unsafe.Pointer(&k[0])) 776 b += *(*uint32)(unsafe.Pointer(&k[4])) 777 break 778 case 7: 779 b += uint32(k[6]) << 16 780 fallthrough 781 case 6: 782 b += uint32(k[5]) << 8 783 fallthrough 784 case 5: 785 b += uint32(k[4]) 786 fallthrough 787 case 4: 788 a += *(*uint32)(unsafe.Pointer(&k[0])) 789 break 790 case 3: 791 a += uint32(k[2]) << 16 792 fallthrough 793 case 2: 794 a += uint32(k[1]) << 8 795 fallthrough 796 case 1: 797 a += uint32(k[0]) 798 break 799 case 0: 800 //fmt.Printf("case 0\n") 801 return c, b /* zero length strings require no mixing */ 802 } 803 a, b, c = final1(a, b, c) 804 a, b, c = final2(a, b, c) 805 return c, b 806 } 807 808 func HashString(s string, pc, pb uint32) (rpc, rpb uint32) { 809 k := ([]byte)(s) 810 rpc, rpb = Jenkins364(k, len(k), pc, pb) 811 return 812 } 813 814 func HashBytesLength(k []byte, length int, seed uint32) uint32 { 815 if length > len(k) { 816 fmt.Printf("len(k)=%d, length=%d\n", len(k), length) 817 panic("HashBytesLength") 818 } 819 ret, _ := Jenkins364(k, length, seed, 0) 820 return ret 821 } 822 823 // 824 // Streaming interface and new interface 825 826 type State332 struct { 827 hash uint32 828 seed uint32 829 pc uint32 830 pb uint32 831 clen int 832 tail []byte 833 } 834 835 type State332c struct { 836 State332 837 } 838 839 type State332b struct { 840 State332 841 } 842 843 type State364 struct { 844 hash uint64 845 seed uint64 846 pc uint32 847 pb uint32 848 clen int 849 tail []byte 850 } 851 852 type State264 struct { 853 hash uint64 854 seed uint64 855 } 856 857 type State232 struct { 858 hash uint32 859 seed uint32 860 clen int 861 tail []byte 862 } 863 864 // const Size = 4 865 866 // Sum32 returns the 32 bit hash of data given the seed. 867 // This is code is what I started with before I added the hash.Hash and hash.Hash32 interfaces. 868 func Sum32(data []byte, seed uint32) uint32 { 869 rpc, _ := Jenkins364(data, len(data), seed, seed) 870 return rpc 871 } 872 873 // New returns a new hash.Hash32 interface that computes a 32 bit jenkins lookup3 hash. 874 func New(seed uint32) hash.Hash32 { 875 s := new(State332c) 876 s.seed = seed 877 s.Reset() 878 return s 879 } 880 881 // New returns a new nhash.HashF32 interface that computes a 32 bit jenkins lookup3 hash. 882 func New332c(seed uint32) nhash.HashF32 { 883 s := new(State332c) 884 s.seed = seed 885 s.Reset() 886 return s 887 } 888 889 /* 890 func New332b(seed uint32) nhash.HashF32 { 891 s := new(State332b) 892 s.seed = seed 893 s.Reset() 894 return s 895 } 896 */ 897 898 // Return the size of the resulting hash. 899 func (d *State332c) Size() int { return 4 } 900 901 // Return the blocksize of the hash which in this case is 1 byte. 902 func (d *State332c) BlockSize() int { return 1 } 903 904 // Return the maximum number of seed bypes required. In this case 2 x 32 905 func (d *State332c) NumSeedBytes() int { 906 return 8 907 } 908 909 // Return the number of bits the hash function outputs. 910 func (d *State332c) HashSizeInBits() int { 911 return 32 912 } 913 914 // Reset the hash state. 915 func (d *State332c) Reset() { 916 d.pc = d.seed 917 d.pb = d.seed 918 d.clen = 0 919 d.tail = nil 920 } 921 922 // Accept a byte stream p used for calculating the hash. For now this call is lazy and the actual hash calculations take place in Sum() and Sum32(). 923 func (d *State332c) Write(p []byte) (nn int, err error) { 924 l := len(p) 925 d.clen += l 926 d.tail = append(d.tail, p...) 927 return l, nil 928 } 929 930 // Return the current hash as a byte slice. 931 func (d *State332c) Sum(b []byte) []byte { 932 d.pc, d.pb = Jenkins364(d.tail, len(d.tail), d.pc, d.pb) 933 d.hash = d.pc 934 h := d.hash 935 return append(b, byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) 936 } 937 938 // Return the current hash as a 32 bit unsigned type. 939 func (d *State332c) Sum32() uint32 { 940 d.pc, d.pb = Jenkins364(d.tail, len(d.tail), d.pc, d.pb) 941 d.hash = d.pc 942 return d.hash 943 } 944 945 // Given b as input and an optional 32 bit seed return the Jenkins lookup3 hash c bits. 946 func (d *State332c) Hash32(b []byte, seeds ...uint32) uint32 { 947 //fmt.Printf("len(b)=%d, b=%x\n", len(b), b) 948 /* 949 switch len(seeds) { 950 case 2: 951 d.pb = seeds[1] 952 fallthrough 953 case 1: 954 d.pc = seeds[0] 955 default: 956 d.pc, d.pb = 0, 0 957 } 958 */ 959 d.pc, d.pb = 0, 0 960 961 d.pc, d.pb = Jenkins364(b, len(b), d.pc, d.pb) 962 d.hash = d.pc 963 return d.hash 964 } 965 966 // ---- 967 968 // changed this from HashF64 to Hash64 to get streaming functions, what did I break? 7-22-15 969 func New364(seed uint64) nhash.Hash64 { 970 s := new(State364) 971 s.seed = seed 972 s.Reset() 973 return s 974 } 975 976 // Return the size of the resulting hash. 977 func (d *State364) Size() int { return 8 } 978 979 // Return the blocksize of the hash which in this case is 1 byte. 980 func (d *State364) BlockSize() int { return 1 } 981 982 // Return the maximum number of seed bypes required. In this case 2 x 32 983 func (d *State364) NumSeedBytes() int { 984 return 8 985 } 986 987 // Return the number of bits the hash function outputs. 988 func (d *State364) HashSizeInBits() int { 989 return 64 990 } 991 992 // Reset the hash state. 993 func (d *State364) Reset() { 994 d.pc = uint32(d.seed) 995 d.pb = uint32(d.seed >> 32) 996 d.clen = 0 997 d.tail = nil 998 } 999 1000 // Accept a byte stream p used for calculating the hash. For now this call is lazy and the actual hash calculations take place in Sum() and Sum32(). 1001 func (d *State364) Write(p []byte) (nn int, err error) { 1002 l := len(p) 1003 d.clen += l 1004 d.tail = append(d.tail, p...) 1005 return l, nil 1006 } 1007 1008 // Return the current hash as a byte slice. 1009 func (d *State364) Sum(b []byte) []byte { 1010 d.pc, d.pb = Jenkins364(d.tail, len(d.tail), d.pc, d.pb) 1011 d.hash = uint64(d.pb<<32) | uint64(d.pc) 1012 h := d.hash 1013 return append(b, byte(h>>56), byte(h>>48), byte(h>>40), byte(h>>32), byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) 1014 } 1015 1016 func (d *State364) Write64(h uint64) (err error) { 1017 d.clen += 8 1018 d.tail = append(d.tail, byte(h>>56), byte(h>>48), byte(h>>40), byte(h>>32), byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) 1019 return nil 1020 } 1021 1022 // Return the current hash as a 64 bit unsigned type. 1023 func (d *State364) Sum64() uint64 { 1024 d.pc, d.pb = Jenkins364(d.tail, len(d.tail), d.pc, d.pb) 1025 d.hash = uint64(d.pb)<<32 | uint64(d.pc) 1026 return d.hash 1027 } 1028 1029 func (d *State364) Hash64(b []byte, seeds ...uint64) uint64 { 1030 switch len(seeds) { 1031 case 2: 1032 d.pc = uint32(seeds[0]) 1033 d.pb = uint32(seeds[1]) 1034 case 1: 1035 d.pc = uint32(seeds[0]) 1036 d.pb = uint32(seeds[0] >> 32) 1037 } 1038 d.pc, d.pb = Jenkins364(b, len(b), d.pc, d.pb) 1039 //fmt.Printf("pc=0x%08x, pb=0x%08x\n", d.pc, d.pb) 1040 1041 // pc is better mixed than pb so pc goes in the low order bits 1042 d.hash = uint64(d.pb)<<32 | uint64(d.pc) 1043 return d.hash 1044 } 1045 1046 func (d *State364) Hash64S(b []byte, seed uint64) uint64 { 1047 d.pc, d.pb = uint32(seed), uint32(seed>>32) 1048 d.pc, d.pb = Jenkins364(b, len(b), d.pc, d.pb) 1049 //fmt.Printf("pc=0x%08x, pb=0x%08x\n", d.pc, d.pb) 1050 1051 // pc is better mixed than pb so pc goes in the low order bits 1052 d.hash = uint64(d.pb)<<32 | uint64(d.pc) 1053 return d.hash 1054 } 1055 1056 // ---- 1057 1058 // New returns a new nhash.HashF32 interface that computes a 32 bit jenkins lookup3 hash. 1059 func New232(seed uint32) nhash.HashF32 { 1060 s := new(State232) 1061 s.seed = seed 1062 s.Reset() 1063 return s 1064 } 1065 1066 // Return the size of the resulting hash. 1067 func (s *State232) Size() int { return 4 } 1068 1069 // Return the blocksize of the hash which in this case is 12 bytes at a time. 1070 func (s *State232) BlockSize() int { return 12 } 1071 1072 // Return the maximum number of seed bypes required. 1073 func (s *State232) NumSeedBytes() int { 1074 return 4 1075 } 1076 1077 // Return the number of bits the hash function outputs. 1078 func (s *State232) HashSizeInBits() int { 1079 return 32 1080 } 1081 1082 // Reset the hash state. 1083 func (s *State232) Reset() { 1084 s.seed = 0 1085 s.clen = 0 1086 s.tail = nil 1087 } 1088 1089 // Accept a byte stream p used for calculating the hash. For now this call is lazy and the actual hash calculations take place in Sum() and Sum32(). 1090 func (s *State232) Write(p []byte) (nn int, err error) { 1091 l := len(p) 1092 s.clen += l 1093 s.tail = append(s.tail, p...) 1094 return l, nil 1095 } 1096 1097 // Return the current hash as a byte slice. 1098 func (s *State232) Sum(b []byte) []byte { 1099 s.hash = Hash232(s.tail, s.seed) 1100 h := s.hash 1101 return append(b, byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) 1102 } 1103 1104 // Return the current hash as a 64 bit unsigned type. 1105 func (s *State232) Sum32() uint32 { 1106 s.hash = Hash232(s.tail, s.seed) 1107 return s.hash 1108 } 1109 1110 func (s *State232) Hash32(b []byte, seeds ...uint32) uint32 { 1111 // fmt.Printf("Hash32: len(b)=%d, b=%x\n", len(b), b) 1112 if len(seeds) > 0 { 1113 s.seed = 0 1114 } 1115 s.hash = Hash232(b, s.seed) 1116 return s.hash 1117 } 1118 1119 /* 1120 var mix = func() { 1121 a -= c; a ^= c << 4 | c >> (32 - 4); c += b; 1122 b -= a; b ^= a << 6 | a >> (32 - 6); a += c; 1123 c -= b; c ^= b << 8 | b >> (32 - 8); b += a; 1124 a -= c; a ^= c << 16 | c >> (32 - 16); c += b; 1125 b -= a; b ^= a << 19 | a >> (32 - 19); a += c; 1126 c -= b; c ^= b << 4 | b >> (32 - 4); b += a; 1127 } 1128 1129 var final = func() { 1130 c ^= b; c -= b << 14 | b >> (32 - 14); 1131 a ^= c; a -= c << 11 | c >> (32 - 11); 1132 b ^= a; b -= a << 25 | a >> (32 - 25); 1133 c ^= b; c -= b << 16 | b >> (32 - 16); 1134 a ^= c; a -= c << 4 | c >> (32 - 4); 1135 b ^= a; b -= a << 14 | a >> (32 - 14); 1136 c ^= b; c -= b << 24 | b >> (32 - 24); 1137 } 1138 */