golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.73k stars 17.63k forks source link

proposal: sync: Add sync.MutexMap generic type #70066

Closed 13770129 closed 4 hours ago

13770129 commented 4 hours ago

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 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.

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

  1. 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.

  2. 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.

  3. Connection Pools: Managing a pool of database or network connections where connections are frequently borrowed and returned, requiring balanced read/write access.

  4. Request Deduplication: Services that need to track and deduplicate in-flight requests, where items are frequently added and removed.

  5. 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

  1. 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.

  2. Cache Behavior: The simpler memory layout of a mutex-protected map could potentially improve CPU cache utilization, but this needs empirical validation.

  3. 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

  1. Type Safety: Generic implementation provides compile-time type checking
  2. Performance: A mutex-protected map may be more efficient for workloads sync.Map is not intended for
  3. Safety: Providing a standard implementation helps avoid common mistakes
  4. Convenience: Reduces boilerplate in codebases
  5. 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:

  1. Core type and methods
  2. Comprehensive test suite
  3. Benchmarks comparing performance with sync.Map under various workloads
  4. Documentation and examples
gabyhelp commented 4 hours ago

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

seankhliao commented 4 hours ago

Duplicate of #47657