github.com/duomi520/utils@v0.0.0-20240430123446-e03a4cddd6ec/cache.go (about) 1 package utils 2 3 import ( 4 "sync/atomic" 5 ) 6 7 type Cell struct { 8 wyhash uint64 9 fnv1a uint64 10 out any 11 } 12 13 // IdempotentCache 幂等函数缓存,幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数 14 type IdempotentCache[T string | []byte] struct { 15 //缓存的大小,使用2的power次方作为大小。 16 power uint64 17 size uint64 18 //用于hash的种子 19 seed uint64 20 buf []atomic.Value 21 do func(T) any 22 } 23 24 // Init 初始化 power表示缓存大小的指数,seed表示hash的种子,do表示要缓存的幂等函数 25 func (ic *IdempotentCache[T]) Init(power, seed uint64, do func(T) any) { 26 ic.power = power 27 ic.size = 2 ^ power 28 ic.seed = seed 29 ic.buf = make([]atomic.Value, 2^power) 30 ic.do = do 31 } 32 33 // Get 用于获取缓存中的结果 34 func (ic *IdempotentCache[T]) Get(in T) any { 35 h := Hash64WY(in, ic.seed) 36 f := Hash64FNV1A(in) 37 //取余 38 index := h & (ic.size - 1) 39 v := ic.buf[index].Load() 40 if v != nil { 41 cell := v.(Cell) 42 if cell.wyhash == h && cell.fnv1a == f { 43 return cell.out 44 } 45 } 46 c := Cell{wyhash: h, fnv1a: f, out: ic.do(in)} 47 ic.buf[index].Store(c) 48 return c.out 49 } 50 51 // https://github.com/cespare/xxhash