func NewShardedWithSize[K comparable, V any]()

in shardedlru.go [60:114]


func NewShardedWithSize[K comparable, V any](shards, capacity, size uint32,
	hash HashKeyCallback[K]) (
	*ShardedLRU[K, V], error) {
	if capacity == 0 {
		return nil, errors.New("capacity must be positive")
	}
	if size < capacity {
		return nil, fmt.Errorf("size (%d) is smaller than capacity (%d)", size, capacity)
	}

	if size < 1<<31 {
		size = nextPowerOfTwo(size) // next power of 2 so the LRUs can avoid costly divisions
	} else {
		size = 1 << 31 // the highest 2^N value that fits in a uint32
	}

	shards = nextPowerOfTwo(shards) // next power of 2 so we can avoid costly division for sharding

	for shards > size/16 {
		shards /= 16
	}
	if shards == 0 {
		shards = 1
	}

	size /= shards // size per LRU
	if size == 0 {
		size = 1
	}

	capacity = (capacity + shards - 1) / shards // size per LRU
	if capacity == 0 {
		capacity = 1
	}

	lrus := make([]LRU[K, V], shards)
	buckets := make([]uint32, size*shards)
	elements := make([]element[K, V], size*shards)

	from := 0
	to := int(size)
	for i := range lrus {
		initLRU(&lrus[i], capacity, size, hash, buckets[from:to], elements[from:to])
		from = to
		to += int(size)
	}

	return &ShardedLRU[K, V]{
		lrus:   lrus,
		mus:    make([]sync.RWMutex, shards),
		hash:   hash,
		shards: shards,
		mask:   shards - 1,
	}, nil
}