]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/BandwidthBucket.cc
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
13 #include "BandwidthBucket.h"
14 #include "ClientInfo.h"
15 #include "comm/Connection.h"
16 #include "debug/Stream.h"
19 BandwidthBucket::BandwidthBucket(const int speed
, const int initialLevelPercent
, const double sizeLimit
) :
20 bucketLevel( sizeLimit
* (initialLevelPercent
/ 100.0)),
22 writeSpeedLimit(speed
),
23 bucketSizeLimit(sizeLimit
)
26 /* put current time to have something sensible here */
27 prevTime
= current_dtime
;
31 BandwidthBucket::refillBucket()
35 // all these times are in seconds, with double precision
36 const double currTime
= current_dtime
;
37 const double timePassed
= currTime
- prevTime
;
39 // Calculate allowance for the time passed. Use double to avoid
40 // accumulating rounding errors for small intervals. For example, always
41 // adding 1 byte instead of 1.4 results in 29% bandwidth allocation error.
42 const double gain
= timePassed
* writeSpeedLimit
;
44 // to further combat error accumulation during micro updates,
45 // quit before updating time if we cannot add at least one byte
51 // for "first" connections, drain initial fat before refilling but keep
52 // updating prevTime to avoid bursts after the fat is gone
53 if (bucketLevel
> bucketSizeLimit
) {
54 debugs(77, 4, "not refilling while draining initial fat");
61 if (bucketLevel
> bucketSizeLimit
)
62 bucketLevel
= bucketSizeLimit
;
66 BandwidthBucket::applyQuota(int &nleft
, Comm::IoCallback
*state
)
68 const int q
= quota();
73 const int nleft_corrected
= min(nleft
, q
);
74 if (nleft
!= nleft_corrected
) {
75 debugs(77, 5, state
->conn
<< " writes only " <<
76 nleft_corrected
<< " out of " << nleft
);
77 nleft
= nleft_corrected
;
83 BandwidthBucket::reduceBucket(const int len
)
85 if (len
<= 0 || noLimit())
88 if (bucketLevel
< 0.0) {
89 debugs(77, DBG_IMPORTANT
, "drained too much"); // should not happen
95 BandwidthBucket::SelectBucket(fde
*f
)
97 BandwidthBucket
*bucket
= f
->writeQuotaHandler
.getRaw();
99 ClientInfo
*clientInfo
= f
->clientInfo
;
100 if (clientInfo
&& clientInfo
->writeLimitingActive
)
106 #endif /* USE_DELAY_POOLS */