char *id;
JournalRateLimitPool pools[POOLS_MAX];
- unsigned hash;
+ unsigned long hash;
LIST_FIELDS(JournalRateLimitGroup, bucket);
LIST_FIELDS(JournalRateLimitGroup, lru);
JournalRateLimitGroup *lru, *lru_tail;
unsigned n_groups;
+
+ uint8_t hash_key[16];
};
JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
r->interval = interval;
r->burst = burst;
+ random_bytes(r->hash_key, sizeof(r->hash_key));
+
return r;
}
if (g->parent->lru_tail == g)
g->parent->lru_tail = g->lru_prev;
- LIST_REMOVE(JournalRateLimitGroup, lru, g->parent->lru, g);
- LIST_REMOVE(JournalRateLimitGroup, bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
+ LIST_REMOVE(lru, g->parent->lru, g);
+ LIST_REMOVE(bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
g->parent->n_groups --;
}
free(r);
}
-static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) {
+_pure_ static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) {
unsigned i;
assert(g);
if (!g->id)
goto fail;
- g->hash = string_hash_func(g->id);
+ g->hash = string_hash_func(g->id, r->hash_key);
journal_rate_limit_vacuum(r, ts);
- LIST_PREPEND(JournalRateLimitGroup, bucket, r->buckets[g->hash % BUCKETS_MAX], g);
- LIST_PREPEND(JournalRateLimitGroup, lru, r->lru, g);
+ LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g);
+ LIST_PREPEND(lru, r->lru, g);
if (!g->lru_next)
r->lru_tail = g;
r->n_groups ++;
}
int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
- unsigned h;
+ unsigned long h;
JournalRateLimitGroup *g;
JournalRateLimitPool *p;
unsigned burst;
ts = now(CLOCK_MONOTONIC);
- h = string_hash_func(id);
+ h = string_hash_func(id, r->hash_key);
g = r->buckets[h % BUCKETS_MAX];
LIST_FOREACH(bucket, g, g)