I propose adding a new generic sync.MutexMap type that provides a type-safe, mutex-protected map implementing the same API as sync.Map plus a Len() method. This type would serve as an alternative to sync.Map for the common case where a basic mutex-protected map is sufficient or where sync.Map would not perform well.
However, developers must currently implement their own mutex-protected maps, leading to:
Duplicated code across projects
Potential subtle correctness issues
Inconsistent implementations
Use Cases
Session Storage: Web servers often need to store session data with mixed read/write patterns. A mutex-protected map is ideal for this common scenario where cache hit rates are unpredictable.
Configuration Management: Applications that need to occasionally update configuration values while handling frequent reads. Unlike sync.Map which is optimized for read-mostly workloads, MutexMap performs well with mixed access patterns.
Connection Pools: Managing a pool of database or network connections where connections are frequently borrowed and returned, requiring balanced read/write access.
Request Deduplication: Services that need to track and deduplicate in-flight requests, where items are frequently added and removed.
Rate Limiting: Tracking request counts per user/IP with frequent counter updates, where sync.Map's optimization for non-overlapping writes doesn't provide benefits.
Performance Considerations
Memory Usage: A MutexMap may use less memory than sync.Map as it only needs a single map and mutex, though this should be verified with benchmarks.
Cache Behavior: The simpler memory layout of a mutex-protected map could potentially improve CPU cache utilization, but this needs empirical validation.
Predictable Behavior: The performance characteristics of mutex-based locking are well understood, potentially making performance easier to reason about.
Proposal
Add a new generic type sync.MutexMap that wraps a standard map with a mutex:
type MutexMap[K comparable, V any] struct {
// contains filtered or unexported fields
}
// New creates a new MutexMap
func NewMutexMap[K comparable, V any]() *MutexMap[K, V]
// Methods with type safety
func (m *MutexMap[K, V]) Store(key K, value V)
func (m *MutexMap[K, V]) Load(key K) (value V, ok bool)
func (m *MutexMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool)
func (m *MutexMap[K, V]) LoadAndDelete(key K) (value V, loaded bool)
func (m *MutexMap[K, V]) Delete(key K)
func (m *MutexMap[K, V]) Range(f func(key K, value V) bool)
func (m *MutexMap[K, V]) Clear()
func (m *MutexMap[K, V]) Swap(key K, value V) (previous V, loaded bool)
func (m *MutexMap[K, V]) CompareAndSwap(key K, old, new V) bool
func (m *MutexMap[K, V]) CompareAndDelete(key K, old V) bool
func (m *MutexMap[K, V]) Len() int
Rationale
Type Safety: Generic implementation provides compile-time type checking
Performance: A mutex-protected map may be more efficient for workloads sync.Map is not intended for
Safety: Providing a standard implementation helps avoid common mistakes
Convenience: Reduces boilerplate in codebases
Length: Unlike sync.Map, a mutex-protected map can efficiently track its size
Compatibility
This change is fully backwards compatible as it only adds new functionality.
Implementation
I'm happy to implement this if the proposal is accepted. The implementation would include:
Core type and methods
Comprehensive test suite
Benchmarks comparing performance with sync.Map under various workloads
Proposal Details
Proposal: Add sync.MutexMap generic type
I propose adding a new generic
sync.MutexMap
type that provides a type-safe, mutex-protected map implementing the same API assync.Map
plus aLen()
method. This type would serve as an alternative tosync.Map
for the common case where a basic mutex-protected map is sufficient or wheresync.Map
would not perform well.Background
The current
sync.Map
documentation states: "Most code should use a plain Go map instead, with separate locking or coordination, for better type safety and to make it easier to maintain other invariants along with the map content."However, developers must currently implement their own mutex-protected maps, leading to:
Use Cases
Session Storage: Web servers often need to store session data with mixed read/write patterns. A mutex-protected map is ideal for this common scenario where cache hit rates are unpredictable.
Configuration Management: Applications that need to occasionally update configuration values while handling frequent reads. Unlike
sync.Map
which is optimized for read-mostly workloads,MutexMap
performs well with mixed access patterns.Connection Pools: Managing a pool of database or network connections where connections are frequently borrowed and returned, requiring balanced read/write access.
Request Deduplication: Services that need to track and deduplicate in-flight requests, where items are frequently added and removed.
Rate Limiting: Tracking request counts per user/IP with frequent counter updates, where
sync.Map
's optimization for non-overlapping writes doesn't provide benefits.Performance Considerations
Memory Usage: A
MutexMap
may use less memory thansync.Map
as it only needs a single map and mutex, though this should be verified with benchmarks.Cache Behavior: The simpler memory layout of a mutex-protected map could potentially improve CPU cache utilization, but this needs empirical validation.
Predictable Behavior: The performance characteristics of mutex-based locking are well understood, potentially making performance easier to reason about.
Proposal
Add a new generic type
sync.MutexMap
that wraps a standard map with a mutex:Rationale
sync.Map
is not intended forsync.Map
, a mutex-protected map can efficiently track its sizeCompatibility
This change is fully backwards compatible as it only adds new functionality.
Implementation
I'm happy to implement this if the proposal is accepted. The implementation would include:
sync.Map
under various workloads