@@ -14,12 +14,12 @@ import (
1414// similar to the congestion control algorithm used in TCP.
1515type AIMDTokenBucketLimiter struct {
1616 limiter * TokenBucketLimiter
17- rates atomicSliceInt64 // Per-bucket rates in tokens per second
18- rateMin int64 // Minimum rate (tokens per unit)
19- rateMax int64 // Maximum rate (tokens per unit)
20- rateAI int64 // Additive increase (tokens per unit)
21- rateMD float64 // Multiplicative decrease (multiplier)
22- rateUnit time.Duration // Time unit for rate calculations
17+ rates atomicSliceFloat64 // Per-bucket rates in tokens per unit
18+ rateMin float64 // Minimum rate (tokens per unit)
19+ rateMax float64 // Maximum rate (tokens per unit)
20+ rateAI float64 // Additive increase (tokens per unit)
21+ rateMD float64 // Multiplicative decrease (multiplier)
22+ rateUnit time.Duration // Time unit for rate calculations
2323}
2424
2525// NewAIMDTokenBucketLimiter creates a new AIMD token bucket limiter
@@ -139,18 +139,17 @@ func NewAIMDTokenBucketLimiter(
139139 }
140140 }
141141
142- rate := nanoRate (rateUnit , rateInit )
143- rates := newAtomicSliceInt64 (limiter .buckets .Len ())
142+ rates := newAtomicSliceFloat64 (limiter .buckets .Len ())
144143 for i := range rates .Len () {
145- rates .Set (i , rate )
144+ rates .Set (i , rateInit )
146145 }
147146
148147 return & AIMDTokenBucketLimiter {
149148 limiter : limiter ,
150149 rates : rates ,
151- rateMin : nanoRate ( rateUnit , rateMin ) ,
152- rateMax : nanoRate ( rateUnit , rateMax ) ,
153- rateAI : nanoRate ( rateUnit , rateAdditiveIncrease ) ,
150+ rateMin : rateMin ,
151+ rateMax : rateMax ,
152+ rateAI : rateAdditiveIncrease ,
154153 rateMD : rateMultiplicativeDecrease ,
155154 rateUnit : rateUnit ,
156155 }, nil
@@ -163,7 +162,8 @@ func NewAIMDTokenBucketLimiter(
163162func (a * AIMDTokenBucketLimiter ) TakeToken (id []byte ) bool {
164163 index := a .limiter .index (id )
165164 rate := a .rates .Get (index )
166- return a .limiter .takeTokenInner (index , rate )
165+ nano := nanoRate (a .rateUnit , rate )
166+ return a .limiter .takeTokenInner (index , nano )
167167}
168168
169169// Check returns whether a token would be available for the given ID
@@ -175,7 +175,8 @@ func (a *AIMDTokenBucketLimiter) TakeToken(id []byte) bool {
175175func (a * AIMDTokenBucketLimiter ) Check (id []byte ) bool {
176176 index := a .limiter .index (id )
177177 rate := a .rates .Get (index )
178- return a .limiter .checkInner (index , rate )
178+ nano := nanoRate (a .rateUnit , rate )
179+ return a .limiter .checkInner (index , nano )
179180}
180181
181182// IncreaseRate additively increases the rate for the bucket
@@ -192,7 +193,7 @@ func (a *AIMDTokenBucketLimiter) IncreaseRate(id []byte) float64 {
192193 for {
193194 rate := a .rates .Get (index )
194195 if rate == a .rateMax {
195- return unitRate ( a . rateUnit , rate )
196+ return rate
196197 }
197198
198199 next := a .rateMax
@@ -201,11 +202,11 @@ func (a *AIMDTokenBucketLimiter) IncreaseRate(id []byte) float64 {
201202 }
202203
203204 if rate == next {
204- return unitRate ( a . rateUnit , rate )
205+ return rate
205206 }
206207
207208 if a .rates .CompareAndSwap (index , rate , next ) {
208- return unitRate ( a . rateUnit , rate )
209+ return rate
209210 }
210211 }
211212}
@@ -227,16 +228,16 @@ func (a *AIMDTokenBucketLimiter) DecreaseRate(id []byte) float64 {
227228 for {
228229 rate := a .rates .Get (index )
229230 if rate == a .rateMin {
230- return unitRate ( a . rateUnit , rate )
231+ return rate
231232 }
232233
233- next := max (a .rateMin , a .rateMin + int64 ( float64 ( rate - a .rateMin )/ a .rateMD ) )
234+ next := max (a .rateMin , a .rateMin + ( rate - a .rateMin )/ a .rateMD )
234235 if rate == next {
235- return unitRate ( a . rateUnit , rate )
236+ return rate
236237 }
237238
238239 if a .rates .CompareAndSwap (index , rate , next ) {
239- return unitRate ( a . rateUnit , rate )
240+ return rate
240241 }
241242 }
242243}
@@ -248,6 +249,5 @@ func (a *AIMDTokenBucketLimiter) DecreaseRate(id []byte) float64 {
248249// goroutines.
249250func (a * AIMDTokenBucketLimiter ) Rate (id []byte ) float64 {
250251 index := a .limiter .index (id )
251- rate := a .rates .Get (index )
252- return unitRate (a .rateUnit , rate )
252+ return a .rates .Get (index )
253253}
0 commit comments