29#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
47 return (*p1)->
weight - (*p2)->weight;
54 double P_last, X_last, Xn;
65 const auto peer = p.get();
67 if (!p->options.userhash)
75 rawUserHashPeers.push_back(peer);
80 if (rawUserHashPeers.empty())
84 for (
const auto &p: rawUserHashPeers) {
88 for (t = p->name; *t != 0; ++t)
89 p->userhash.hash +=
ROTATE_LEFT(p->userhash.hash, 19) + (
unsigned int) *t;
91 p->userhash.hash += p->userhash.hash * 0x62531965;
93 p->userhash.hash =
ROTATE_LEFT(p->userhash.hash, 21);
96 p->userhash.load_factor = ((
double) p->weight) / (
double) W;
98 if (floor(p->userhash.load_factor * 1000.0) == 0.0)
99 p->userhash.load_factor = 0.0;
103 qsort(rawUserHashPeers.data(), rawUserHashPeers.size(),
sizeof(
decltype(rawUserHashPeers)::value_type),
peerSortWeight);
113 const auto K = rawUserHashPeers.size();
121 for (
size_t k = 1; k <= K; ++k) {
122 double Kk1 = (
double) (K - k + 1);
123 const auto p = rawUserHashPeers[k - 1];
124 p->userhash.load_multiplier = (Kk1 * (p->userhash.load_factor - P_last)) / Xn;
125 p->userhash.load_multiplier += pow(X_last, Kk1);
126 p->userhash.load_multiplier = pow(p->userhash.load_multiplier, 1.0 / Kk1);
127 Xn *= p->userhash.load_multiplier;
128 X_last = p->userhash.load_multiplier;
129 P_last = p->userhash.load_factor;
132 UserHashPeers().assign(rawUserHashPeers.begin(), rawUserHashPeers.end());
147 unsigned int user_hash = 0;
148 unsigned int combined_hash;
150 double high_score = 0;
151 const char *key =
nullptr;
166 debugs(39, 2,
"peerUserHashSelectParent: Calculating hash for " << key);
168 for (c = key; *c != 0; ++c)
176 combined_hash = (user_hash ^ tp->userhash.hash);
177 combined_hash += combined_hash * 0x62531965;
179 score = combined_hash * tp->userhash.load_multiplier;
180 debugs(39, 3, *tp <<
" combined_hash " << combined_hash <<
181 " score " << std::setprecision(0) << score);
183 if ((score > high_score) &&
peerHTTPOkay(tp.get(), ps)) {
190 debugs(39, 2,
"selected " << *p);
209 sumfetches += p->stats.fetches;
216 p->name, p->userhash.hash,
217 p->userhash.load_multiplier,
218 p->userhash.load_factor,
219 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
char const * username() const
Auth::UserRequest::Pointer auth_user_request
#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)
#define ROTATE_LEFT(x, n)
static void peerUserHashRegisterWithCacheManager(void)
static int peerSortWeight(const void *a, const void *b)
static auto & UserHashPeers()
userhash peers ordered by their userhash weight
void peerUserHashInit(void)
static OBJH peerUserHashCachemgr
CachePeer * peerUserHashSelectParent(PeerSelector *ps)
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)