Skip to content

feat: add top-level CompareAndSwap and CompareAndDelete functions #14

@millerjp

Description

@millerjp

feat: add top-level CompareAndSwap and CompareAndDelete functions

Summary

sync.Map gained CompareAndSwap and CompareAndDelete in Go 1.20. Both require the value type to be comparable. SyncMap[K comparable, V any] allows non-comparable V (slices, maps, functions), so these cannot be added as methods without a breaking constraint change. Per the v1.0.0 requirements doc and the user's architectural decision recorded in the plan, expose them as top-level generic functions with a tighter V comparable constraint — mirroring the stdlib pattern for constraint mismatches. The SyncMap type constraints stay unchanged.

Requirements

  1. Add in syncmap.go (or a new cas.go at the implementer's discretion — prefer syncmap.go to keep single-source rule):
    func CompareAndSwap[K, V comparable](m *SyncMap[K, V], key K, old, new V) (swapped bool)
    func CompareAndDelete[K, V comparable](m *SyncMap[K, V], key K, old V) (deleted bool)
    Each wraps the corresponding sync.Map method.
  2. Godoc on both functions: style matching docs: add doc.go and rewrite godoc on every exported symbol #11, calling out the V comparable constraint explicitly and naming the reason (sync.Map requires it).
  3. Unit tests in syncmap_test.go:
    • TestCompareAndSwap — subtests: match_swaps_returns_true, mismatch_no_swap_returns_false, missing_key_returns_false, zero_V_match_works.
    • TestCompareAndDelete — subtests: match_deletes_returns_true, mismatch_no_delete_returns_false, missing_key_returns_false, zero_V_match_works.
    • TestCompareAndSwapContention — 100 goroutines all attempting CAS on same key; exactly one succeeds per round.
  4. Coverage must not regress; new functions included in the 95% total.
  5. Apache 2.0 header; no AI-attribution tokens.
  6. CHANGELOG "Added" entry (lands in feat: add top-level CompareAndSwap and CompareAndDelete functions #14 if CHANGELOG exists, otherwise ships with this PR).

Acceptance Criteria

  1. grep -nE 'func CompareAndSwap\[' syncmap.go returns exactly one match.
  2. grep -nE 'func CompareAndDelete\[' syncmap.go returns exactly one match.
  3. Both functions compile against SyncMap[string, int] (comparable V) in the test file.
  4. A deliberate test-compile check with SyncMap[string, []byte] (non-comparable V) must produce a compile error — demonstrated by a comment in the test file referencing the Go playground or by including a commented-out line in a file-level comment block documenting that this is the expected failure mode. This is documentation, not a running test — it proves the constraint is load-bearing.
  5. go doc github.com/axonops/syncmap CompareAndSwap and … CompareAndDelete print non-empty godoc.
  6. go test -race -run 'TestCompareAndSwap|TestCompareAndDelete' -count=10 ./... passes stably.
  7. make coverage reports ≥95% including the new functions.
  8. make check passes end-to-end.
  9. CI on the PR green.

Testing Requirements

Documentation Requirements

Dependencies

Labels

  • enhancement
  • P0

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Blocks releaseenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions