From: Miroslav Lichvar Date: Thu, 4 Jun 2026 14:43:13 +0000 (+0200) Subject: clientlog: optimize get_record() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8cd87bdf3a031e47eeadabe986553950cf3852b6;p=thirdparty%2Fchrony.git clientlog: optimize get_record() In the clientlog get_record() function use a simplified local version of UTI_CompareIPs() to be inlined to minimize the overhead of searching in the slot. Revert commit 837323d687b9 ("clientlog: simplify code") and unroll the first assignment in the search for the last hit to help the compiler to produce faster code. --- diff --git a/clientlog.c b/clientlog.c index e18f8fce..a8fd10c6 100644 --- a/clientlog.c +++ b/clientlog.c @@ -214,6 +214,24 @@ compare_total_hits(Record *x, Record *y) /* ================================================== */ +static int +is_ip_equal(const IPAddr *a, const IPAddr *b) +{ + if (a->family != b->family) + return 0; + + switch (a->family) { + case IPADDR_INET4: + return a->addr.in4 == b->addr.in4; + case IPADDR_INET6: + return memcmp(a->addr.in6, b->addr.in6, sizeof (a->addr.in6)) == 0; + } + + return 0; +} + +/* ================================================== */ + static Record * get_record(IPAddr *ip) { @@ -231,14 +249,15 @@ get_record(IPAddr *ip) for (i = 0, oldest_record = NULL; i < SLOT_SIZE; i++) { record = ARR_GetElement(records, first + i); - if (!UTI_CompareIPs(ip, &record->ip_addr, NULL)) + if (is_ip_equal(ip, &record->ip_addr)) return record; if (record->ip_addr.family == IPADDR_UNSPEC) break; - for (j = 0; j < MAX_SERVICES; j++) { - if (j == 0 || compare_ts(last_hit, record->last_hit[j]) < 0) + last_hit = record->last_hit[0]; + for (j = 1; j < MAX_SERVICES; j++) { + if (compare_ts(last_hit, record->last_hit[j]) < 0) last_hit = record->last_hit[j]; } @@ -265,13 +284,16 @@ get_record(IPAddr *ip) } record->ip_addr = *ip; - for (i = 0; i < MAX_SERVICES; i++) { + for (i = 0; i < MAX_SERVICES; i++) record->last_hit[i] = INVALID_TS; + for (i = 0; i < MAX_SERVICES; i++) record->hits[i] = 0; + for (i = 0; i < MAX_SERVICES; i++) record->drops[i] = 0; + for (i = 0; i < MAX_SERVICES; i++) record->tokens[i] = max_tokens[i]; + for (i = 0; i < MAX_SERVICES; i++) record->rate[i] = INVALID_RATE; - } record->ntp_timeout_rate = INVALID_RATE; record->drop_flags = 0; diff --git a/test/unit/clientlog.c b/test/unit/clientlog.c index d7d40a0e..2ea1f763 100644 --- a/test/unit/clientlog.c +++ b/test/unit/clientlog.c @@ -73,7 +73,7 @@ test_unit(void) struct timespec ts, ts2; CLG_Service s; NTP_int64 ntp_ts; - IPAddr ip; + IPAddr ip, ip2; char *env, conf[][100] = { "clientloglimit 20000", "ratelimit interval 3 burst 4 leak 3", @@ -90,6 +90,18 @@ test_unit(void) TEST_CHECK(ARR_GetSize(records) == 16); + TST_GetRandomAddress(&ip, IPADDR_INET4, 8); + while (UTI_CompareIPs(&ip, &ip2, NULL) == 0) + TST_GetRandomAddress(&ip2, IPADDR_INET4, 8); + TEST_CHECK(is_ip_equal(&ip, &ip)); + TEST_CHECK(!is_ip_equal(&ip, &ip2)); + TST_GetRandomAddress(&ip, IPADDR_INET6, 8); + TEST_CHECK(!is_ip_equal(&ip, &ip2)); + while (UTI_CompareIPs(&ip, &ip2, NULL) == 0) + TST_GetRandomAddress(&ip2, IPADDR_INET6, 8); + TEST_CHECK(is_ip_equal(&ip, &ip)); + TEST_CHECK(!is_ip_equal(&ip, &ip2)); + /* Expected format of the variable: ITERS:BITS */ if ((env = getenv("BENCH_CLIENTLOG"))) { exit(!bench(env));