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  }