Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
13770129 opened this issue Oct 26, 2024 · 2 comments
Closed

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

13770129 opened this issue Oct 26, 2024 · 2 comments
Labels
Milestone

Comments

@13770129
Copy link

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:

  • Duplicated code across projects
  • Potential subtle correctness issues
  • Inconsistent implementations

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
@gopherbot gopherbot added this to the Proposal milestone Oct 26, 2024
@seankhliao
Copy link
Member

Duplicate of #47657

@seankhliao seankhliao marked this as a duplicate of #47657 Oct 26, 2024
@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Oct 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants