29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Reflection;
32 using OpenSim.Framework;
36 namespace OpenSim.
Region.ClientStack.LindenUDP
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 private static Int32 m_counter = 0;
50 protected const float m_timeScale = 1e-3f;
59 protected const float m_quantumsPerBurst = 5;
63 protected const float m_minimumDripRate = 1500;
78 protected Dictionary<TokenBucket, float> m_children =
new Dictionary<TokenBucket, float>();
90 get {
return m_parent; }
91 set { m_parent = value; }
100 public virtual float MaxDripRate {
get; set; }
102 public float RequestedBurst
104 get {
return m_burst; }
106 float rate = (value < 0 ? 0 : value);
107 if (rate < 1.5f * m_minimumDripRate)
108 rate = 1.5f * m_minimumDripRate;
109 else if (rate > m_minimumDripRate * m_quantumsPerBurst)
110 rate = m_minimumDripRate * m_quantumsPerBurst;
119 float rate = RequestedBurst * BurstModifier();
120 if (rate < m_minimumDripRate)
121 rate = m_minimumDripRate;
137 public virtual float RequestedDripRate
139 get {
return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); }
141 m_dripRate = (value < 0 ? 0 : value);
142 m_totalDripRequest = m_dripRate;
144 if (m_parent != null)
145 m_parent.RegisterRequest(
this,m_dripRate);
149 public virtual float DripRate
152 float rate = Math.Min(RequestedDripRate,TotalDripRequest);
153 if (m_parent == null)
156 rate *= m_parent.DripRateModifier();
157 if (rate < m_minimumDripRate)
158 rate = m_minimumDripRate;
168 public float TotalDripRequest
170 get {
return m_totalDripRequest; }
171 set { m_totalDripRequest = value; }
174 #endregion Properties
194 RequestedDripRate = dripRate;
195 RequestedBurst = MaxBurst;
198 m_lastDrip = Util.EnvironmentTickCount() + 100000;
201 #endregion Constructor
212 float driprate = DripRate;
213 return driprate >= TotalDripRequest ? 1.0f : driprate / TotalDripRequest;
223 return DripRateModifier();
234 m_children[child] = request;
236 m_totalDripRequest = 0;
237 foreach (KeyValuePair<TokenBucket, float> cref
in m_children)
238 m_totalDripRequest += cref.Value;
242 if (m_parent != null)
243 m_parent.RegisterRequest(
this, Math.Min(RequestedDripRate, TotalDripRequest));
254 m_children.Remove(child);
256 m_totalDripRequest = 0;
257 foreach (KeyValuePair<TokenBucket, float> cref
in m_children)
258 m_totalDripRequest += cref.Value;
263 Parent.RegisterRequest(
this,Math.Min(RequestedDripRate, TotalDripRequest));
278 if (m_tokenCount - amount >= 0)
282 m_tokenCount -= amount;
291 return (m_tokenCount - amount >= 0);
297 return (
int)(timeMS * DripRate * 1e-3);
312 m_log.WarnFormat(
"[TOKENBUCKET] something odd is happening and drip rate is 0 for {0}", m_counter);
316 Int32 now = Util.EnvironmentTickCount();
317 Int32 deltaMS = now - m_lastDrip;
323 m_tokenCount += deltaMS * DripRate * m_timeScale;
326 if (m_tokenCount > burst)
327 m_tokenCount = burst;
333 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
335 public bool AdaptiveEnabled {
get; set; }
342 protected const float m_minimumFlow = 50000;
349 protected float m_maxDripRate = 0;
350 public override float MaxDripRate
352 get {
return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
355 m_maxDripRate = (value == 0 ? m_totalDripRequest : Math.Max(value, m_minimumFlow));
359 private bool m_enabled =
false;
364 public virtual float AdjustedDripRate
366 get {
return m_dripRate; }
369 m_dripRate = OpenSim.Framework.Util.Clamp<
float>(value, m_minimumFlow, MaxDripRate);
371 if (m_parent != null)
372 m_parent.RegisterRequest(
this, m_dripRate);
381 : base(parent, maxDripRate, maxBurst)
385 MaxDripRate = maxDripRate;
388 AdjustedDripRate = m_maxDripRate * .5f;
390 AdjustedDripRate = m_maxDripRate;
401 AdjustedDripRate = (Int64)(AdjustedDripRate / Math.Pow(2, count));
410 AdjustedDripRate = AdjustedDripRate + count;
A hierarchical token bucket for bandwidth throttling. See http://en.wikipedia.org/wiki/Token_bucket f...
Int32 m_lastDrip
Time of the last drip, in system ticks
float m_totalDripRequest
The current total of the requested maximum burst rates of children buckets.
bool CheckTokens(int amount)
void UnregisterRequest(TokenBucket child)
Remove the rate requested by a child of this throttle. Pass the changes up the hierarchy.
TokenBucket m_parent
The parent bucket of this bucket, or null if this bucket has no parent. The parent bucket will limit ...
TokenBucket(TokenBucket parent, float dripRate, float MaxBurst)
Default constructor
float DripRateModifier()
Compute a modifier for the MaxBurst rate. This is 1.0, meaning no modification if the requested bandw...
AdaptiveTokenBucket(TokenBucket parent, float maxDripRate, float maxBurst, bool enabled)
bool RemoveTokens(int amount)
Remove a given number of tokens from the bucket
float m_tokenCount
The number of bytes that can be sent at this moment. This is the current number of tokens in the buck...
int GetCatBytesCanSend(int timeMS)
void RegisterRequest(TokenBucket child, float request)
Register drip rate requested by a child of this throttle. Pass the changes up the hierarchy...
void Drip()
Add tokens to the bucket over time. The number of tokens added each call depends on the length of tim...
float m_dripRate
The requested drip rate for this particular bucket.
void AcknowledgePackets(Int32 count)
float m_burst
This is the maximum number of tokens that can accumulate in the bucket at any one time...
void ExpirePackets(Int32 count)
Reliable packets sent to the client for which we never received an ack adjust the drip rate down...