package utilities import ( "math" "math/rand/v2" "time" ) var ( ApplyJitter = DefaultApplyJitter ) const ( maxInt64 = math.MaxInt64 minInt64 = math.MinInt64 ) func satAdd(a, b int64) int64 { switch { case b > 0 && a > maxInt64-b: return maxInt64 case b < 0 && a < minInt64-b: return minInt64 default: return a + b } } func satSub(a, b int64) int64 { switch { case b > 0 && a < minInt64+b: return minInt64 case b < 0 && a > maxInt64+b: return maxInt64 default: return a - b } } func absDurationSat(d time.Duration) time.Duration { if d >= 0 { return d } if d == time.Duration(math.MinInt64) { return time.Duration(math.MaxInt64) } return -d } func DefaultApplyJitter(pauseDuration time.Duration, jitter time.Duration) time.Duration { switch { case pauseDuration <= 0: return 0 case jitter == 0: return pauseDuration case jitter < 0: jitter = absDurationSat(jitter) case jitter > pauseDuration: pauseDuration, jitter = jitter, pauseDuration } min := satSub(pauseDuration.Nanoseconds(), jitter.Nanoseconds()) if min < 0 { min = 0 } max := satAdd(pauseDuration.Nanoseconds(), jitter.Nanoseconds()) if max <= min { return time.Duration(min) } var maxExcl int64 if max == math.MaxInt64 { span := max - min if span == math.MaxInt64 { return time.Duration(rand.Int64N(math.MaxInt64) + min) } n := rand.Int64N(span + 1) return time.Duration(min + n) } maxExcl = max + 1 return time.Duration(min + rand.Int64N(maxExcl-min)) }