wz_reader 0.0.21

A wz file reader to resolve wz file with thread safe
Documentation
use criterion::{black_box, criterion_group, Criterion};
use std::sync::Arc;
use wz_reader::version::WzMapleVersion;
use wz_reader::{property::WzSubProperty, WzImage, WzNode, WzNodeArc, WzNodeCast, WzObjectType};

fn create_int_node(num: i32, parent: &WzNodeArc) -> WzNodeArc {
    WzNode::new(&format!("{}", num).into(), num, Some(parent)).into_lock()
}

fn thin_setup() -> (WzNodeArc, String) {
    let root = WzNode::new(
        &"root".into(),
        WzObjectType::Property(WzSubProperty::Property),
        None,
    )
    .into_lock();

    let (_, mut path) = (0..99).fold((Arc::clone(&root), String::from("")), |node, num| {
        let child = create_int_node(num, &node.0);
        node.0
            .write()
            .unwrap()
            .children
            .insert(num.to_string().into(), Arc::clone(&child));
        (child, format!("{}/{}", node.1, num))
    });

    path.remove(0);

    (root, path)
}

fn fat_setup() -> (WzNodeArc, String) {
    let root = WzNode::new(
        &"root".into(),
        WzObjectType::Property(WzSubProperty::Property),
        None,
    )
    .into_lock();

    let (_, mut path) = (0..=500).fold((Arc::clone(&root), String::from("")), |node, _| {
        let first = create_int_node(0, &node.0);
        node.0
            .write()
            .unwrap()
            .children
            .insert("0".into(), Arc::clone(&first));

        let last = (1..=500).fold(first, |_, num| {
            let child = create_int_node(num, &node.0);
            node.0
                .write()
                .unwrap()
                .children
                .insert(num.to_string().into(), Arc::clone(&child));
            child
        });
        (last, format!("{}/{}", node.1, 500))
    });

    path.remove(0);

    (root, path)
}

fn lookup(node: &WzNodeArc, look_path: &str) {
    assert!(node.read().unwrap().at_path(look_path).is_some());
}
fn parse_and_lookup(node: &WzNodeArc, look_path: &str) {
    assert!(node.write().unwrap().parse(node).is_ok());
    assert!(node.read().unwrap().at_path(look_path).is_some());
}
fn direct_lookup(node: &WzImage, look_path: &str) {
    assert!(node.at_path(look_path).is_ok());
}

fn thin_bench(c: &mut Criterion) {
    let (node, path) = thin_setup();
    c.bench_function("thin node lookup", |b| {
        b.iter(|| lookup(black_box(&node), black_box(&path)))
    });
}

fn fat_bench(c: &mut Criterion) {
    let (node, path) = fat_setup();
    c.bench_function("fat node lookup", |b| {
        b.iter(|| lookup(black_box(&node), black_box(&path)))
    });
}

fn parse_and_access_bench(c: &mut Criterion) {
    let node = WzNode::from_wz_file_full(
        "./benches/benchmarks/test.wz",
        Some(WzMapleVersion::BMS),
        Some(123),
        None,
        None,
    )
    .unwrap()
    .into_lock();
    assert!(node.write().unwrap().parse(&node).is_ok());
    let image_node = node.read().unwrap().at("wz_img.img").unwrap();
    c.bench_function("parse and access lookup", |b| {
        b.iter(|| {
            parse_and_lookup(black_box(&image_node), "1/1/1/1/1/1/1/1/1/1/1");
        })
    });
}

fn access_after_parsing_bench(c: &mut Criterion) {
    let node = WzNode::from_wz_file_full(
        "./benches/benchmarks/test.wz",
        Some(WzMapleVersion::BMS),
        Some(123),
        None,
        None,
    )
    .unwrap()
    .into_lock();
    assert!(node.write().unwrap().parse(&node).is_ok());
    let image_node = node.read().unwrap().at("wz_img.img").unwrap();
    image_node.write().unwrap().parse(&image_node).unwrap();
    c.bench_function("access after parsing lookup", |b| {
        b.iter(|| {
            lookup(black_box(&image_node), "1/1/1/1/1/1/1/1/1/1/1");
        })
    });
}

fn direct_access_bench(c: &mut Criterion) {
    let node = WzNode::from_wz_file_full(
        "./benches/benchmarks/test.wz",
        Some(WzMapleVersion::BMS),
        Some(123),
        None,
        None,
    )
    .unwrap()
    .into_lock();
    assert!(node.write().unwrap().parse(&node).is_ok());
    let image_node = node.read().unwrap().at("wz_img.img").unwrap();
    let image_node = image_node.read().unwrap();
    let image_node = image_node.try_as_image().unwrap();
    c.bench_function("direct access lookup", |b| {
        b.iter(|| {
            direct_lookup(black_box(&image_node), "1/1/1/1/1/1/1/1/1/1/1");
        })
    });
}

criterion_group!(
    benches,
    thin_bench,
    fat_bench,
    parse_and_access_bench,
    access_after_parsing_bench,
    direct_access_bench
);