From d1b9ed92f20948aaea0168c437f85bf4084853aa Mon Sep 17 00:00:00 2001 From: Lukáš Ondráček Date: Mon, 30 Dec 2024 16:01:05 +0100 Subject: daemon/defer: add subpriorities by prefix length --- lib/kru.h | 8 ++++++++ lib/kru.inc.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'lib') diff --git a/lib/kru.h b/lib/kru.h index ef177ef8..b3690703 100644 --- a/lib/kru.h +++ b/lib/kru.h @@ -90,6 +90,14 @@ struct kru_api { /// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace; as above. uint16_t (*load_multi_prefix_max)(struct kru *kru, uint32_t time_now, uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint8_t *prefix_out); + + + /// Multiple queries based on different prefixes of a single key. + /// Stores the final values of the involved counters normalized to the limit 2^16 to *loads_out (unless NULL). + /// Set prices to NULL to skip updating; otherwise, KRU is always updated, using maximal allowed value on overflow. + /// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace; as above. + void (*load_multi_prefix)(struct kru *kru, uint32_t time_now, + uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint16_t *loads_out); }; // The functions are stored this way to make it easier to switch diff --git a/lib/kru.inc.c b/lib/kru.inc.c index 2272adab..166e1004 100644 --- a/lib/kru.inc.c +++ b/lib/kru.inc.c @@ -565,6 +565,33 @@ static uint8_t kru_limited_multi_prefix_or(struct kru *kru, uint32_t time_now, u return 0; } +static void kru_load_multi_prefix(struct kru *kru, uint32_t time_now, uint8_t namespace, + uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint16_t *loads_out) +{ + struct query_ctx ctx[queries_cnt]; + + for (size_t i = 0; i < queries_cnt; i++) { + kru_limited_prefetch_prefix(kru, time_now, namespace, key, prefixes[i], (prices ? prices[i] : 0), ctx + i); + } + + for (size_t i = 0; i < queries_cnt; i++) { + kru_limited_fetch(kru, ctx + i); + } + + if (prices) { + for (int i = queries_cnt - 1; i >= 0; i--) { + kru_limited_update(kru, ctx + i, true); + } + } + + if (loads_out) { + for (size_t i = 0; i < queries_cnt; i++) { + loads_out[i] = ctx[i].final_load_value; + } + } +} + + static uint16_t kru_load_multi_prefix_max(struct kru *kru, uint32_t time_now, uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint8_t *prefix_out) { @@ -612,5 +639,6 @@ static bool kru_limited(struct kru *kru, uint32_t time_now, uint8_t key[static 1 .limited_multi_or = kru_limited_multi_or, \ .limited_multi_or_nobreak = kru_limited_multi_or_nobreak, \ .limited_multi_prefix_or = kru_limited_multi_prefix_or, \ + .load_multi_prefix = kru_load_multi_prefix, \ .load_multi_prefix_max = kru_load_multi_prefix_max, \ } -- cgit v1.2.3