fsmonitor: convert shown khash to strset in do_handle_client

Replace the khash-based string set used for deduplicating pathnames in do_handle_client() with a strset, which provides a cleaner interface for the same purpose. Since the paths are interned strings from the batch data, use strdup_strings=0 to avoid unnecessary copies. Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Paul Tarjan <github@paulisageek.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Paul Tarjan committed Apr 15, 2026 at 13:27 UTC b1cebd7194299ad5414ab2122b2970b339399446
1 file changed +6 -11
builtin/fsmonitor--daemon.c
+6 -11
@@ -16,7 +16,7 @@
16 #include "fsmonitor--daemon.h"
17
18 #include "simple-ipc.h"
19 -#include "khash.h"
19 +#include "strmap.h"
20 #include "run-command.h"
21 #include "trace.h"
22 #include "trace2.h"
@@ -674,8 +674,6 @@ static int fsmonitor_parse_client_token(const char *buf_token,
674 return 0;
675 }
676
677 -KHASH_INIT(str, const char *, int, 0, kh_str_hash_func, kh_str_hash_equal)
678 -
677 static int do_handle_client(struct fsmonitor_daemon_state *state,
678 const char *command,
679 ipc_server_reply_cb *reply,
@@ -692,8 +690,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
690 const struct fsmonitor_batch *batch;
691 struct fsmonitor_batch *remainder = NULL;
692 intmax_t count = 0, duplicates = 0;
695 - kh_str_t *shown = NULL;
696 - int hash_ret;
693 + struct strset shown = STRSET_INIT;
694 int do_trivial = 0;
695 int do_flush = 0;
696 int do_cookie = 0;
@@ -882,14 +879,14 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
879 * so walk the batch list backwards from the current head back
880 * to the batch (sequence number) they named.
881 *
885 - * We use khash to de-dup the list of pathnames.
882 + * We use a strset to de-dup the list of pathnames.
883 *
884 * NEEDSWORK: each batch contains a list of interned strings,
885 * so we only need to do pointer comparisons here to build the
886 * hash table. Currently, we're still comparing the string
887 * values.
888 */
892 - shown = kh_init_str();
889 + strset_init_with_options(&shown, NULL, 0);
890 for (batch = batch_head;
891 batch && batch->batch_seq_nr > requested_oldest_seq_nr;
892 batch = batch->next) {
@@ -899,11 +896,9 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
896 const char *s = batch->interned_paths[k];
897 size_t s_len;
898
902 - if (kh_get_str(shown, s) != kh_end(shown))
899 + if (!strset_add(&shown, s))
900 duplicates++;
901 else {
905 - kh_put_str(shown, s, &hash_ret);
906 -
902 trace_printf_key(&trace_fsmonitor,
903 "send[%"PRIuMAX"]: %s",
904 count, s);
@@ -973,7 +968,7 @@ static int do_handle_client(struct fsmonitor_daemon_state *state,
968 trace2_data_intmax("fsmonitor", the_repository, "response/count/duplicates", duplicates);
969
970 cleanup:
976 - kh_destroy_str(shown);
971 + strset_clear(&shown);
972 strbuf_release(&response_token);
973 strbuf_release(&requested_token_id);
974 strbuf_release(&payload);