use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use fcb_core::error::Result;
use fcb_core::static_btree::Float;
use fcb_core::{AttrQuery, FcbReader, KeyType, Operator};
use std::{fs::File, io::BufReader};
fn read_fcb_without_attr_index(path: &str) -> Result<()> {
let input_file = File::open(path)?;
let input_reader = BufReader::new(input_file);
let mut reader = FcbReader::open(input_reader)?.select_all()?;
let header = reader.header();
let feat_count = header.features_count();
let mut target_feat_num = 0;
let mut feat_total = 0;
while let Some(feat_buf) = reader.next()? {
let feature = feat_buf.cur_cj_feature()?;
for (_, co) in feature.city_objects.iter() {
if let Some(attributes) = &co.attributes {
if let Some(identificatie) = attributes.get("identificatie") {
if identificatie.as_str().unwrap() == "NL.IMBAG.Pand.0503100000012869" {
target_feat_num += 1;
break;
}
}
}
}
feat_total += 1;
if feat_total == feat_count {
break;
}
}
Ok(())
}
fn read_fcb_with_attr_index_seekable(path: &str) -> Result<()> {
let input_file = File::open(path)?;
let input_reader = BufReader::new(input_file);
let query: AttrQuery = vec![
(
"b3_h_dak_50p".to_string(),
Operator::Gt,
KeyType::Float64(Float(2.0)),
),
(
"b3_h_dak_50p".to_string(),
Operator::Lt,
KeyType::Float64(Float(50.0)),
),
];
let mut reader = FcbReader::open(input_reader)?.select_attr_query(query)?;
let header = reader.header();
let feat_count = header.features_count();
let mut target_feat_num = 0;
let mut feat_total = 0;
while let Some(feat_buf) = reader.next()? {
let feature = feat_buf.cur_cj_feature()?;
for (_, co) in feature.city_objects.iter() {
if let Some(attributes) = &co.attributes {
if let Some(b3_h_dak_50p) = attributes.get("b3_h_dak_50p") {
if b3_h_dak_50p.as_f64().unwrap() > 2.0 && b3_h_dak_50p.as_f64().unwrap() < 50.0
{
println!("b3_h_dak_50p: {b3_h_dak_50p:?}");
target_feat_num += 1;
continue;
}
}
}
}
feat_total += 1;
if feat_total == feat_count {
break;
}
}
Ok(())
}
fn read_fcb_with_attr_index_non_seekable(path: &str) -> Result<()> {
let input_file = File::open(path)?;
let input_reader = BufReader::new(input_file);
let query: AttrQuery = vec![
(
"b3_h_dak_50p".to_string(),
Operator::Gt,
KeyType::Float64(Float(2.0)),
),
(
"b3_h_dak_50p".to_string(),
Operator::Lt,
KeyType::Float64(Float(50.0)),
),
];
let mut reader = FcbReader::open(input_reader)?.select_attr_query_seq(query)?;
let header = reader.header();
let feat_count = header.features_count();
let mut target_feat_num = 0;
let mut feat_total = 0;
while let Some(feat_buf) = reader.next()? {
let feature = feat_buf.cur_cj_feature()?;
for (_, co) in feature.city_objects.iter() {
if let Some(attributes) = &co.attributes {
if let Some(b3_h_dak_50p) = attributes.get("b3_h_dak_50p") {
if b3_h_dak_50p.as_f64().unwrap() > 2.0 && b3_h_dak_50p.as_f64().unwrap() < 50.0
{
println!("b3_h_dak_50p: {b3_h_dak_50p:?}");
target_feat_num += 1;
continue;
}
}
}
}
feat_total += 1;
if feat_total == feat_count {
break;
}
}
Ok(())
}
const DATASETS: &[(&str, (&str, &str))] = &[(
"delft",
(
"benchmark_data/attribute/3dbag_partial.fcb",
"benchmark_data/attribute/3dbag_partial.fcb",
),
)];
pub fn read_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("read");
group.sample_size(10);
for &(dataset, (_file_without, file_with)) in DATASETS.iter() {
group.bench_with_input(
BenchmarkId::new(format!("{dataset} with seekable (streamable)"), file_with),
&file_with,
|b, &path| {
b.iter(|| {
read_fcb_with_attr_index_seekable(path).unwrap();
})
},
);
group.bench_with_input(
BenchmarkId::new(
format!("{dataset} with non-seekable (sequential)"),
file_with,
),
&file_with,
|b, &path| {
b.iter(|| {
read_fcb_with_attr_index_non_seekable(path).unwrap();
})
},
);
}
group.finish();
println!("\nBenchmark Results:");
println!("{:<12} {:<25} {:<15}", "Dataset", "Method", "Mean Time");
println!("{:-<52}", "");
}
criterion_group!(benches, read_benchmark);
criterion_main!(benches);