github.com/cockroachdb/swiss@v0.0.0-20240303172742-c161743eb608/options.go (about) 1 // Copyright 2024 The Cockroach Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package swiss 16 17 import "unsafe" 18 19 // Option provides an interface for passing configuration parameters for Map 20 // initialization. 21 type Option[K comparable, V any] interface { 22 apply(m *Map[K, V]) 23 } 24 25 type hashOption[K comparable, V any] struct { 26 hash func(key *K, seed uintptr) uintptr 27 } 28 29 func (op hashOption[K, V]) apply(m *Map[K, V]) { 30 m.hash = *(*hashFn)(noescape(unsafe.Pointer(&op.hash))) 31 } 32 33 // WithHash is an option to specify the hash function to use for a Map[K,V]. 34 func WithHash[K comparable, V any](hash func(key *K, seed uintptr) uintptr) Option[K, V] { 35 return hashOption[K, V]{hash} 36 } 37 38 type maxBucketCapacityOption[K comparable, V any] struct { 39 maxBucketCapacity uint32 40 } 41 42 func (op maxBucketCapacityOption[K, V]) apply(m *Map[K, V]) { 43 m.maxBucketCapacity = op.maxBucketCapacity 44 } 45 46 // WithMaxBucketCapacity is an option to specify the max bucket size to use 47 // for a Map[K,V]. Specifying a very large bucket size results in slower 48 // resize operations but delivers performance more akin to a raw Swiss table. 49 func WithMaxBucketCapacity[K comparable, V any](v uint32) Option[K, V] { 50 return maxBucketCapacityOption[K, V]{v} 51 } 52 53 // Allocator specifies an interface for allocating and releasing memory used 54 // by a Map. The default allocator utilizes Go's builtin make() and allows the 55 // GC to reclaim memory. 56 // 57 // If the allocator is manually managing memory and requires that slots and 58 // controls be freed then Map.Close must be called in order to ensure 59 // FreeSlots and FreeControls are called. 60 type Allocator[K comparable, V any] interface { 61 // Alloc should return a slice equivalent to make([]Group, n). 62 Alloc(n int) []Group[K, V] 63 64 // Free can optionally release the memory associated with the supplied 65 // slice that is guaranteed to have been allocated by Alloc. 66 Free(groups []Group[K, V]) 67 } 68 69 type defaultAllocator[K comparable, V any] struct{} 70 71 func (defaultAllocator[K, V]) Alloc(n int) []Group[K, V] { 72 return make([]Group[K, V], n) 73 } 74 75 func (defaultAllocator[K, V]) Free(_ []Group[K, V]) { 76 } 77 78 type allocatorOption[K comparable, V any] struct { 79 allocator Allocator[K, V] 80 } 81 82 func (op allocatorOption[K, V]) apply(m *Map[K, V]) { 83 m.allocator = op.allocator 84 } 85 86 // WithAllocator is an option for specifying the Allocator to use for a Map[K,V]. 87 func WithAllocator[K comparable, V any](allocator Allocator[K, V]) Option[K, V] { 88 return allocatorOption[K, V]{allocator} 89 }