Skip to content

Commit

Permalink
Add and use new string-cache-codegen crate
Browse files Browse the repository at this point in the history
  • Loading branch information
aidanhs authored and SimonSapin committed Oct 27, 2016
1 parent e0b355e commit a9efc44
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 103 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ script:
- cargo test --features log-events
- "if [ $TRAVIS_RUST_VERSION = nightly ]; then cargo test --features unstable; fi"
- cargo test --features heapsize
- "cd string-cache-codegen/ && cargo build && cd .."
- "cd examples/event-log/ && cargo build && cd ../.."
- "cd examples/summarize-events/ && cargo build && cd ../.."
notifications:
Expand Down
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ repository = "https://github.com/servo/string-cache"
documentation = "https://docs.rs/string_cache/"
build = "build.rs"

# Do not `exclude` ./string-cache-codegen because we want to include
# ./string-cache-codegen/shared.rs, and `include` is a pain to use
# (It has to be exhaustive.)
# This means that packages for this crate include some unused files,
# but they’re not too big so that shouldn’t be a problem.

[lib]
name = "string_cache"

Expand Down Expand Up @@ -36,4 +42,4 @@ heapsize = { version = "0.3", optional = true }
rand = "0.3"

[build-dependencies]
phf_generator = "0.7.4"
string_cache_codegen = { version = "0.3", path = "./string-cache-codegen" }
62 changes: 7 additions & 55 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,62 +1,14 @@
extern crate phf_generator;
extern crate string_cache_codegen;

#[path = "src/shared.rs"] #[allow(dead_code)] mod shared;
#[path = "src/static_atom_list.rs"] mod static_atom_list;
#[path = "src/static_atom_list.rs"]
mod static_atom_list;

use std::env;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;

fn main() {
let hash_state = generate();
write_static_atom_set(&hash_state);
write_atom_macro(&hash_state);
}

fn generate() -> phf_generator::HashState {
let mut set = std::collections::HashSet::new();
for atom in static_atom_list::ATOMS {
if !set.insert(atom) {
panic!("duplicate static atom `{:?}`", atom);
}
}
phf_generator::generate_hash(static_atom_list::ATOMS)
}

fn write_static_atom_set(hash_state: &phf_generator::HashState) {
let path = Path::new(&std::env::var("OUT_DIR").unwrap()).join("static_atom_set.rs");
let mut file = BufWriter::new(File::create(&path).unwrap());
macro_rules! w {
($($arg: expr),+) => { (writeln!(&mut file, $($arg),+).unwrap()) }
}
w!("pub static STATIC_ATOM_SET: PhfStrSet = PhfStrSet {{");
w!(" key: {},", hash_state.key);
w!(" disps: &[");
for &(d1, d2) in &hash_state.disps {
w!(" ({}, {}),", d1, d2);
}
w!(" ],");
w!(" atoms: &[");
for &idx in &hash_state.map {
w!(" {:?},", static_atom_list::ATOMS[idx]);
}
w!(" ],");
w!("}};");
}

fn write_atom_macro(hash_state: &phf_generator::HashState) {
let path = Path::new(&env::var("OUT_DIR").unwrap()).join("atom_macro.rs");
let mut file = BufWriter::new(File::create(&path).unwrap());
writeln!(file, r"#[macro_export]").unwrap();
writeln!(file, r"macro_rules! atom {{").unwrap();
for (i, &idx) in hash_state.map.iter().enumerate() {
writeln!(
file,
r"({:?}) => {{ $crate::Atom {{ unsafe_data: 0x{:x}, phantom: ::std::marker::PhantomData }} }};",
static_atom_list::ATOMS[idx],
shared::pack_static(i as u32),
).unwrap();
}
writeln!(file, r"}}").unwrap();
string_cache_codegen::AtomType::new("atom::tests::TestAtom", "test_atom!")
.atoms(static_atom_list::ATOMS)
.write_to_file(&Path::new(&env::var("OUT_DIR").unwrap()).join("test_atom.rs"))
.unwrap()
}
2 changes: 1 addition & 1 deletion examples/summarize-events/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extern crate string_cache;
extern crate rustc_serialize;
extern crate phf_shared;

