30#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
48 return (*p1)->
weight - (*p2)->weight;
55 double P_last, X_last, Xn;
66 const auto peer = p.get();
68 if (!p->options.userhash)
76 rawUserHashPeers.push_back(peer);
81 if (rawUserHashPeers.empty())
85 for (
const auto &p: rawUserHashPeers) {
89 for (t = p->name; *t != 0; ++t)
90 p->userhash.hash +=
ROTATE_LEFT(p->userhash.hash, 19) + (
unsigned int) *t;
92 p->userhash.hash += p->userhash.hash * 0x62531965;
94 p->userhash.hash =
ROTATE_LEFT(p->userhash.hash, 21);
97 p->userhash.load_factor = ((
double) p->weight) / (
double) W;
99 if (floor(p->userhash.load_factor * 1000.0) == 0.0)
100 p->userhash.load_factor = 0.0;
104 qsort(rawUserHashPeers.data(), rawUserHashPeers.size(),
sizeof(
decltype(rawUserHashPeers)::value_type),
peerSortWeight);
114 const auto K = rawUserHashPeers.size();
122 for (
size_t k = 1; k <= K; ++k) {
123 double Kk1 = (
double) (K - k + 1);
124 const auto p = rawUserHashPeers[k - 1];
125 p->userhash.load_multiplier = (Kk1 * (p->userhash.load_factor - P_last)) / Xn;
126 p->userhash.load_multiplier += pow(X_last, Kk1);
127 p->userhash.load_multiplier = pow(p->userhash.load_multiplier, 1.0 / Kk1);
128 Xn *= p->userhash.load_multiplier;
129 X_last = p->userhash.load_multiplier;
130 P_last = p->userhash.load_factor;
133 UserHashPeers().assign(rawUserHashPeers.begin(), rawUserHashPeers.end());
159 unsigned int user_hash = 0;
160 unsigned int combined_hash;
162 double high_score = 0;
163 const char *key =
nullptr;
178 debugs(39, 2,
"peerUserHashSelectParent: Calculating hash for " << key);
180 for (c = key; *c != 0; ++c)
188 combined_hash = (user_hash ^ tp->userhash.hash);
189 combined_hash += combined_hash * 0x62531965;
191 score = combined_hash * tp->userhash.load_multiplier;
192 debugs(39, 3, *tp <<
" combined_hash " << combined_hash <<
193 " score " << std::setprecision(0) << score);
195 if ((score > high_score) &&
peerHTTPOkay(tp.get(), ps)) {
202 debugs(39, 2,
"selected " << *p);
221 sumfetches += p->stats.fetches;
228 p->name, p->userhash.hash,
229 p->userhash.load_multiplier,
230 p->userhash.load_factor,
231 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
#define DefineRunnerRegistrator(ClassName)
char const * username() const
Auth::UserRequest::Pointer auth_user_request
reacts to RegisteredRunner events relevant to this module
void useConfig() override
void syncConfig() override
#define debugs(SECTION, LEVEL, CONTENT)
void RegisterAction(char const *action, char const *desc, OBJH *handler, Protected, Atomic, Format)
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
static OBJH peerUserHashCachemgr
CachePeer * peerUserHashSelectParent(PeerSelector *ps)
static void peerUserHashInit(void)
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)