24#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
41 return (*p1)->
weight - (*p2)->weight;
54 double P_last, X_last, Xn;
67 const auto p = peer.get();
77 rawCarpPeers.push_back(p);
82 if (rawCarpPeers.empty())
86 for (
const auto p: rawCarpPeers) {
90 for (t = p->name; *t != 0; ++t)
93 p->carp.hash += p->carp.hash * 0x62531965;
100 if (floor(p->carp.load_factor * 1000.0) == 0.0)
101 p->carp.load_factor = 0.0;
105 qsort(rawCarpPeers.data(), rawCarpPeers.size(),
sizeof(
decltype(rawCarpPeers)::value_type),
peerSortWeight);
115 const auto K = rawCarpPeers.size();
123 for (
size_t k = 1; k <= K; ++k) {
124 double Kk1 = (
double) (K - k + 1);
125 const auto p = rawCarpPeers[k - 1];
126 p->carp.load_multiplier = (Kk1 * (p->carp.load_factor - P_last)) / Xn;
127 p->carp.load_multiplier += pow(X_last, Kk1);
128 p->carp.load_multiplier = pow(p->carp.load_multiplier, 1.0 / Kk1);
129 Xn *= p->carp.load_multiplier;
130 X_last = p->carp.load_multiplier;
131 P_last = p->carp.load_factor;
134 CarpPeers().assign(rawCarpPeers.begin(), rawCarpPeers.end());
144 unsigned int user_hash = 0;
145 unsigned int combined_hash;
147 double high_score = 0;
161 if (tp->options.carp_key.set) {
164 if (tp->options.carp_key.scheme) {
169 if (tp->options.carp_key.host) {
172 if (tp->options.carp_key.port) {
175 if (tp->options.carp_key.path) {
179 if (tp->options.carp_key.params) {
195 combined_hash = (user_hash ^ tp->carp.hash);
196 combined_hash += combined_hash * 0x62531965;
198 score = combined_hash * tp->carp.load_multiplier;
199 debugs(39, 3, *tp <<
" key=" << key <<
" combined_hash=" << combined_hash <<
200 " score=" << std::setprecision(0) << score);
202 if ((score > high_score) &&
peerHTTPOkay(tp.get(), ps)) {
209 debugs(39, 2,
"selected " << *p);
228 sumfetches += p->stats.fetches;
235 p->name, p->carp.hash,
236 p->carp.load_multiplier,
238 sumfetches ? (
double) p->stats.fetches / sumfetches : -1.0);
const CachePeers & CurrentCachePeers()
std::vector< CachePeer *, PoolingAllocator< CachePeer * > > RawCachePeers
Temporary, local storage of raw pointers to zero or more Config.peers.
std::vector< CbcPointer< CachePeer >, PoolingAllocator< CbcPointer< CachePeer > > > SelectedCachePeers
static void carpRegisterWithCacheManager(void)
static auto & CarpPeers()
CARP cache_peers ordered by their CARP weight.
CachePeer * carpSelectParent(PeerSelector *ps)
#define ROTATE_LEFT(x, n)
static int peerSortWeight(const void *a, const void *b)
AnyP::UriScheme const & getScheme() const
void port(const Port p)
reset authority port subcomponent
void host(const char *src)
AnyP::Uri url
the request URI
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
const char * rawContent() const
static const size_type npos
size_type length() const
Returns the number of bytes stored in SBuf.
SBuf & appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
SBuf & append(const SBuf &S)
MemBlob::size_type size_type
#define debugs(SECTION, LEVEL, CONTENT)
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
int peerHTTPOkay(const CachePeer *p, PeerSelector *ps)
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)