From 09b4adabbf8862bfcdae9fd03b70c0e2d1dae71d Mon Sep 17 00:00:00 2001 From: reverse Date: Wed, 19 Aug 2026 01:51:31 +0000 Subject: [PATCH] =?UTF-8?q?disable:=20cache=20the=20disabled-command=20set?= =?UTF-8?q?=20(config=5Fgen-tagged=20HashSet)=20instead=20of=20re-splittin?= =?UTF-8?q?g=20disabled=5Fcommands=20on=20every=20non-oper=20command=20?= =?UTF-8?q?=E2=80=94=20the=20hottest=20hook=20in=20the=20server;=20re-pars?= =?UTF-8?q?es=20only=20on=20rehash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/disable.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/modules/disable.rs b/src/modules/disable.rs index 5ce3ee4..73f568e 100644 --- a/src/modules/disable.rs +++ b/src/modules/disable.rs @@ -2,11 +2,19 @@ //! `disabled_commands = LIST WHO KNOCK` (space-separated; repeatable). A disabled //! command replies with `421` as if it didn't exist. Off unless configured. +use crate::map::HashSet; use crate::module::{ModResult, Module}; use crate::numeric::ERR_UNKNOWNCOMMAND; use crate::server::Server; use crate::Uid; +/// The disabled-command set, parsed once and re-parsed only when the config changes. +#[derive(Default)] +struct DisabledCache { + gen: u64, + cmds: HashSet, // uppercased command names +} + pub struct Disable; impl Module for Disable { @@ -25,11 +33,22 @@ impl Module for Disable { if srv.is_oper(uid) { return ModResult::Passthru; } + // (re)build the set only when the config generation changes, not per command + let gen = srv.config_gen; + let stale = srv.ext.get::().map(|c| c.gen != gen).unwrap_or(true); + if stale { + let cmds: HashSet = srv + .conf_all("disabled_commands") + .iter() + .flat_map(|line| line.split_whitespace()) + .map(|c| c.to_ascii_uppercase()) + .collect(); + srv.ext.set(DisabledCache { gen, cmds }); + } let disabled = srv - .conf_all("disabled_commands") - .iter() - .flat_map(|line| line.split_whitespace()) - .any(|c| c.eq_ignore_ascii_case(cmd)); + .ext + .get::() + .is_some_and(|c| c.cmds.contains(&cmd.to_ascii_uppercase())); if disabled { srv.numeric( uid,