Files
Chris Lu ec83a87d68 perf(s3/lifecycle): defer pool Put on ShardID hasher
defer guarantees the hasher returns to the pool even if h.Write or
h.Sum panic, preventing pool leak under unexpected failure modes.
2026-05-07 17:08:50 -07:00

34 lines
987 B
Go

package s3lifecycle
import (
"crypto/sha256"
"hash"
"sync"
)
// ShardCount partitions the (bucket, key) keyspace for the per-shard
// lifecycle reader. Workers receive one READ task per owned shard;
// each shard's cursor advances independently.
const ShardCount = 16
// shardHashPool reuses sha256 hashers — ShardID is in the per-event hot
// path and a fresh allocation per call shows up under load.
var shardHashPool = sync.Pool{
New: func() interface{} { return sha256.New() },
}
// ShardID maps (bucket, key) to a shard in [0, ShardCount). Stable across
// restarts and across processes — identical (bucket, key) always lands on
// the same shard. Implementation: top 4 bits of sha256(bucket || "/" || key).
func ShardID(bucket, key string) int {
h := shardHashPool.Get().(hash.Hash)
defer shardHashPool.Put(h)
h.Reset()
h.Write([]byte(bucket))
h.Write([]byte{'/'})
h.Write([]byte(key))
var buf [sha256.Size]byte
sum := h.Sum(buf[:0])
return int(sum[0] >> 4)
}