github.com/zhangyunhao116/wyhash@v0.4.1-0.20220217162229-7d42996fa899/wyhashv3.go (about) 1 package wyhash 2 3 import ( 4 "unsafe" 5 6 "github.com/zhangyunhao116/sbconv" 7 "github.com/zhangyunhao116/wyhash/internal/unalign" 8 ) 9 10 func Sum64V3(data []byte) uint64 { 11 return Sum64WithSeedV3(data, DefaultSeed) 12 } 13 14 func Sum64StringV3(data string) uint64 { 15 return Sum64StringWithSeedV3(data, DefaultSeed) 16 } 17 18 func Sum64WithSeedV3(data []byte, seed uint64) uint64 { 19 return Sum64StringWithSeedV3(sbconv.BytesToString(data), seed) 20 } 21 22 func Sum64StringWithSeedV3(data string, seed uint64) uint64 { 23 var ( 24 a, b uint64 25 ) 26 27 length := len(data) 28 i := uintptr(len(data)) 29 paddr := *(*unsafe.Pointer)(unsafe.Pointer(&data)) 30 31 if length <= 16 { 32 if length >= 4 { 33 // Note: for short string, i == uintptr(length) 34 // a=(_wyr4(p)<<32)|_wyr4(p+((len>>3)<<2)); b=(_wyr4(p+len-4)<<32)|_wyr4(p+len-4-((len>>3)<<2)); 35 a = unalign.Read4(paddr)<<32 | unalign.Read4(add(paddr, (i>>3)<<2)) 36 b = unalign.Read4(add(paddr, i-4))<<32 | unalign.Read4(add(paddr, i-4-((i>>3)<<2))) 37 } else if length > 0 { 38 // a=_wyr3(p,len); b=0; 39 a = uint64(*(*byte)(paddr))<<16 | uint64(*(*byte)(add(paddr, uintptr(i>>1))))<<8 | uint64(*(*byte)(add(paddr, uintptr(i-1)))) 40 } 41 } else { 42 var ( 43 see1 = seed 44 see2 = seed 45 ) 46 if i > 48 { 47 for i > 48 { 48 // seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed); 49 // see1=_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^see1); 50 // see2=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see2); 51 // p+=48; i-=48; 52 seed = _wymix(unalign.Read8(paddr)^s1, unalign.Read8(add(paddr, 8))^seed) 53 see1 = _wymix(unalign.Read8(add(paddr, 16))^s2, unalign.Read8(add(paddr, 24))^see1) 54 see2 = _wymix(unalign.Read8(add(paddr, 32))^s3, unalign.Read8(add(paddr, 40))^see2) 55 paddr = add(paddr, 48) 56 i -= 48 57 } 58 seed ^= see1 ^ see2 59 } 60 for i > 16 { 61 // seed=_wymix(unalign.Read8(p)^secret[1],unalign.Read8(p+8)^seed); i-=16; p+=16; 62 seed = _wymix(unalign.Read8(paddr)^s1, unalign.Read8(add(paddr, 8))^seed) 63 paddr = add(paddr, 16) 64 i -= 16 65 } 66 // a=unalign.Read8(p+i-16); b=unalign.Read8(p+i-8); 67 a = unalign.Read8(add(paddr, i-16)) 68 b = unalign.Read8(add(paddr, i-8)) 69 } 70 // _wymix(secret[1]^len,_wymix(a^secret[1],b^seed)); 71 return _wymix(s1^uint64(length), _wymix(a^s1, b^seed)) 72 }