refactor lowercase hash key handling

This commit is contained in:
tali 2024-01-08 00:55:53 -05:00
parent 7b72410498
commit d310d4ad6e
2 changed files with 13 additions and 11 deletions

View File

@ -7,3 +7,8 @@ type fd = Lwt_unix.file_descr
let pp_sockaddr ppf = function let pp_sockaddr ppf = function
| Unix.ADDR_INET (adr, port) -> Fmt.pf ppf "%s:%d" (Unix.string_of_inet_addr adr) port | Unix.ADDR_INET (adr, port) -> Fmt.pf ppf "%s:%d" (Unix.string_of_inet_addr adr) port
| Unix.ADDR_UNIX path -> Fmt.string ppf path | Unix.ADDR_UNIX path -> Fmt.string ppf path
type string_ci = Case_insensitive of string [@@unboxed]
let pp_string_ci ppf (Case_insensitive s) = Fmt.string ppf s
let string_ci s = Case_insensitive (String.lowercase_ascii s)
let empty_string_ci = Case_insensitive ""

View File

@ -1,16 +1,14 @@
type nick_key = Nick_key of string [@@unboxed] open! Import
let nick_key n = Nick_key (String.lowercase_ascii n) (* TODO: "scandinavian" lowercase *)
let unset = Nick_key ""
type t = { type t = {
users : (nick_key, user) Hashtbl.t users : (string_ci, user) Hashtbl.t
(* TODO: channels *) (* TODO: channels *)
} }
and user = { and user = {
router : t; router : t;
hostname : string; hostname : string;
mutable key : nick_key; mutable key : string_ci;
mutable nick : Irc.nick; mutable nick : Irc.nick;
mutable userinfo : Irc.userinfo option; mutable userinfo : Irc.userinfo option;
mutable mode : Irc.Mode.t; mutable mode : Irc.Mode.t;
@ -22,7 +20,7 @@ let make () =
{ users = Hashtbl.create 4096 } { users = Hashtbl.create 4096 }
let find_user t nick = let find_user t nick =
Hashtbl.find_opt t.users (nick_key nick) Hashtbl.find_opt t.users (string_ci nick)
module User = struct module User = struct
type t = user type t = user
@ -32,7 +30,7 @@ module User = struct
{ {
router; router;
hostname; hostname;
key = unset; key = empty_string_ci;
nick = "*"; nick = "*";
userinfo = None; userinfo = None;
mode = Irc.Mode.of_string "iw"; mode = Irc.Mode.of_string "iw";
@ -41,19 +39,18 @@ module User = struct
let nick t = t.nick let nick t = t.nick
let prefix t = Irc.Msg.User_prefix (t.nick, t.userinfo, Some t.hostname) let prefix t = Irc.Msg.User_prefix (t.nick, t.userinfo, Some t.hostname)
let is_registered t = t.key <> empty_string_ci
let inbox t = t.inbox let inbox t = t.inbox
let send t msg = try t.push_inbox (Some msg) with Lwt_stream.Closed -> () let send t msg = try t.push_inbox (Some msg) with Lwt_stream.Closed -> ()
let close t = try t.push_inbox None with Lwt_stream.Closed -> () let close t = try t.push_inbox None with Lwt_stream.Closed -> ()
let is_registered t = t.key <> unset
let unregister t = let unregister t =
Hashtbl.remove t.router.users t.key; Hashtbl.remove t.router.users t.key;
t.key <- unset t.key <- empty_string_ci
let set_nick t new_nick = let set_nick t new_nick =
let key = nick_key new_nick in let key = string_ci new_nick in
if Hashtbl.mem t.router.users key then if Hashtbl.mem t.router.users key then
`nick_in_use `nick_in_use
else begin else begin