2 releases
0.1.1 | Nov 22, 2023 |
---|---|
0.1.0 | Oct 16, 2023 |
#1198 in Data structures
60KB
973 lines
QuickPHF-Codegen
quickphf_codegen
is a Rust crate that allows you to generate static hash maps and
hash sets at compile-time using
PTHash perfect hash functions.
For the runtime code necessary to use these data structures check out the
quickphf
crate instead.
The minimum supported Rust version is 1.56. This crate uses #![forbid(unsafe_code)]
.
WARNING: quickphf
and quickphf_codegen
currently use the standard library
Hash
trait which is not portable between systems with different endianness.
Example
Currently, the only way to generate data structures for use with quickphf
is by running
one of
build_raw_map
,
build_map
,
or build_set
,
displaying the result as a string, and then importing the resulting Rust code at the desired location.
For example, you can write a build.rs
script
such as:
use std::env;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;
fn main() {
let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs");
let mut file = BufWriter::new(fs::File::create(&path).unwrap());
let keys = ["jpg", "png", "svg"];
let values = ["image/jpeg", "image/png", "image/svg+xml"];
let code = quickphf_codegen::build_map(&keys, &values);
write!(&mut file, code).unwrap();
}
and then import the result in your lib.rs
by:
static MIME_TYPES: quickphf::PhfMap<&'static str, &'static str> =
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
Advanced Usage
Using QuickPHF with custom types
To be usable as a key in a PhfMap
or PhfSet
, or as value in a RawPhfMap
or a PhfMap
, a type must implement
the trait ConstInstantiable
, which provides a way to generate code which instantiates any value of that type in
a const
context. This trait is already implemented for many built-in types, but users can also implement it for
their own custom types, by one of two ways:
- If the code required to instantiate a value of a type is identical to its
Debug
representation, for example, like the following enum:
#[derive(Debug, Hash, PartialEq, Eq)]
enum PositionType {
Contract { hours_per_week: u32 },
Salaried,
Managerial,
}
then it suffices to write
impl quickphf_codegen::DebugInstantiable for PositionType {}
- The user has to provide a custom implementation. For example, the following struct has
private fields and thus its values cannot be instantiated using the
{}
syntax, but provides anew
constructor that isconst fn
. Thus, given
#[derive(Debug, Hash, PartialEq, Eq)]
struct EmploymentRules {
overtime_eligible: bool,
bonus_eligible: bool,
}
impl EmploymentRules {
pub const fn new(overtime_eligible: bool, bonus_eligible: bool) -> EmploymentRules {
EmploymentRules {
overtime_eligible,
bonus_eligible,
}
}
}
we can provide a custom ConstInstantiable
implementation by
use core::fmt;
use quickphf_codegen::*;
impl ConstInstantiable for EmploymentRules {
fn fmt_const_new(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"EmploymentRules::new({}, {})",
self.overtime_eligible, self.bonus_eligible
)
}
}
Performance
Generating a PHF-based data structure with quickphf_codegen
is about 10 times faster than
with phf
. It can generate a 1,000,000 entry map in about
300 ms.
License
Licensed under any of:
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
- zlib License (LICENSE-ZLIB or https://opensource.org/license/zlib/)
by your choice.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be multi-licensed as above, without any additional terms or conditions.
Dependencies
~94KB