From 79fc95888755cdf235d9806076857f72403203cd Mon Sep 17 00:00:00 2001 From: "Folke H. Gleumes" Date: Fri, 17 May 2024 22:17:00 +0200 Subject: [PATCH] Improve compile time and introduce features This patch allows the different indexes to be toggled since they contribute significantly to compile time and for many applications not all three are needed. Additionally the entry-or_insert pattern was replaced by building the HashMap from a slice, reducing the compile time even more. --- x11-keysymdef/Cargo.toml | 6 +++ x11-keysymdef/build.rs | 95 ++++++++++++++++++++++------------------ x11-keysymdef/src/lib.rs | 6 +++ 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/x11-keysymdef/Cargo.toml b/x11-keysymdef/Cargo.toml index 39c17fc..ea246b6 100644 --- a/x11-keysymdef/Cargo.toml +++ b/x11-keysymdef/Cargo.toml @@ -14,3 +14,9 @@ lazy_static = "1.3.0" [build-dependencies] serde_json = "1.0.40" serde = { version = "1.0.97", features = ["derive"] } + +[features] +default = ["by_name", "by_codepoint", "by_keysym" ] +by_name = [] +by_codepoint = [] +by_keysym = [] diff --git a/x11-keysymdef/build.rs b/x11-keysymdef/build.rs index b3e2ae7..8a151f6 100644 --- a/x11-keysymdef/build.rs +++ b/x11-keysymdef/build.rs @@ -56,65 +56,74 @@ fn from_json() { writeln!(&mut file, "::lazy_static::lazy_static! {{").unwrap(); // First map: Index by name - writeln!( - &mut file, - "static ref BY_NAMES: ::std::collections::HashMap<&'static str, &'static Record> = {{" - ) - .unwrap(); - writeln!(&mut file, "let mut map = ::std::collections::HashMap::new();").unwrap(); - for (index, r) in records.iter().enumerate() { - // multiple names per record possible, add one entry for each - for name in &r.names { - // Use unchecked access here because we just built the array of records - // with exactly these indices. - writeln!( - &mut file, - r#"map.entry("{}").or_insert(unsafe {{ RECORDS.get_unchecked({}) }});"#, - name, index - ) - .unwrap(); + #[cfg(feature = "by_name")] + { + writeln!( + &mut file, + "static ref BY_NAMES: ::std::collections::HashMap<&'static str, &'static Record> = {{" + ) + .unwrap(); + writeln!(&mut file, "::std::collections::HashMap::from([").unwrap(); + for (index, r) in records.iter().enumerate() { + // multiple names per record possible, add one entry for each + for name in &r.names { + // Use unchecked access here because we just built the array of records + // with exactly these indices. + writeln!( + &mut file, + r#"("{}", unsafe {{ RECORDS.get_unchecked({}) }}),"#, + name, index + ) + .unwrap(); + } } + writeln!(&mut file, "])").unwrap(); + writeln!(&mut file, "}};").unwrap(); } - writeln!(&mut file, "map").unwrap(); - writeln!(&mut file, "}};").unwrap(); // Next up: Index by codepoint - writeln!( - &mut file, - "static ref BY_CODEPOINT: std::collections::HashMap = {{" - ) - .unwrap(); - writeln!(&mut file, "let mut map = std::collections::HashMap::new();").unwrap(); - - for (index, r) in records.iter().enumerate() { + #[cfg(feature = "by_codepoint")] + { writeln!( &mut file, - r#"map.entry('\u{{{:x}}}').or_insert(unsafe {{ RECORDS.get_unchecked({}) }});"#, - r.unicode, index + "static ref BY_CODEPOINT: std::collections::HashMap = {{" ) .unwrap(); + writeln!(&mut file, "std::collections::HashMap::from([").unwrap(); + + for (index, r) in records.iter().enumerate() { + writeln!( + &mut file, + r#"('\u{{{:x}}}', unsafe {{ RECORDS.get_unchecked({}) }}),"#, + r.unicode, index + ) + .unwrap(); + } + writeln!(&mut file, "])").unwrap(); + writeln!(&mut file, "}};").unwrap(); } - writeln!(&mut file, "map").unwrap(); - writeln!(&mut file, "}};").unwrap(); // Last but not least: Index by keysym - writeln!( - &mut file, - "static ref BY_KEYSYM: std::collections::HashMap = {{" - ) - .unwrap(); - writeln!(&mut file, "let mut map = std::collections::HashMap::new();").unwrap(); - - for (index, r) in records.iter().enumerate() { + #[cfg(feature = "by_keysym")] + { writeln!( &mut file, - r#"map.entry({}).or_insert(unsafe {{ RECORDS.get_unchecked({}) }});"#, - r.keysym, index + "static ref BY_KEYSYM: std::collections::HashMap = {{" ) .unwrap(); + writeln!(&mut file, "std::collections::HashMap::from([").unwrap(); + + for (index, r) in records.iter().enumerate() { + writeln!( + &mut file, + r#"({}, unsafe {{ RECORDS.get_unchecked({}) }}),"#, + r.keysym, index + ) + .unwrap(); + } + writeln!(&mut file, "])").unwrap(); + writeln!(&mut file, "}};").unwrap(); } - writeln!(&mut file, "map").unwrap(); - writeln!(&mut file, "}};").unwrap(); // End of lazy_static writeln!(&mut file, "}}").unwrap(); diff --git a/x11-keysymdef/src/lib.rs b/x11-keysymdef/src/lib.rs index 413ba87..c38c93b 100644 --- a/x11-keysymdef/src/lib.rs +++ b/x11-keysymdef/src/lib.rs @@ -11,23 +11,29 @@ include!(concat!(env!("OUT_DIR"), "/mapping.rs")); /// Look up a record by the mnemonic macro name +#[cfg(feature = "by_name")] pub fn lookup_by_name(name: &str) -> Option<&'static Record> { BY_NAMES.get(&name).copied() } /// Look up a record by unicode char (unicode code point) +#[cfg(feature = "by_codepoint")] pub fn lookup_by_codepoint(codepoint: char) -> Option<&'static Record> { BY_CODEPOINT.get(&codepoint).copied() } /// Look up a mnemonic macro name by the keysym code +#[cfg(feature = "by_keysym")] pub fn lookup_by_keysym(keysym: u32) -> Option<&'static Record> { BY_KEYSYM.get(&keysym).copied() } #[test] fn access_works() { + #[cfg(feature = "by_name")] assert!(lookup_by_name("Uhorngrave").is_some()); + #[cfg(feature = "by_codepoint")] assert!(lookup_by_codepoint('\u{1EEA}').is_some()); + #[cfg(feature = "by_keysym")] assert!(lookup_by_keysym(0x1eea).is_some()); }