summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLukáš Ondráček <lukas.ondracek@nic.cz>2024-12-30 16:01:05 +0100
committerVladimír Čunát <vladimir.cunat@nic.cz>2024-12-30 16:46:47 +0100
commitd1b9ed92f20948aaea0168c437f85bf4084853aa (patch)
treeb1acd3f7c32dad32fbee73b0a71bc5796ea29771 /lib
parentdaemon/defer: make rate limits relative to single cpu (diff)
downloadknot-resolver-d1b9ed92f20948aaea0168c437f85bf4084853aa.tar.xz
knot-resolver-d1b9ed92f20948aaea0168c437f85bf4084853aa.zip
daemon/defer: add subpriorities by prefix length
Diffstat (limited to 'lib')
-rw-r--r--lib/kru.h8
-rw-r--r--lib/kru.inc.c28
2 files changed, 36 insertions, 0 deletions
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, \
}