I wrote: > > * v8 with chunked interface: > latency average = 555.688 ms > > This starts to improve things for me. > > * v8 with chunked, and return lower 32 bits of full 64-bit hash: > latency average = 556.324 ms > > This is within the noise level. There doesn't seem to be much downside > of using a couple cycles for fasthash's 32-bit reduction. > > * revert back to master from Dec 4 and then cherry pick a86c61c9ee > (save last entry of SearchPathCache) > latency average = 545.747 ms > > So chunked incremental hashing gets within ~2% of that, which is nice. > It seems we should use that when removing strlen, when convenient. > > Updated next steps: > * Investigate whether/how to incorporate final length into the > calculation when we don't have the length up front. > * Add some desperately needed explanatory comments. > * Use this in some existing cases where it makes sense. > * Get back to GUC hash and dynahash.
For #1 here, I cloned SMHasher and was dismayed at the complete lack of documentation, but after some poking around, found how to run the tests, using the 32-bit hash to save time. It turns out that the input length is important. I've attached two files of results -- "nolen" means stop using the initial length to tweak the internal seed. As you can see, there are 8 failures. "pluslen" means I then incorporated the length within the finalizer. This *does* pass SMHasher, so that's good. (of course this way can't produce the same hash as when we know the length up front, but that's not important). The attached shows how that would work, further whacking around and testing with Jeff's prototype for the search path cache hash table. I'll work on code comments and get it polished.
--- Testing fasthash32 "fast-hash 32bit" with NO LENGTH [[[ Sanity Tests ]]] Verification value 0x6A202089 ....... FAIL! (Expected 0xe9481afc) Running sanity check 1 .......... PASS Running AppendedZeroesTest .......... PASS [[[ Keyset 'Sparse' Tests ]]] Keyset 'Sparse' - 16-bit keys with up to 9 bits set - 50643 keys Testing collisions ( 32-bit) - Expected 0.3, actual 0 (0.00x) Testing collisions (high 19-25 bits) - Worst is 20 bits: 1227/1203 (1.02x) Testing collisions (low 19-25 bits) - Worst is 24 bits: 81/76 (1.06x) Testing distribution - Worst bias is the 13-bit window at bit 31 - 0.436% Keyset 'Sparse' - 24-bit keys with up to 8 bits set - 1271626 keys Testing collisions ( 32-bit) - Expected 188.2, actual 182 (0.97x) Testing distribution - Worst bias is the 17-bit window at bit 11 - 0.089% Keyset 'Sparse' - 32-bit keys with up to 7 bits set - 4514873 keys Testing collisions ( 32-bit) - Expected 2372.2, actual 2286 (0.96x) Testing distribution - Worst bias is the 19-bit window at bit 23 - 0.044% Keyset 'Sparse' - 40-bit keys with up to 6 bits set - 4598479 keys Testing collisions ( 32-bit) - Expected 2460.8, actual 2426 (0.99x) (-34) Testing distribution - Worst bias is the 19-bit window at bit 25 - 0.041% Keyset 'Sparse' - 48-bit keys with up to 6 bits set - 14196869 keys Testing collisions ( 32-bit) - Expected 23437.8, actual 23601 (1.01x) (164) Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.020% Keyset 'Sparse' - 56-bit keys with up to 5 bits set - 4216423 keys Testing collisions ( 32-bit) - Expected 2069.0, actual 1958 (0.95x) Testing distribution - Worst bias is the 19-bit window at bit 2 - 0.040% Keyset 'Sparse' - 64-bit keys with up to 5 bits set - 8303633 keys Testing collisions ( 32-bit) - Expected 8021.7, actual 7994 (1.00x) (-27) Testing distribution - Worst bias is the 20-bit window at bit 30 - 0.040% Keyset 'Sparse' - 72-bit keys with up to 5 bits set - 15082603 keys Testing collisions ( 32-bit) - Expected 26451.8, actual 26503 (1.00x) (52) Testing distribution - Worst bias is the 20-bit window at bit 11 - 0.021% Keyset 'Sparse' - 96-bit keys with up to 4 bits set - 3469497 keys Testing collisions ( 32-bit) - Expected 1401.0, actual 1415 (1.01x) (15) Testing distribution - Worst bias is the 19-bit window at bit 12 - 0.058% Keyset 'Sparse' - 160-bit keys with up to 4 bits set - 26977161 keys Testing collisions ( 32-bit) - Expected 84546.1, actual 84165 (1.00x) (-381) Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.012% Keyset 'Sparse' - 256-bit keys with up to 3 bits set - 2796417 keys Testing collisions ( 32-bit) - Expected 910.2, actual 905 (0.99x) (-5) Testing distribution - Worst bias is the 18-bit window at bit 21 - 0.056% Keyset 'Sparse' - 512-bit keys with up to 3 bits set - 22370049 keys Testing collisions ( 32-bit) - Expected 58155.4, actual 57846 (0.99x) (-309) Testing distribution - Worst bias is the 20-bit window at bit 6 - 0.013% Keyset 'Sparse' - 1024-bit keys with up to 2 bits set - 524801 keys Testing collisions ( 32-bit) - Expected 32.1, actual 35 (1.09x) (3) Testing distribution - Worst bias is the 16-bit window at bit 13 - 0.118% Keyset 'Sparse' - 2048-bit keys with up to 2 bits set - 2098177 keys Testing collisions ( 32-bit) - Expected 512.4, actual 513 (1.00x) (1) Testing distribution - Worst bias is the 18-bit window at bit 20 - 0.086% [[[ Keyset 'Permutation' Tests ]]] Combination Lowbits Tests: Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys Testing collisions ( 32-bit) - Expected 668.6, actual 33953 (50.78x) (33285) !!!!! *********FAIL********* Combination Highbits Tests Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys Testing collisions ( 32-bit) - Expected 668.6, actual 33990 (50.84x) (33322) !!!!! *********FAIL********* Combination Hi-Lo Tests: Keyset 'Combination' - up to 6 blocks from a set of 15 - 12204240 keys Testing collisions ( 32-bit) - Expected 17322.9, actual 777895 (44.91x) (760573) !!!!! *********FAIL********* Combination 0x8000000 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 2799870 (342.00x) (2791684) !!!!! *********FAIL********* Combination 0x0000001 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 2799806 (342.00x) (2791620) !!!!! *********FAIL********* Combination 0x800000000000000 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8241 (1.01x) (55) Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.031% Combination 0x000000000000001 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8150 (1.00x) (-36) Testing distribution - Worst bias is the 20-bit window at bit 22 - 0.056% Combination 16-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8016 (0.98x) Testing distribution - Worst bias is the 20-bit window at bit 19 - 0.033% Combination 16-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8250 (1.01x) (64) Testing distribution - Worst bias is the 20-bit window at bit 17 - 0.029% Combination 32-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8066 (0.99x) (-120) Testing distribution - Worst bias is the 19-bit window at bit 12 - 0.022% Combination 32-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8265 (1.01x) (79) Testing distribution - Worst bias is the 20-bit window at bit 10 - 0.044% Combination 64-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8051 (0.98x) (-135) Testing distribution - Worst bias is the 20-bit window at bit 30 - 0.031% Combination 64-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8122 (0.99x) (-64) Testing distribution - Worst bias is the 20-bit window at bit 4 - 0.032% Combination 128-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8107 (0.99x) (-79) Testing distribution - Worst bias is the 20-bit window at bit 9 - 0.038% Combination 128-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8050 (0.98x) (-136) Testing distribution - Worst bias is the 20-bit window at bit 11 - 0.026% [[[ Keyset 'Cyclic' Tests ]]] Keyset 'Cyclic' - 8 cycles of 4 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 125 (1.07x) (9) Testing distribution - Worst bias is the 17-bit window at bit 2 - 0.141% Keyset 'Cyclic' - 8 cycles of 5 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 108 (0.93x) Testing distribution - Worst bias is the 17-bit window at bit 19 - 0.046% Keyset 'Cyclic' - 8 cycles of 6 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 121 (1.04x) (5) Testing distribution - Worst bias is the 17-bit window at bit 2 - 0.116% Keyset 'Cyclic' - 8 cycles of 7 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 104 (0.89x) Testing distribution - Worst bias is the 15-bit window at bit 26 - 0.068% Keyset 'Cyclic' - 8 cycles of 8 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 118 (1.01x) (2) Testing distribution - Worst bias is the 17-bit window at bit 9 - 0.140% Keyset 'Cyclic' - 8 cycles of 12 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 98 (0.84x) Testing distribution - Worst bias is the 17-bit window at bit 26 - 0.093% [[[ Keyset 'TwoBytes' Tests ]]] Keyset 'TwoBytes' - up-to-4-byte keys, 652545 total keys Testing collisions ( 32-bit) - Expected 49.6, actual 261390 (5273.28x) (261341) !!!!! Keyset 'TwoBytes' - up-to-8-byte keys, 5471025 total keys Testing collisions ( 32-bit) - Expected 3483.1, actual 3648670 (1047.54x) (3645187) !!!!! Keyset 'TwoBytes' - up-to-12-byte keys, 18616785 total keys Testing collisions ( 32-bit) - Expected 40289.5, actual 12503722 (310.35x) (12463433) !!!!! Keyset 'TwoBytes' - up-to-16-byte keys, 44251425 total keys Testing collisions ( 32-bit) - Expected 227182.3, actual 34632335 (152.44x) (34405153) !!!!! Keyset 'TwoBytes' - up-to-20-byte keys, 86536545 total keys Testing collisions ( 32-bit) - Expected 865959.1, actual 64602745 (74.60x) (63736786) !!!!! Keyset 'TwoBytes' - up-to-24-byte keys, 149633745 total keys Testing collisions ( 32-bit) - Expected 2576560.5, actual 122139184 (47.40x) (119562624) !!!!! *********FAIL********* [[[ Keyset 'Text' Tests ]]] Keyset 'Text' - keys of form "FooXXXXBar" - 14776336 keys Testing collisions ( 32-bit) - Expected 25389.0, actual 25539 (1.01x) (150) Testing distribution - Worst bias is the 20-bit window at bit 3 - 0.024% Keyset 'Text' - keys of form "FooBarXXXX" - 14776336 keys Testing collisions ( 32-bit) - Expected 25389.0, actual 25349 (1.00x) (-40) Testing distribution - Worst bias is the 20-bit window at bit 30 - 0.033% Keyset 'Text' - keys of form "XXXXFooBar" - 14776336 keys Testing collisions ( 32-bit) - Expected 25389.0, actual 25368 (1.00x) (-21) Testing distribution - Worst bias is the 20-bit window at bit 14 - 0.018% Keyset 'Words' - 4000000 random keys of len 6-16 from alnum charset Testing collisions ( 32-bit) - Expected 1862.1, actual 1859 (1.00x) (-3) Testing distribution - Worst bias is the 19-bit window at bit 30 - 0.065% Keyset 'Words' - 4000000 random keys of len 6-16 from password charset Testing collisions ( 32-bit) - Expected 1862.1, actual 1818 (0.98x) Testing distribution - Worst bias is the 18-bit window at bit 14 - 0.042% Keyset 'Words' - 479826 dict words Testing collisions ( 32-bit) - Expected 26.8, actual 34 (1.27x) (8) Testing distribution - Worst bias is the 16-bit window at bit 11 - 0.144% [[[ Keyset 'Zeroes' Tests ]]] Keyset 'Zeroes' - 204800 keys Testing collisions ( 32-bit) - Expected 4.9, actual 179199 (36700.72x) (179195) !!!!!! *********FAIL********* [[[ Keyset 'Seed' Tests ]]] Keyset 'Seed' - 5000000 keys Testing collisions ( 32-bit) - Expected 2909.3, actual 2886 (0.99x) (-23) Testing distribution - Worst bias is the 19-bit window at bit 0 - 0.044% [[[ Keyset 'PerlinNoise' Tests ]]] Testing 16777216 coordinates (L2) : Testing collisions ( 32-bit) - Expected 32725.4, actual 32812 (1.00x) (87) Testing AV variant, 128 count with 4 spacing, 4-12: Testing collisions ( 32-bit) - Expected 1116.2, actual 2064632 (1849.78x) (2063516) [[[ DiffDist 'Differential Distribution' Tests ]]] Testing bit 0 Testing collisions ( 32-bit) - Expected 511.9, actual 516 (1.01x) (5) Testing distribution - Worst bias is the 18-bit window at bit 28 - 0.060% Testing bit 1 Testing collisions ( 32-bit) - Expected 511.9, actual 543 (1.06x) (32) Testing distribution - Worst bias is the 18-bit window at bit 19 - 0.075% Testing bit 2 Testing collisions ( 32-bit) - Expected 511.9, actual 544 (1.06x) (33) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.053% Testing bit 3 Testing collisions ( 32-bit) - Expected 511.9, actual 487 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 26 - 0.064% Testing bit 4 Testing collisions ( 32-bit) - Expected 511.9, actual 517 (1.01x) (6) Testing distribution - Worst bias is the 17-bit window at bit 6 - 0.057% Testing bit 5 Testing collisions ( 32-bit) - Expected 511.9, actual 551 (1.08x) (40) Testing distribution - Worst bias is the 18-bit window at bit 21 - 0.058% Testing bit 6 Testing collisions ( 32-bit) - Expected 511.9, actual 531 (1.04x) (20) Testing distribution - Worst bias is the 18-bit window at bit 30 - 0.053% Testing bit 7 Testing collisions ( 32-bit) - Expected 511.9, actual 532 (1.04x) (21) Testing distribution - Worst bias is the 18-bit window at bit 1 - 0.055% Testing bit 8 Testing collisions ( 32-bit) - Expected 511.9, actual 530 (1.04x) (19) Testing distribution - Worst bias is the 18-bit window at bit 23 - 0.080% Testing bit 9 Testing collisions ( 32-bit) - Expected 511.9, actual 511 (1.00x) Testing distribution - Worst bias is the 18-bit window at bit 5 - 0.065% Testing bit 10 Testing collisions ( 32-bit) - Expected 511.9, actual 524 (1.02x) (13) Testing distribution - Worst bias is the 18-bit window at bit 6 - 0.061% Testing bit 11 Testing collisions ( 32-bit) - Expected 511.9, actual 498 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 20 - 0.071% Testing bit 12 Testing collisions ( 32-bit) - Expected 511.9, actual 504 (0.98x) (-7) Testing distribution - Worst bias is the 18-bit window at bit 19 - 0.110% Testing bit 13 Testing collisions ( 32-bit) - Expected 511.9, actual 513 (1.00x) (2) Testing distribution - Worst bias is the 17-bit window at bit 7 - 0.032% Testing bit 14 Testing collisions ( 32-bit) - Expected 511.9, actual 526 (1.03x) (15) Testing distribution - Worst bias is the 18-bit window at bit 20 - 0.050% Testing bit 15 Testing collisions ( 32-bit) - Expected 511.9, actual 502 (0.98x) (-9) Testing distribution - Worst bias is the 18-bit window at bit 23 - 0.053% Testing bit 16 Testing collisions ( 32-bit) - Expected 511.9, actual 493 (0.96x) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.071% Testing bit 17 Testing collisions ( 32-bit) - Expected 511.9, actual 506 (0.99x) (-5) Testing distribution - Worst bias is the 18-bit window at bit 5 - 0.066% Testing bit 18 Testing collisions ( 32-bit) - Expected 511.9, actual 504 (0.98x) (-7) Testing distribution - Worst bias is the 18-bit window at bit 0 - 0.090% Testing bit 19 Testing collisions ( 32-bit) - Expected 511.9, actual 499 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 26 - 0.076% Testing bit 20 Testing collisions ( 32-bit) - Expected 511.9, actual 534 (1.04x) (23) Testing distribution - Worst bias is the 18-bit window at bit 5 - 0.109% Testing bit 21 Testing collisions ( 32-bit) - Expected 511.9, actual 508 (0.99x) (-3) Testing distribution - Worst bias is the 18-bit window at bit 8 - 0.065% Testing bit 22 Testing collisions ( 32-bit) - Expected 511.9, actual 506 (0.99x) (-5) Testing distribution - Worst bias is the 16-bit window at bit 4 - 0.040% Testing bit 23 Testing collisions ( 32-bit) - Expected 511.9, actual 516 (1.01x) (5) Testing distribution - Worst bias is the 18-bit window at bit 22 - 0.096% Testing bit 24 Testing collisions ( 32-bit) - Expected 511.9, actual 496 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.066% Testing bit 25 Testing collisions ( 32-bit) - Expected 511.9, actual 514 (1.00x) (3) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.082% Testing bit 26 Testing collisions ( 32-bit) - Expected 511.9, actual 527 (1.03x) (16) Testing distribution - Worst bias is the 18-bit window at bit 15 - 0.067% Testing bit 27 Testing collisions ( 32-bit) - Expected 511.9, actual 500 (0.98x) Testing distribution - Worst bias is the 18-bit window at bit 3 - 0.042% Testing bit 28 Testing collisions ( 32-bit) - Expected 511.9, actual 565 (1.10x) (54) Testing distribution - Worst bias is the 18-bit window at bit 26 - 0.069% Testing bit 29 Testing collisions ( 32-bit) - Expected 511.9, actual 481 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.061% Testing bit 30 Testing collisions ( 32-bit) - Expected 511.9, actual 518 (1.01x) (7) Testing distribution - Worst bias is the 18-bit window at bit 1 - 0.063% Testing bit 31 Testing collisions ( 32-bit) - Expected 511.9, actual 511 (1.00x) Testing distribution - Worst bias is the 18-bit window at bit 22 - 0.084% Testing bit 32 Testing collisions ( 32-bit) - Expected 511.9, actual 519 (1.01x) (8) Testing distribution - Worst bias is the 18-bit window at bit 30 - 0.058% Testing bit 33 Testing collisions ( 32-bit) - Expected 511.9, actual 532 (1.04x) (21) Testing distribution - Worst bias is the 18-bit window at bit 30 - 0.058% Testing bit 34 Testing collisions ( 32-bit) - Expected 511.9, actual 502 (0.98x) (-9) Testing distribution - Worst bias is the 18-bit window at bit 0 - 0.077% Testing bit 35 Testing collisions ( 32-bit) - Expected 511.9, actual 479 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 29 - 0.063% Testing bit 36 Testing collisions ( 32-bit) - Expected 511.9, actual 548 (1.07x) (37) Testing distribution - Worst bias is the 18-bit window at bit 14 - 0.059% Testing bit 37 Testing collisions ( 32-bit) - Expected 511.9, actual 545 (1.06x) (34) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.100% Testing bit 38 Testing collisions ( 32-bit) - Expected 511.9, actual 532 (1.04x) (21) Testing distribution - Worst bias is the 18-bit window at bit 3 - 0.052% Testing bit 39 Testing collisions ( 32-bit) - Expected 511.9, actual 500 (0.98x) Testing distribution - Worst bias is the 18-bit window at bit 1 - 0.090% Testing bit 40 Testing collisions ( 32-bit) - Expected 511.9, actual 556 (1.09x) (45) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.074% Testing bit 41 Testing collisions ( 32-bit) - Expected 511.9, actual 542 (1.06x) (31) Testing distribution - Worst bias is the 18-bit window at bit 15 - 0.032% Testing bit 42 Testing collisions ( 32-bit) - Expected 511.9, actual 520 (1.02x) (9) Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.059% Testing bit 43 Testing collisions ( 32-bit) - Expected 511.9, actual 446 (0.87x) Testing distribution - Worst bias is the 18-bit window at bit 15 - 0.063% Testing bit 44 Testing collisions ( 32-bit) - Expected 511.9, actual 515 (1.01x) (4) Testing distribution - Worst bias is the 18-bit window at bit 31 - 0.063% Testing bit 45 Testing collisions ( 32-bit) - Expected 511.9, actual 487 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.065% Testing bit 46 Testing collisions ( 32-bit) - Expected 511.9, actual 529 (1.03x) (18) Testing distribution - Worst bias is the 18-bit window at bit 2 - 0.066% Testing bit 47 Testing collisions ( 32-bit) - Expected 511.9, actual 525 (1.03x) (14) Testing distribution - Worst bias is the 18-bit window at bit 0 - 0.084% Testing bit 48 Testing collisions ( 32-bit) - Expected 511.9, actual 534 (1.04x) (23) Testing distribution - Worst bias is the 18-bit window at bit 20 - 0.071% Testing bit 49 Testing collisions ( 32-bit) - Expected 511.9, actual 534 (1.04x) (23) Testing distribution - Worst bias is the 18-bit window at bit 27 - 0.073% Testing bit 50 Testing collisions ( 32-bit) - Expected 511.9, actual 550 (1.07x) (39) Testing distribution - Worst bias is the 18-bit window at bit 23 - 0.080% Testing bit 51 Testing collisions ( 32-bit) - Expected 511.9, actual 487 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 19 - 0.022% Testing bit 52 Testing collisions ( 32-bit) - Expected 511.9, actual 526 (1.03x) (15) Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.072% Testing bit 53 Testing collisions ( 32-bit) - Expected 511.9, actual 491 (0.96x) Testing distribution - Worst bias is the 18-bit window at bit 11 - 0.063% Testing bit 54 Testing collisions ( 32-bit) - Expected 511.9, actual 516 (1.01x) (5) Testing distribution - Worst bias is the 18-bit window at bit 12 - 0.053% Testing bit 55 Testing collisions ( 32-bit) - Expected 511.9, actual 496 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 28 - 0.037% Testing bit 56 Testing collisions ( 32-bit) - Expected 511.9, actual 488 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 27 - 0.054% Testing bit 57 Testing collisions ( 32-bit) - Expected 511.9, actual 477 (0.93x) Testing distribution - Worst bias is the 18-bit window at bit 24 - 0.062% Testing bit 58 Testing collisions ( 32-bit) - Expected 511.9, actual 517 (1.01x) (6) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.067% Testing bit 59 Testing collisions ( 32-bit) - Expected 511.9, actual 518 (1.01x) (7) Testing distribution - Worst bias is the 18-bit window at bit 10 - 0.057% Testing bit 60 Testing collisions ( 32-bit) - Expected 511.9, actual 467 (0.91x) Testing distribution - Worst bias is the 18-bit window at bit 14 - 0.056% Testing bit 61 Testing collisions ( 32-bit) - Expected 511.9, actual 507 (0.99x) (-4) Testing distribution - Worst bias is the 18-bit window at bit 31 - 0.058% Testing bit 62 Testing collisions ( 32-bit) - Expected 511.9, actual 495 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 26 - 0.078% Testing bit 63 Testing collisions ( 32-bit) - Expected 511.9, actual 505 (0.99x) (-6) Testing distribution - Worst bias is the 18-bit window at bit 8 - 0.046% Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001 Verification value is 0x00000001 - Testing took 264.327292 seconds [[[ Avalanche Tests ]]] Testing 24-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.576000% Testing 32-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.652667% Testing 40-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.716000% Testing 48-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.664667% Testing 56-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.634667% Testing 64-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.760667% Testing 72-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.696667% Testing 80-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.678000% Testing 96-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.784667% Testing 112-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.610000% Testing 128-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.603333% Testing 160-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.709333% Testing 512-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.768667% Testing 1024-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.751333% [[[ Diff 'Differential' Tests ]]] Testing 8303632 up-to-5-bit differentials in 64-bit keys -> 32 bit hashes. 1000 reps, 8303632000 total tests, expecting 1.93 random collisions.......... 0 total collisions, of which 0 single collisions were ignored Testing 11017632 up-to-4-bit differentials in 128-bit keys -> 32 bit hashes. 1000 reps, 11017632000 total tests, expecting 2.57 random collisions.......... 0 total collisions, of which 0 single collisions were ignored Testing 2796416 up-to-3-bit differentials in 256-bit keys -> 32 bit hashes. 1000 reps, 2796416000 total tests, expecting 0.65 random collisions.......... 0 total collisions, of which 0 single collisions were ignored [[[ MomentChi2 Tests ]]] Analyze hashes produced from a serie of linearly increasing numbers of 32-bit, using a step of 2 ... Target values to approximate : 1391290.000000 - 686.666667 4 threads starting... done Popcount 1 stats : 1391274.272774 - 687.214286 Popcount 0 stats : 1391326.086340 - 687.394241 MomentChi2 for bits 1 : 0.180034 MomentChi2 for bits 0 : 0.947719 Derivative stats (transition from 2 consecutive values) : Popcount 1 stats : 1391337.595605 - 687.344446 Popcount 0 stats : 1391285.423503 - 687.295030 MomentChi2 for deriv b1 : 1.64871 MomentChi2 for deriv b0 : 0.0152437 Great [[[ Prng Tests ]]] Skipping PRNG test; it is designed for hashes >= 64-bits [[[ BIC 'Bit Independence Criteria' Tests ]]] ........... Max bias 0.005424 - ( 1 : 13, 26) Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001 Verification value is 0x00000001 - Testing took 720.371917 seconds
--- Testing fasthash32 "fast-hash 32bit" with length in finalizer [[[ Sanity Tests ]]] Verification value 0x6A202089 ....... FAIL! (Expected 0xe9481afc) [JCN - won't give the same answer obviously] Running sanity check 1 .......... PASS Running AppendedZeroesTest .......... PASS [[[ Keyset 'Sparse' Tests ]]] Keyset 'Sparse' - 16-bit keys with up to 9 bits set - 50643 keys Testing collisions ( 32-bit) - Expected 0.3, actual 0 (0.00x) Testing collisions (high 19-25 bits) - Worst is 25 bits: 47/38 (1.23x) Testing collisions (low 19-25 bits) - Worst is 24 bits: 80/76 (1.05x) Testing distribution - Worst bias is the 13-bit window at bit 2 - 0.495% Keyset 'Sparse' - 24-bit keys with up to 8 bits set - 1271626 keys Testing collisions ( 32-bit) - Expected 188.2, actual 183 (0.97x) Testing distribution - Worst bias is the 17-bit window at bit 30 - 0.081% Keyset 'Sparse' - 32-bit keys with up to 7 bits set - 4514873 keys Testing collisions ( 32-bit) - Expected 2372.2, actual 2427 (1.02x) (55) Testing distribution - Worst bias is the 19-bit window at bit 28 - 0.047% Keyset 'Sparse' - 40-bit keys with up to 6 bits set - 4598479 keys Testing collisions ( 32-bit) - Expected 2460.8, actual 2569 (1.04x) (109) Testing distribution - Worst bias is the 19-bit window at bit 4 - 0.057% Keyset 'Sparse' - 48-bit keys with up to 6 bits set - 14196869 keys Testing collisions ( 32-bit) - Expected 23437.8, actual 23175 (0.99x) (-262) Testing distribution - Worst bias is the 20-bit window at bit 30 - 0.022% Keyset 'Sparse' - 56-bit keys with up to 5 bits set - 4216423 keys Testing collisions ( 32-bit) - Expected 2069.0, actual 2093 (1.01x) (25) Testing distribution - Worst bias is the 19-bit window at bit 11 - 0.049% Keyset 'Sparse' - 64-bit keys with up to 5 bits set - 8303633 keys Testing collisions ( 32-bit) - Expected 8021.7, actual 8008 (1.00x) (-13) Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.033% Keyset 'Sparse' - 72-bit keys with up to 5 bits set - 15082603 keys Testing collisions ( 32-bit) - Expected 26451.8, actual 26440 (1.00x) (-11) Testing distribution - Worst bias is the 20-bit window at bit 1 - 0.018% Keyset 'Sparse' - 96-bit keys with up to 4 bits set - 3469497 keys Testing collisions ( 32-bit) - Expected 1401.0, actual 1408 (1.01x) (8) Testing distribution - Worst bias is the 19-bit window at bit 26 - 0.055% Keyset 'Sparse' - 160-bit keys with up to 4 bits set - 26977161 keys Testing collisions ( 32-bit) - Expected 84546.1, actual 84196 (1.00x) (-350) Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.015% Keyset 'Sparse' - 256-bit keys with up to 3 bits set - 2796417 keys Testing collisions ( 32-bit) - Expected 910.2, actual 890 (0.98x) Testing distribution - Worst bias is the 19-bit window at bit 27 - 0.044% Keyset 'Sparse' - 512-bit keys with up to 3 bits set - 22370049 keys Testing collisions ( 32-bit) - Expected 58155.4, actual 57845 (0.99x) (-310) Testing distribution - Worst bias is the 20-bit window at bit 1 - 0.007% Keyset 'Sparse' - 1024-bit keys with up to 2 bits set - 524801 keys Testing collisions ( 32-bit) - Expected 32.1, actual 37 (1.15x) (5) Testing distribution - Worst bias is the 16-bit window at bit 21 - 0.125% Keyset 'Sparse' - 2048-bit keys with up to 2 bits set - 2098177 keys Testing collisions ( 32-bit) - Expected 512.4, actual 547 (1.07x) (35) Testing distribution - Worst bias is the 18-bit window at bit 14 - 0.063% [[[ Keyset 'Permutation' Tests ]]] Combination Lowbits Tests: Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys Testing collisions ( 32-bit) - Expected 668.6, actual 618 (0.92x) Testing distribution - Worst bias is the 18-bit window at bit 12 - 0.050% Combination Highbits Tests Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys Testing collisions ( 32-bit) - Expected 668.6, actual 691 (1.03x) (23) Testing distribution - Worst bias is the 18-bit window at bit 15 - 0.071% Combination Hi-Lo Tests: Keyset 'Combination' - up to 6 blocks from a set of 15 - 12204240 keys Testing collisions ( 32-bit) - Expected 17322.9, actual 17300 (1.00x) (-22) Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.034% Combination 0x8000000 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8259 (1.01x) (73) Testing distribution - Worst bias is the 20-bit window at bit 13 - 0.040% Combination 0x0000001 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8168 (1.00x) (-18) Testing distribution - Worst bias is the 20-bit window at bit 15 - 0.022% Combination 0x800000000000000 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8173 (1.00x) (-13) Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.027% Combination 0x000000000000001 Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8087 (0.99x) (-99) Testing distribution - Worst bias is the 20-bit window at bit 5 - 0.015% Combination 16-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8066 (0.99x) (-120) Testing distribution - Worst bias is the 20-bit window at bit 7 - 0.028% Combination 16-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8314 (1.02x) (128) Testing distribution - Worst bias is the 20-bit window at bit 21 - 0.030% Combination 32-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8304 (1.01x) (118) Testing distribution - Worst bias is the 20-bit window at bit 0 - 0.016% Combination 32-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8253 (1.01x) (67) Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.034% Combination 64-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8108 (0.99x) (-78) Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.035% Combination 64-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8216 (1.00x) (30) Testing distribution - Worst bias is the 20-bit window at bit 11 - 0.041% Combination 128-bytes [0-1] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8073 (0.99x) (-113) Testing distribution - Worst bias is the 20-bit window at bit 17 - 0.027% Combination 128-bytes [0-last] Tests: Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys Testing collisions ( 32-bit) - Expected 8186.7, actual 8048 (0.98x) (-138) Testing distribution - Worst bias is the 19-bit window at bit 5 - 0.026% [[[ Keyset 'Cyclic' Tests ]]] Keyset 'Cyclic' - 8 cycles of 4 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 108 (0.93x) Testing distribution - Worst bias is the 17-bit window at bit 16 - 0.124% Keyset 'Cyclic' - 8 cycles of 5 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 126 (1.08x) (10) Testing distribution - Worst bias is the 17-bit window at bit 19 - 0.092% Keyset 'Cyclic' - 8 cycles of 6 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 111 (0.95x) Testing distribution - Worst bias is the 17-bit window at bit 10 - 0.087% Keyset 'Cyclic' - 8 cycles of 7 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 117 (1.01x) (1) Testing distribution - Worst bias is the 17-bit window at bit 21 - 0.113% Keyset 'Cyclic' - 8 cycles of 8 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 134 (1.15x) (18) Testing distribution - Worst bias is the 16-bit window at bit 13 - 0.062% Keyset 'Cyclic' - 8 cycles of 12 bytes - 1000000 keys Testing collisions ( 32-bit) - Expected 116.4, actual 127 (1.09x) (11) Testing distribution - Worst bias is the 17-bit window at bit 25 - 0.091% [[[ Keyset 'TwoBytes' Tests ]]] Keyset 'TwoBytes' - up-to-4-byte keys, 652545 total keys Testing collisions ( 32-bit) - Expected 49.6, actual 50 (1.01x) (1) Testing distribution - Worst bias is the 16-bit window at bit 21 - 0.089% Keyset 'TwoBytes' - up-to-8-byte keys, 5471025 total keys Testing collisions ( 32-bit) - Expected 3483.1, actual 3457 (0.99x) (-26) Testing distribution - Worst bias is the 20-bit window at bit 9 - 0.094% Keyset 'TwoBytes' - up-to-12-byte keys, 18616785 total keys Testing collisions ( 32-bit) - Expected 40289.5, actual 40410 (1.00x) (121) Testing distribution - Worst bias is the 20-bit window at bit 29 - 0.017% Keyset 'TwoBytes' - up-to-16-byte keys, 44251425 total keys Testing collisions ( 32-bit) - Expected 227182.3, actual 227335 (1.00x) (153) Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.008% Keyset 'TwoBytes' - up-to-20-byte keys, 86536545 total keys Testing collisions ( 32-bit) - Expected 865959.1, actual 865658 (1.00x) (-301) Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.004% Keyset 'TwoBytes' - up-to-24-byte keys, 149633745 total keys Testing collisions ( 32-bit) - Expected 2576560.5, actual 2575915 (1.00x) (-645) Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.002% [[[ Keyset 'Text' Tests ]]] Keyset 'Text' - keys of form "FooXXXXBar" - 14776336 keys Testing collisions ( 32-bit) - Expected 25389.0, actual 25549 (1.01x) (160) Testing distribution - Worst bias is the 20-bit window at bit 15 - 0.024% Keyset 'Text' - keys of form "FooBarXXXX" - 14776336 keys Testing collisions ( 32-bit) - Expected 25389.0, actual 25290 (1.00x) (-99) Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.014% Keyset 'Text' - keys of form "XXXXFooBar" - 14776336 keys Testing collisions ( 32-bit) - Expected 25389.0, actual 25389 (1.00x) Testing distribution - Worst bias is the 20-bit window at bit 13 - 0.025% Keyset 'Words' - 4000000 random keys of len 6-16 from alnum charset Testing collisions ( 32-bit) - Expected 1862.1, actual 1905 (1.02x) (43) Testing distribution - Worst bias is the 19-bit window at bit 26 - 0.060% Keyset 'Words' - 4000000 random keys of len 6-16 from password charset Testing collisions ( 32-bit) - Expected 1862.1, actual 1899 (1.02x) (37) Testing distribution - Worst bias is the 19-bit window at bit 23 - 0.029% Keyset 'Words' - 479826 dict words Testing collisions ( 32-bit) - Expected 26.8, actual 19 (0.71x) Testing distribution - Worst bias is the 15-bit window at bit 3 - 0.141% [[[ Keyset 'Zeroes' Tests ]]] Keyset 'Zeroes' - 204800 keys Testing collisions ( 32-bit) - Expected 4.9, actual 5 (1.02x) (1) Testing collisions (high 21-29 bits) - Worst is 26 bits: 329/312 (1.05x) Testing collisions (low 21-29 bits) - Worst is 26 bits: 310/312 (0.99x) Testing distribution - Worst bias is the 15-bit window at bit 26 - 0.177% [[[ Keyset 'Seed' Tests ]]] Keyset 'Seed' - 5000000 keys Testing collisions ( 32-bit) - Expected 2909.3, actual 3028 (1.04x) (119) Testing distribution - Worst bias is the 19-bit window at bit 17 - 0.050% [[[ Keyset 'PerlinNoise' Tests ]]] Testing 16777216 coordinates (L2) : Testing collisions ( 32-bit) - Expected 32725.4, actual 32761 (1.00x) (36) Testing AV variant, 128 count with 4 spacing, 4-12: Testing collisions ( 32-bit) - Expected 1116.2, actual 1079 (0.97x) [[[ DiffDist 'Differential Distribution' Tests ]]] Testing bit 0 Testing collisions ( 32-bit) - Expected 511.9, actual 517 (1.01x) (6) Testing distribution - Worst bias is the 18-bit window at bit 7 - 0.073% Testing bit 1 Testing collisions ( 32-bit) - Expected 511.9, actual 497 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.064% Testing bit 2 Testing collisions ( 32-bit) - Expected 511.9, actual 482 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.069% Testing bit 3 Testing collisions ( 32-bit) - Expected 511.9, actual 484 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 11 - 0.055% Testing bit 4 Testing collisions ( 32-bit) - Expected 511.9, actual 497 (0.97x) Testing distribution - Worst bias is the 17-bit window at bit 2 - 0.052% Testing bit 5 Testing collisions ( 32-bit) - Expected 511.9, actual 516 (1.01x) (5) Testing distribution - Worst bias is the 17-bit window at bit 4 - 0.045% Testing bit 6 Testing collisions ( 32-bit) - Expected 511.9, actual 496 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 13 - 0.096% Testing bit 7 Testing collisions ( 32-bit) - Expected 511.9, actual 527 (1.03x) (16) Testing distribution - Worst bias is the 18-bit window at bit 14 - 0.088% Testing bit 8 Testing collisions ( 32-bit) - Expected 511.9, actual 514 (1.00x) (3) Testing distribution - Worst bias is the 18-bit window at bit 12 - 0.046% Testing bit 9 Testing collisions ( 32-bit) - Expected 511.9, actual 482 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 31 - 0.063% Testing bit 10 Testing collisions ( 32-bit) - Expected 511.9, actual 495 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.043% Testing bit 11 Testing collisions ( 32-bit) - Expected 511.9, actual 524 (1.02x) (13) Testing distribution - Worst bias is the 18-bit window at bit 21 - 0.041% Testing bit 12 Testing collisions ( 32-bit) - Expected 511.9, actual 505 (0.99x) (-6) Testing distribution - Worst bias is the 17-bit window at bit 8 - 0.067% Testing bit 13 Testing collisions ( 32-bit) - Expected 511.9, actual 554 (1.08x) (43) Testing distribution - Worst bias is the 18-bit window at bit 12 - 0.037% Testing bit 14 Testing collisions ( 32-bit) - Expected 511.9, actual 502 (0.98x) (-9) Testing distribution - Worst bias is the 18-bit window at bit 19 - 0.104% Testing bit 15 Testing collisions ( 32-bit) - Expected 511.9, actual 505 (0.99x) (-6) Testing distribution - Worst bias is the 18-bit window at bit 24 - 0.065% Testing bit 16 Testing collisions ( 32-bit) - Expected 511.9, actual 526 (1.03x) (15) Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.088% Testing bit 17 Testing collisions ( 32-bit) - Expected 511.9, actual 482 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 19 - 0.082% Testing bit 18 Testing collisions ( 32-bit) - Expected 511.9, actual 556 (1.09x) (45) Testing distribution - Worst bias is the 17-bit window at bit 1 - 0.067% Testing bit 19 Testing collisions ( 32-bit) - Expected 511.9, actual 507 (0.99x) (-4) Testing distribution - Worst bias is the 18-bit window at bit 26 - 0.073% Testing bit 20 Testing collisions ( 32-bit) - Expected 511.9, actual 506 (0.99x) (-5) Testing distribution - Worst bias is the 18-bit window at bit 11 - 0.068% Testing bit 21 Testing collisions ( 32-bit) - Expected 511.9, actual 513 (1.00x) (2) Testing distribution - Worst bias is the 18-bit window at bit 13 - 0.049% Testing bit 22 Testing collisions ( 32-bit) - Expected 511.9, actual 518 (1.01x) (7) Testing distribution - Worst bias is the 18-bit window at bit 26 - 0.057% Testing bit 23 Testing collisions ( 32-bit) - Expected 511.9, actual 520 (1.02x) (9) Testing distribution - Worst bias is the 18-bit window at bit 29 - 0.069% Testing bit 24 Testing collisions ( 32-bit) - Expected 511.9, actual 488 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 18 - 0.086% Testing bit 25 Testing collisions ( 32-bit) - Expected 511.9, actual 575 (1.12x) (64) Testing distribution - Worst bias is the 18-bit window at bit 28 - 0.087% Testing bit 26 Testing collisions ( 32-bit) - Expected 511.9, actual 525 (1.03x) (14) Testing distribution - Worst bias is the 18-bit window at bit 24 - 0.070% Testing bit 27 Testing collisions ( 32-bit) - Expected 511.9, actual 481 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 20 - 0.068% Testing bit 28 Testing collisions ( 32-bit) - Expected 511.9, actual 496 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 17 - 0.084% Testing bit 29 Testing collisions ( 32-bit) - Expected 511.9, actual 509 (0.99x) (-2) Testing distribution - Worst bias is the 18-bit window at bit 30 - 0.073% Testing bit 30 Testing collisions ( 32-bit) - Expected 511.9, actual 509 (0.99x) (-2) Testing distribution - Worst bias is the 18-bit window at bit 28 - 0.051% Testing bit 31 Testing collisions ( 32-bit) - Expected 511.9, actual 516 (1.01x) (5) Testing distribution - Worst bias is the 17-bit window at bit 25 - 0.064% Testing bit 32 Testing collisions ( 32-bit) - Expected 511.9, actual 499 (0.97x) Testing distribution - Worst bias is the 17-bit window at bit 12 - 0.055% Testing bit 33 Testing collisions ( 32-bit) - Expected 511.9, actual 500 (0.98x) Testing distribution - Worst bias is the 18-bit window at bit 12 - 0.118% Testing bit 34 Testing collisions ( 32-bit) - Expected 511.9, actual 506 (0.99x) (-5) Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.050% Testing bit 35 Testing collisions ( 32-bit) - Expected 511.9, actual 489 (0.96x) Testing distribution - Worst bias is the 18-bit window at bit 1 - 0.084% Testing bit 36 Testing collisions ( 32-bit) - Expected 511.9, actual 532 (1.04x) (21) Testing distribution - Worst bias is the 18-bit window at bit 11 - 0.072% Testing bit 37 Testing collisions ( 32-bit) - Expected 511.9, actual 532 (1.04x) (21) Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.064% Testing bit 38 Testing collisions ( 32-bit) - Expected 511.9, actual 506 (0.99x) (-5) Testing distribution - Worst bias is the 18-bit window at bit 2 - 0.071% Testing bit 39 Testing collisions ( 32-bit) - Expected 511.9, actual 530 (1.04x) (19) Testing distribution - Worst bias is the 18-bit window at bit 23 - 0.053% Testing bit 40 Testing collisions ( 32-bit) - Expected 511.9, actual 511 (1.00x) Testing distribution - Worst bias is the 18-bit window at bit 13 - 0.060% Testing bit 41 Testing collisions ( 32-bit) - Expected 511.9, actual 539 (1.05x) (28) Testing distribution - Worst bias is the 18-bit window at bit 29 - 0.083% Testing bit 42 Testing collisions ( 32-bit) - Expected 511.9, actual 510 (1.00x) (-1) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.063% Testing bit 43 Testing collisions ( 32-bit) - Expected 511.9, actual 519 (1.01x) (8) Testing distribution - Worst bias is the 18-bit window at bit 13 - 0.079% Testing bit 44 Testing collisions ( 32-bit) - Expected 511.9, actual 523 (1.02x) (12) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.084% Testing bit 45 Testing collisions ( 32-bit) - Expected 511.9, actual 542 (1.06x) (31) Testing distribution - Worst bias is the 18-bit window at bit 31 - 0.076% Testing bit 46 Testing collisions ( 32-bit) - Expected 511.9, actual 543 (1.06x) (32) Testing distribution - Worst bias is the 18-bit window at bit 20 - 0.088% Testing bit 47 Testing collisions ( 32-bit) - Expected 511.9, actual 547 (1.07x) (36) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.105% Testing bit 48 Testing collisions ( 32-bit) - Expected 511.9, actual 512 (1.00x) (1) Testing distribution - Worst bias is the 18-bit window at bit 8 - 0.068% Testing bit 49 Testing collisions ( 32-bit) - Expected 511.9, actual 505 (0.99x) (-6) Testing distribution - Worst bias is the 18-bit window at bit 3 - 0.076% Testing bit 50 Testing collisions ( 32-bit) - Expected 511.9, actual 496 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 0 - 0.071% Testing bit 51 Testing collisions ( 32-bit) - Expected 511.9, actual 487 (0.95x) Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.083% Testing bit 52 Testing collisions ( 32-bit) - Expected 511.9, actual 514 (1.00x) (3) Testing distribution - Worst bias is the 18-bit window at bit 16 - 0.055% Testing bit 53 Testing collisions ( 32-bit) - Expected 511.9, actual 492 (0.96x) Testing distribution - Worst bias is the 18-bit window at bit 18 - 0.049% Testing bit 54 Testing collisions ( 32-bit) - Expected 511.9, actual 494 (0.97x) Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.076% Testing bit 55 Testing collisions ( 32-bit) - Expected 511.9, actual 503 (0.98x) (-8) Testing distribution - Worst bias is the 17-bit window at bit 30 - 0.044% Testing bit 56 Testing collisions ( 32-bit) - Expected 511.9, actual 491 (0.96x) Testing distribution - Worst bias is the 18-bit window at bit 13 - 0.051% Testing bit 57 Testing collisions ( 32-bit) - Expected 511.9, actual 502 (0.98x) (-9) Testing distribution - Worst bias is the 18-bit window at bit 1 - 0.098% Testing bit 58 Testing collisions ( 32-bit) - Expected 511.9, actual 524 (1.02x) (13) Testing distribution - Worst bias is the 18-bit window at bit 18 - 0.064% Testing bit 59 Testing collisions ( 32-bit) - Expected 511.9, actual 519 (1.01x) (8) Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.068% Testing bit 60 Testing collisions ( 32-bit) - Expected 511.9, actual 541 (1.06x) (30) Testing distribution - Worst bias is the 18-bit window at bit 13 - 0.034% Testing bit 61 Testing collisions ( 32-bit) - Expected 511.9, actual 472 (0.92x) Testing distribution - Worst bias is the 18-bit window at bit 10 - 0.065% Testing bit 62 Testing collisions ( 32-bit) - Expected 511.9, actual 507 (0.99x) (-4) Testing distribution - Worst bias is the 18-bit window at bit 1 - 0.069% Testing bit 63 Testing collisions ( 32-bit) - Expected 511.9, actual 482 (0.94x) Testing distribution - Worst bias is the 18-bit window at bit 22 - 0.077% Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001 Verification value is 0x00000001 - Testing took 350.971248 seconds [[[ Avalanche Tests ]]] Testing 24-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.576000% Testing 32-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.652667% Testing 40-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.716000% Testing 48-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.664667% Testing 56-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.634667% Testing 64-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.760667% Testing 72-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.696667% Testing 80-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.678000% Testing 96-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.784667% Testing 112-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.610000% Testing 128-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.603333% Testing 160-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.709333% Testing 512-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.768667% Testing 1024-bit keys -> 32-bit hashes, 300000 reps.......... worst bias is 0.751333% [[[ Diff 'Differential' Tests ]]] Testing 8303632 up-to-5-bit differentials in 64-bit keys -> 32 bit hashes. 1000 reps, 8303632000 total tests, expecting 1.93 random collisions.......... 0 total collisions, of which 0 single collisions were ignored Testing 11017632 up-to-4-bit differentials in 128-bit keys -> 32 bit hashes. 1000 reps, 11017632000 total tests, expecting 2.57 random collisions.......... 0 total collisions, of which 0 single collisions were ignored Testing 2796416 up-to-3-bit differentials in 256-bit keys -> 32 bit hashes. 1000 reps, 2796416000 total tests, expecting 0.65 random collisions.......... 0 total collisions, of which 0 single collisions were ignored [[[ MomentChi2 Tests ]]] Analyze hashes produced from a serie of linearly increasing numbers of 32-bit, using a step of 2 ... Target values to approximate : 1391290.000000 - 686.666667 4 threads starting... done Popcount 1 stats : 1391274.272774 - 687.214286 Popcount 0 stats : 1391326.086340 - 687.394241 MomentChi2 for bits 1 : 0.180034 MomentChi2 for bits 0 : 0.947719 Derivative stats (transition from 2 consecutive values) : Popcount 1 stats : 1391337.595605 - 687.344446 Popcount 0 stats : 1391285.423503 - 687.295030 MomentChi2 for deriv b1 : 1.64871 MomentChi2 for deriv b0 : 0.0152437 Great [[[ Prng Tests ]]] Skipping PRNG test; it is designed for hashes >= 64-bits [[[ BIC 'Bit Independence Criteria' Tests ]]] ........... Max bias 0.005424 - ( 1 : 13, 26) Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001 Verification value is 0x00000001 - Testing took 718.518900 seconds
From eacb3fccb25c10696334def8a8346257958ec3dd Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Sun, 10 Dec 2023 15:14:24 +0700 Subject: [PATCH v9 4/6] Assert that incremental fasthash variants give the same answer as the original Test that incremental hashing gives the right answer for strings. Use the initial length only for the init step. Test that we can ignore the length afterwards, and only use the presence of the NUL terminator to stop iterating. Assert that this results in the same hash. Based on "Use new hash APIs for search path cache" by Jeff Davis, rebased over v7. --- src/backend/catalog/namespace.c | 48 ++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 5027efc91d..6bb28aecfc 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -41,7 +41,7 @@ #include "catalog/pg_ts_template.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" -#include "common/hashfn.h" +#include "common/hashfn_unstable.h" #include "funcapi.h" #include "mb/pg_wchar.h" #include "miscadmin.h" @@ -247,11 +247,51 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, static inline uint32 spcachekey_hash(SearchPathCacheKey key) { - const unsigned char *bytes = (const unsigned char *) key.searchPath; + const char *buf = key.searchPath; + fasthash_state hs; + + // XXX not for commit +#ifdef USE_ASSERT_CHECKING int blen = strlen(key.searchPath); - return hash_combine(hash_bytes(bytes, blen), - hash_uint32(key.roleid)); + uint64 h_orig = fasthash64_orig(buf, blen, key.roleid); + + // check full function that calls incremental interface + Assert(fasthash64((const unsigned char *) buf, blen, key.roleid) == h_orig); + + // Test that chunked interface can give the same answer, + // if we have length up front. We would typically use it + // for cases where we don't know, but let's try to make + // it as similar as conveniently possible. + fasthash_init(&hs, blen, key.roleid); + while (*buf) + { + int chunk_len = 0; + + while(chunk_len < FH_SIZEOF_ACCUM && buf[chunk_len] != '\0') + chunk_len++; + + fasthash_accum(&hs, (const unsigned char *) buf, chunk_len); + buf += chunk_len; + } + Assert(fasthash_final64(&hs) == h_orig); + buf = key.searchPath; /* reset */ +#endif + + // WIP: maybe roleid should be mixed in normally + // WIP: For now fake the length to preserve the internal seed + fasthash_init(&hs, 1, key.roleid); + while (*buf) + { + int chunk_len = 0; + + while(chunk_len < FH_SIZEOF_ACCUM && buf[chunk_len] != '\0') + chunk_len++; + + fasthash_accum(&hs, (const unsigned char *) buf, chunk_len); + buf += chunk_len; + } + return fasthash_final32(&hs); } static inline bool -- 2.43.0
From 3d77e7effda9360315ab4af330839eb82ed97925 Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Thu, 14 Dec 2023 19:41:17 +0700 Subject: [PATCH v9 6/6] Add optional tweak to finalizer For hashing strings, we need to incorporate the length of the input into the final hash when we call the finalizer. This is necessary to pass SMHasher. To reduce the number of places that need to know about this, it seemed best to make the finalizer a void function, and to make the 32-bit reducer able to accept any uint64 input. --- src/backend/catalog/namespace.c | 11 +++++++++-- src/include/common/hashfn_unstable.h | 21 ++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 6bb28aecfc..3a3cb8ef70 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -247,6 +247,7 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, static inline uint32 spcachekey_hash(SearchPathCacheKey key) { + const char * const start = key.searchPath; const char *buf = key.searchPath; fasthash_state hs; @@ -274,7 +275,10 @@ spcachekey_hash(SearchPathCacheKey key) fasthash_accum(&hs, (const unsigned char *) buf, chunk_len); buf += chunk_len; } - Assert(fasthash_final64(&hs) == h_orig); + + // We passed the length to fasthash_init, so no tweak for assert testing + fasthash_final64(&hs, 0); + Assert(hs.hash == h_orig); buf = key.searchPath; /* reset */ #endif @@ -291,7 +295,10 @@ spcachekey_hash(SearchPathCacheKey key) fasthash_accum(&hs, (const unsigned char *) buf, chunk_len); buf += chunk_len; } - return fasthash_final32(&hs); + + /* pass the length to tweak the final mix */ + fasthash_final64(&hs, buf - start); + return fasthash_reduce32(hs.hash); } static inline bool diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h index e8ca39fed2..578a4d0a83 100644 --- a/src/include/common/hashfn_unstable.h +++ b/src/include/common/hashfn_unstable.h @@ -53,9 +53,9 @@ typedef struct fasthash_state } fasthash_state; static inline uint64 -fasthash_mix(uint64 h) +fasthash_mix(uint64 h, uint64 tweak) { - h ^= h >> 23; + h ^= (h >> 23) + tweak; h *= 0x2127599bf4325c37; h ^= h >> 47; return h; @@ -64,7 +64,7 @@ fasthash_mix(uint64 h) static inline void fasthash_combine(fasthash_state* hs) { - hs->hash ^= fasthash_mix(hs->accum); + hs->hash ^= fasthash_mix(hs->accum, 0); hs->hash *= 0x880355f21e6d1965; /* reset hash state for next input */ @@ -114,19 +114,18 @@ fasthash_accum(fasthash_state *hs, const unsigned char *k, int len) } -static inline uint64 -fasthash_final64(fasthash_state *hs) +static inline void +fasthash_final64(fasthash_state *hs, uint64 tweak) { - return fasthash_mix(hs->hash); + hs->hash = fasthash_mix(hs->hash, tweak); } static inline uint32 -fasthash_final32(fasthash_state *hs) +fasthash_reduce32(uint64 h) { // the following trick converts the 64-bit hashcode to Fermat // residue, which shall retain information from both the higher // and lower parts of hashcode. - uint64 h = fasthash_final64(hs); return h - (h >> 32); } @@ -145,14 +144,14 @@ fasthash64(const unsigned char * k, int len, uint64 seed) } fasthash_accum(&hs, k, len); - return fasthash_final64(&hs); + fasthash_final64(&hs, 0); + return hs.hash; } static inline uint64 fasthash32(const unsigned char * k, int len, uint64 seed) { - uint64 h = fasthash64(k, len, seed); - return h - (h >> 32); + return fasthash_reduce32(fasthash64(k, len, seed)); } -- 2.43.0
From 4e1c6836894c5bed8315ac52c6f0c1ff5439076a Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Sun, 10 Dec 2023 12:11:37 +0700 Subject: [PATCH v9 2/6] Rewrite fasthash functions using a homegrown incremental interface The incremental interface will be useful for cases we don't know the length up front, such as NUL-terminated strings. First, we need to validate that this interface can give the same answer as the original functions when we do know the length. A future commit will add a temporary assert for testing in CI. --- src/include/common/hashfn_unstable.h | 161 +++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 8 deletions(-) diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h index a5bf965fa2..fbae7a5522 100644 --- a/src/include/common/hashfn_unstable.h +++ b/src/include/common/hashfn_unstable.h @@ -1,3 +1,25 @@ +/* +Building blocks for creating fast inlineable hash functions. The +unstable designation is in contrast to hashfn.h, which cannot break +compatibility because hashes can be writen to disk and so must have +the same hashes between versions. + + * + * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group + * + * src/include/common/hashfn_unstable.c + */ + +#ifndef HASHFN_UNSTABLE_H +#define HASHFN_UNSTABLE_H + +/* + * fasthash is a modification of code taken from + * https://code.google.com/archive/p/fast-hash/source/default/source + * under the terms of the MIT licencse. The original copyright + * notice follows: + */ + /* The MIT License Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) @@ -23,16 +45,130 @@ SOFTWARE. */ -#include "fasthash.h" +typedef struct fasthash_state +{ + uint64 accum; +#define FH_SIZEOF_ACCUM sizeof(uint64) + uint64 hash; +} fasthash_state; + +static inline uint64 +fasthash_mix(uint64 h) +{ + h ^= h >> 23; + h *= 0x2127599bf4325c37ULL; + h ^= h >> 47; + return h; +} + +static inline void +fasthash_combine(fasthash_state* hs) +{ + hs->hash ^= fasthash_mix(hs->accum); + hs->hash *= 0x880355f21e6d1965ULL; + + /* reset hash state for next input */ + hs->accum = 0; +} + +static inline void +fasthash_init(fasthash_state *hs, int len, uint64 seed) +{ + memset(hs, 0, sizeof(fasthash_state)); + + // since we don't know the length for a nul-terminated string + // handle some other way -- maybe we can accum the length in + // the state and fold it in during the finalizer (cf. xxHash3) + hs->hash = seed ^ (len * 0x880355f21e6d1965ULL); +} + +static inline void +fasthash_accum(fasthash_state *hs, const unsigned char *k, int len) +{ + Assert(hs->accum == 0); + Assert(len <= FH_SIZEOF_ACCUM); + + switch (len) + { + case 8: memcpy(&hs->accum, k, 8); + break; + case 7: hs->accum |= (uint64) k[6] << 48; + /* FALLTHROUGH */ + case 6: hs->accum |= (uint64) k[5] << 40; + /* FALLTHROUGH */ + case 5: hs->accum |= (uint64) k[4] << 32; + /* FALLTHROUGH */ + case 4: hs->accum |= (uint64) k[3] << 24; + /* FALLTHROUGH */ + case 3: hs->accum |= (uint64) k[2] << 16; + /* FALLTHROUGH */ + case 2: hs->accum |= (uint64) k[1] << 8; + /* FALLTHROUGH */ + case 1: hs->accum |= (uint64) k[0]; + break; + case 0: + return; + } + + fasthash_combine(hs); +} + + +static inline uint64 +fasthash_final64(fasthash_state *hs) +{ + return fasthash_mix(hs->hash); +} + +static inline uint32 +fasthash_final32(fasthash_state *hs) +{ + // the following trick converts the 64-bit hashcode to Fermat + // residue, which shall retain information from both the higher + // and lower parts of hashcode. + uint64 h = fasthash_final64(hs); + return h - (h >> 32); +} + +static inline uint64 +fasthash64(const unsigned char * k, int len, uint64 seed) +{ + fasthash_state hs; + + fasthash_init(&hs, len, seed); + + while (len >= FH_SIZEOF_ACCUM) + { + fasthash_accum(&hs, k, FH_SIZEOF_ACCUM); + k += FH_SIZEOF_ACCUM; + len -= FH_SIZEOF_ACCUM; + } + + fasthash_accum(&hs, k, len); + return fasthash_final64(&hs); +} + +static inline uint64 +fasthash32(const unsigned char * k, int len, uint64 seed) +{ + uint64 h = fasthash64(k, len, seed); + return h - (h >> 32); +} + + +// XXX NOT FOR COMMIT // Compression function for Merkle-Damgard construction. // This function is generated using the framework provided. -#define mix(h) ({ \ - (h) ^= (h) >> 23; \ - (h) *= 0x2127599bf4325c37ULL; \ - (h) ^= (h) >> 47; }) +static inline uint64_t mix(uint64_t h) { + h ^= h >> 23; + h *= 0x2127599bf4325c37ULL; + h ^= h >> 47; + return h; +} -uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) +static inline +uint64_t fasthash64_orig(const void *buf, size_t len, uint64_t seed) { const uint64_t m = 0x880355f21e6d1965ULL; const uint64_t *pos = (const uint64_t *)buf; @@ -52,11 +188,17 @@ uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) switch (len & 7) { case 7: v ^= (uint64_t)pos2[6] << 48; + /* FALLTHROUGH */ case 6: v ^= (uint64_t)pos2[5] << 40; + /* FALLTHROUGH */ case 5: v ^= (uint64_t)pos2[4] << 32; + /* FALLTHROUGH */ case 4: v ^= (uint64_t)pos2[3] << 24; + /* FALLTHROUGH */ case 3: v ^= (uint64_t)pos2[2] << 16; + /* FALLTHROUGH */ case 2: v ^= (uint64_t)pos2[1] << 8; + /* FALLTHROUGH */ case 1: v ^= (uint64_t)pos2[0]; h ^= mix(v); h *= m; @@ -65,11 +207,14 @@ uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) return mix(h); } -uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) +static inline +uint32_t fasthash32_orig(const void *buf, size_t len, uint32_t seed) { // the following trick converts the 64-bit hashcode to Fermat // residue, which shall retain information from both the higher // and lower parts of hashcode. - uint64_t h = fasthash64(buf, len, seed); + uint64_t h = fasthash64_orig(buf, len, seed); return h - (h >> 32); } + +#endif /* HASHFN_UNSTABLE_H */ -- 2.43.0
From 4f875eb84567ccaa31cfc4e01ccd61acb43f9a58 Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Sun, 10 Dec 2023 21:27:13 +0700 Subject: [PATCH v9 3/6] Fix alignment issue in the original fastash Found by UBSan in CI --- src/include/common/hashfn_unstable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h index fbae7a5522..a167681c86 100644 --- a/src/include/common/hashfn_unstable.h +++ b/src/include/common/hashfn_unstable.h @@ -178,9 +178,10 @@ uint64_t fasthash64_orig(const void *buf, size_t len, uint64_t seed) uint64_t v; while (pos != end) { - v = *pos++; + memcpy(&v, pos, 8); h ^= mix(v); h *= m; + pos++; } pos2 = (const unsigned char*)pos; -- 2.43.0
From 63b25e788c81bc47342f28e1e3e489fae8c61d26 Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Thu, 14 Dec 2023 19:03:12 +0700 Subject: [PATCH v9 5/6] Remove ULL --- src/include/common/hashfn_unstable.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h index a167681c86..e8ca39fed2 100644 --- a/src/include/common/hashfn_unstable.h +++ b/src/include/common/hashfn_unstable.h @@ -56,7 +56,7 @@ static inline uint64 fasthash_mix(uint64 h) { h ^= h >> 23; - h *= 0x2127599bf4325c37ULL; + h *= 0x2127599bf4325c37; h ^= h >> 47; return h; } @@ -65,7 +65,7 @@ static inline void fasthash_combine(fasthash_state* hs) { hs->hash ^= fasthash_mix(hs->accum); - hs->hash *= 0x880355f21e6d1965ULL; + hs->hash *= 0x880355f21e6d1965; /* reset hash state for next input */ hs->accum = 0; @@ -79,7 +79,7 @@ fasthash_init(fasthash_state *hs, int len, uint64 seed) // since we don't know the length for a nul-terminated string // handle some other way -- maybe we can accum the length in // the state and fold it in during the finalizer (cf. xxHash3) - hs->hash = seed ^ (len * 0x880355f21e6d1965ULL); + hs->hash = seed ^ (len * 0x880355f21e6d1965); } static inline void @@ -162,7 +162,7 @@ fasthash32(const unsigned char * k, int len, uint64 seed) // This function is generated using the framework provided. static inline uint64_t mix(uint64_t h) { h ^= h >> 23; - h *= 0x2127599bf4325c37ULL; + h *= 0x2127599bf4325c37; h ^= h >> 47; return h; } @@ -170,7 +170,7 @@ static inline uint64_t mix(uint64_t h) { static inline uint64_t fasthash64_orig(const void *buf, size_t len, uint64_t seed) { - const uint64_t m = 0x880355f21e6d1965ULL; + const uint64_t m = 0x880355f21e6d1965; const uint64_t *pos = (const uint64_t *)buf; const uint64_t *end = pos + (len / 8); const unsigned char *pos2; -- 2.43.0
From 6bd53c5ce11a44d39ad1deccc6c84e32b0d9a9fd Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Mon, 27 Nov 2023 17:03:38 +0700 Subject: [PATCH v9 1/6] Vendor fasthash MIT licensed --- src/include/common/hashfn_unstable.h | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/include/common/hashfn_unstable.h diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h new file mode 100644 index 0000000000..a5bf965fa2 --- /dev/null +++ b/src/include/common/hashfn_unstable.h @@ -0,0 +1,75 @@ +/* The MIT License + + Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include "fasthash.h" + +// Compression function for Merkle-Damgard construction. +// This function is generated using the framework provided. +#define mix(h) ({ \ + (h) ^= (h) >> 23; \ + (h) *= 0x2127599bf4325c37ULL; \ + (h) ^= (h) >> 47; }) + +uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) +{ + const uint64_t m = 0x880355f21e6d1965ULL; + const uint64_t *pos = (const uint64_t *)buf; + const uint64_t *end = pos + (len / 8); + const unsigned char *pos2; + uint64_t h = seed ^ (len * m); + uint64_t v; + + while (pos != end) { + v = *pos++; + h ^= mix(v); + h *= m; + } + + pos2 = (const unsigned char*)pos; + v = 0; + + switch (len & 7) { + case 7: v ^= (uint64_t)pos2[6] << 48; + case 6: v ^= (uint64_t)pos2[5] << 40; + case 5: v ^= (uint64_t)pos2[4] << 32; + case 4: v ^= (uint64_t)pos2[3] << 24; + case 3: v ^= (uint64_t)pos2[2] << 16; + case 2: v ^= (uint64_t)pos2[1] << 8; + case 1: v ^= (uint64_t)pos2[0]; + h ^= mix(v); + h *= m; + } + + return mix(h); +} + +uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) +{ + // the following trick converts the 64-bit hashcode to Fermat + // residue, which shall retain information from both the higher + // and lower parts of hashcode. + uint64_t h = fasthash64(buf, len, seed); + return h - (h >> 32); +} -- 2.43.0