#[path = "../../../src/shared.rs"]
#[path = "../../../string-cache-codegen/shared.rs"]
#[allow(dead_code)]
mod shared;

Expand Down
51 changes: 22 additions & 29 deletions src/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ use self::UnpackedAtom::{Dynamic, Inline, Static};
#[cfg(feature = "log-events")]
use event::Event;

include!(concat!(env!("OUT_DIR"), "/static_atom_set.rs"));

#[cfg(not(feature = "log-events"))]
macro_rules! log (($e:expr) => (()));

Expand Down Expand Up @@ -199,7 +197,7 @@ impl StaticAtomSet for EmptyStaticAtomSet {
pub type DefaultAtom = Atom<EmptyStaticAtomSet>;

pub struct Atom<Static: StaticAtomSet> {
/// This field is public so that the `atom!()` macro can use it.
/// This field is public so that the `atom!()` macros can use it.
/// You should not otherwise access this field.
#[doc(hidden)]
pub unsafe_data: u64,
Expand Down Expand Up @@ -234,7 +232,7 @@ impl<Static: StaticAtomSet> Atom<Static> {

impl<Static: StaticAtomSet> Default for Atom<Static> {
fn default() -> Self {
atom!("")
Self::from("")
}
}

Expand Down Expand Up @@ -581,26 +579,17 @@ fn copy_memory(src: &[u8], dst: &mut [u8]) {
}
}

#[cfg(all(test, feature = "unstable"))]
#[path = "bench.rs"]
mod bench;

#[cfg(test)]
#[macro_use]
mod tests {
use std::mem;
use std::thread;
use super::Atom as GenericAtom;
use super::{StaticAtomSet, StringCacheEntry, STATIC_ATOM_SET, PhfStrSet};
use super::{StaticAtomSet, StringCacheEntry};
use super::UnpackedAtom::{Dynamic, Inline, Static};
use shared::ENTRY_ALIGNMENT;

pub type Atom = GenericAtom<DefaultStatic>;
pub struct DefaultStatic;
impl StaticAtomSet for DefaultStatic {
fn get() -> &'static PhfStrSet {
&STATIC_ATOM_SET
}
}
include!(concat!(env!("OUT_DIR"), "/test_atom.rs"));
pub type Atom = TestAtom;

#[test]
fn test_as_slice() {
Expand Down Expand Up @@ -741,17 +730,17 @@ mod tests {
assert_eq_fmt!("0x{:016X}", x.unsafe_data, Atom::from(s).unsafe_data);
assert_eq!(0x2, x.unsafe_data & 0xFFFF_FFFF);
// The index is unspecified by phf.
assert!((x.unsafe_data >> 32) <= DefaultStatic::get().atoms.len() as u64);
assert!((x.unsafe_data >> 32) <= TestAtomStaticSet::get().atoms.len() as u64);
}

// This test is here to make sure we don't change atom representation
// by accident. It may need adjusting if there are changes to the
// static atom table, the tag values, etc.

// Static atoms
check_static("a", atom!("a"));
check_static("address", atom!("address"));
check_static("area", atom!("area"));
check_static("a", test_atom!("a"));
check_static("address", test_atom!("address"));
check_static("area", test_atom!("area"));

// Inline atoms
check("e", 0x0000_0000_0000_6511);
Expand Down Expand Up @@ -790,27 +779,27 @@ mod tests {

#[test]
fn atom_macro() {
assert_eq!(atom!("body"), Atom::from("body"));
assert_eq!(atom!("font-weight"), Atom::from("font-weight"));
assert_eq!(test_atom!("body"), Atom::from("body"));
assert_eq!(test_atom!("font-weight"), Atom::from("font-weight"));
}

#[test]
fn match_atom() {
assert_eq!(2, match Atom::from("head") {
atom!("br") => 1,
atom!("html") | atom!("head") => 2,
test_atom!("br") => 1,
test_atom!("html") | test_atom!("head") => 2,
_ => 3,
});

assert_eq!(3, match Atom::from("body") {
atom!("br") => 1,
atom!("html") | atom!("head") => 2,
test_atom!("br") => 1,
test_atom!("html") | test_atom!("head") => 2,
_ => 3,
});

assert_eq!(3, match Atom::from("zzzzzz") {
atom!("br") => 1,
atom!("html") | atom!("head") => 2,
test_atom!("br") => 1,
test_atom!("html") | test_atom!("head") => 2,
_ => 3,
});
}
Expand Down Expand Up @@ -869,3 +858,7 @@ mod tests {
assert!(Atom::from("camembert".to_owned()) == Atom::from("camembert"));
}
}

#[cfg(all(test, feature = "unstable"))]
#[path = "bench.rs"]
mod bench;
20 changes: 6 additions & 14 deletions src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,12 @@ and cheap to move around, which isn't reflected in these tests.
*/

use atom::tests::Atom;
use atom::tests::TestAtom;
use test::{Bencher, black_box};

macro_rules! test_atom {
($tt: tt) => {{
// Add type annotation to help inference
let atom: Atom = atom!($tt);
atom
}}
}

// Just shorthand
fn mk(x: &str) -> Atom {
Atom::from(x)
fn mk(x: &str) -> TestAtom {
TestAtom::from(x)
}

macro_rules! check_type (($name:ident, $x:expr, $p:pat) => (
Expand Down Expand Up @@ -89,7 +81,7 @@ macro_rules! bench_one (
fn intern(b: &mut Bencher) {
let x = $x.to_string();
b.iter(|| {
black_box(Atom::from(&*x));
black_box(TestAtom::from(&*x));
});
}
);
Expand Down Expand Up @@ -142,7 +134,7 @@ macro_rules! bench_all (
use std::string::ToString;
use std::iter::repeat;

use atom::tests::Atom;
use atom::tests::TestAtom;
use atom::UnpackedAtom::{Static, Inline, Dynamic};

use super::mk;
Expand Down Expand Up @@ -213,7 +205,7 @@ macro_rules! bench_rand ( ($name:ident, $len:expr) => (
*n = (*n % 0x40) + 0x20;
}
let s = str::from_utf8(&buf[..]).unwrap();
black_box(Atom::from(s));
black_box(TestAtom::from(s));
});
}
));
Expand Down
12 changes: 9 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ extern crate phf_shared;

pub use atom::{Atom, StaticAtomSet, PhfStrSet, EmptyStaticAtomSet, DefaultAtom};

include!(concat!(env!("OUT_DIR"), "/atom_macro.rs"));

#[cfg(feature = "log-events")]
#[macro_use]
pub mod event;

pub mod atom;
pub mod shared;

#[path = "../string-cache-codegen/shared.rs"]
mod shared;

// Make test_atom! macro work in this crate.
// `$crate` would not be appropriate for other crates creating such macros
mod string_cache {
pub use {Atom, StaticAtomSet, PhfStrSet};
}
16 changes: 16 additions & 0 deletions string-cache-codegen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]

name = "string_cache_codegen"
version = "0.3.0"
authors = [ "The Servo Project Developers" ]
description = "A codegen library for string-cache, developed as part of the Servo project."
license = "MIT / Apache-2.0"
repository = "https://github.com/servo/string-cache"
documentation = "https://docs.rs/string_cache_codegen/"

[lib]
name = "string_cache_codegen"
path = "lib.rs"

[dependencies]
phf_generator = "0.7.15"
Loading

0 comments on commit a9efc44

Please sign in to comment.