github.com/xgzlucario/GigaCache@v0.0.0-20240508025442-54204e9c8a6b/utils.go (about) 1 package cache 2 3 import ( 4 "math/bits" 5 "sync/atomic" 6 "time" 7 "unsafe" 8 ) 9 10 var ( 11 // now nano time 12 nanosec atomic.Int64 13 sec atomic.Uint32 14 ) 15 16 //go:linkname FastRand runtime.fastrand 17 func FastRand() uint32 18 19 //go:linkname FastRand64 runtime.fastrand64 20 func FastRand64() uint64 21 22 type stringStruct struct { 23 str unsafe.Pointer 24 len int 25 } 26 27 //go:noescape 28 //go:linkname memhash runtime.memhash 29 func memhash(p unsafe.Pointer, h, s uintptr) uintptr 30 31 func init() { 32 now := time.Now() 33 nanosec.Store(now.UnixNano()) 34 sec.Store(uint32(now.Unix())) 35 36 go func() { 37 ticker := time.NewTicker(time.Millisecond) 38 for t := range ticker.C { 39 nanosec.Store(t.UnixNano()) 40 sec.Store(uint32(t.Unix())) 41 } 42 }() 43 } 44 45 // GetNanoSec returns the current nano time. 46 func GetNanoSec() int64 { 47 return nanosec.Load() 48 } 49 50 // GetSec returns the current unix time. 51 func GetSec() uint32 { 52 return sec.Load() 53 } 54 55 type HashFn func(string) uint64 56 57 // MemHash is the hash function used by go map, it utilizes available hardware instructions 58 // (behaves as aes hash if aes instruction is available). 59 // NOTE: The hash seed changes for every process. So, this cannot be used as a persistent hash. 60 func MemHash(str string) uint64 { 61 ss := (*stringStruct)(unsafe.Pointer(&str)) 62 return uint64(memhash(ss.str, 0, uintptr(ss.len))) 63 } 64 65 func s2b(str *string) []byte { 66 strHeader := (*[2]uintptr)(unsafe.Pointer(str)) 67 byteSliceHeader := [3]uintptr{ 68 strHeader[0], strHeader[1], strHeader[1], 69 } 70 return *(*[]byte)(unsafe.Pointer(&byteSliceHeader)) 71 } 72 73 func b2s(b []byte) string { 74 return *(*string)(unsafe.Pointer(&b)) 75 } 76 77 // SizeUvarint 78 // See https://go-review.googlesource.com/c/go/+/572196/1/src/encoding/binary/varint.go#174 79 func SizeUvarint(x uint64) int { 80 return int(9*uint32(bits.Len64(x))+64) / 64 81 }