1
0
mirror of https://github.com/redis/go-redis.git synced 2025-12-02 06:22:31 +03:00

combine cas

This commit is contained in:
Nedyalko Dyakov
2025-10-25 21:20:25 +03:00
parent 0773d52244
commit 9481c4d758
2 changed files with 10 additions and 14 deletions

View File

@@ -122,7 +122,7 @@ func (sm *ConnStateMachine) GetState() ConnState {
}
// TryTransitionFast is an optimized version for the hot path (Get/Put operations).
// It only handles simple IDLE ⇄ IN_USE transitions without waiter notification.
// It only handles simple state transitions without waiter notification.
// This is safe because:
// 1. Get/Put don't need to wait for state changes
// 2. Background operations (handoff/reauth) use UNUSABLE state, which this won't match
@@ -130,8 +130,11 @@ func (sm *ConnStateMachine) GetState() ConnState {
//
// Returns true if transition succeeded, false otherwise.
// Use this for performance-critical paths where you don't need error details.
//
// Performance: Single CAS operation - as fast as the old atomic bool!
// For multiple from states, use: sm.TryTransitionFast(State1, Target) || sm.TryTransitionFast(State2, Target)
// The || operator short-circuits, so only 1 CAS is executed in the common case.
func (sm *ConnStateMachine) TryTransitionFast(fromState, targetState ConnState) bool {
// Single CAS operation - as fast as the old atomic bool!
return sm.state.CompareAndSwap(uint32(fromState), uint32(targetState))
}

View File

@@ -599,19 +599,12 @@ func (p *ConnPool) popIdle() (*Conn, error) {
}
attempts++
// Hot path optimization: try fast IDLE → IN_USE transition first
// This is a single CAS operation, as fast as the old atomic bool
// Hot path optimization: try IDLE → IN_USE or CREATED → IN_USE transition
// Most connections will be IDLE (1 CAS), new connections will be CREATED (2 CAS)
// We inline both attempts to avoid function call overhead
sm := cn.GetStateMachine()
if sm.TryTransitionFast(StateIdle, StateInUse) {
// Successfully acquired the connection (common case)
p.idleConnsLen.Add(-1)
break
}
// Fast path failed - connection might be CREATED (uninitialized) or UNUSABLE (handoff/reauth)
// Try CREATED → IN_USE for new connections
if sm.TryTransitionFast(StateCreated, StateInUse) {
// Successfully acquired uninitialized connection
if sm.TryTransitionFast(StateIdle, StateInUse) || sm.TryTransitionFast(StateCreated, StateInUse) {
// Successfully acquired the connection
p.idleConnsLen.Add(-1)
break
}