#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::time::Duration;
use chronix::prelude::*;
use chronix::{Chronix, fields, tags};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let dir = tempfile::tempdir()?;
let config = ChronixConfig::builder().data_dir(dir.path()).build()?;
let db = Chronix::open(config)?;
let base_ts = 1_700_000_000_000_000_000_i64;
let hosts = [
("web-01", "us-east"),
("web-02", "us-east"),
("db-01", "eu-west"),
];
for (host, region) in &hosts {
let key = SeriesKey::new(
"http_requests",
tags! { "host" => *host, "region" => *region },
)?;
let points: Vec<Point> = (0..60)
.map(|i| {
let value = 100.0 + (i as f64).sin() * 50.0;
Point::new(
key.clone(),
fields! { "count" => value, "latency_ms" => value * 0.1 },
base_ts + i * 1_000_000_000,
)
.unwrap()
})
.collect();
assert!(
db.insert_batch(&points)?.is_complete(),
"insert was partial"
);
}
println!("✅ Seeded 180 points (3 hosts × 60 samples)");
println!("\n─── 1. Scan: http_requests where host=web-01 ───");
let plan = db
.query()
.measurement("http_requests")
.tag("host", "web-01")
.field("count")
.range(base_ts, base_ts + 10_000_000_000)
.build()?;
let batch = db.execute(&plan)?;
println!(" {} rows", batch.num_rows());
arrow::util::pretty::print_batches(&[batch])?;
println!("\n─── 2. Aggregate: avg/min/max of count for web-01 ───");
let plan = db
.query()
.measurement("http_requests")
.tag("host", "web-01")
.field("count")
.range(base_ts, base_ts + 60_000_000_000)
.aggregate(AggFn::Avg)
.aggregate(AggFn::Min)
.aggregate(AggFn::Max)
.build()?;
let batch = db.execute(&plan)?;
arrow::util::pretty::print_batches(&[batch])?;
println!("\n─── 3. Downsample: 10s buckets, avg(count) for db-01 ───");
let plan = db
.query()
.measurement("http_requests")
.tag("host", "db-01")
.field("count")
.range(base_ts, base_ts + 60_000_000_000)
.downsample(TimeBucket::fixed(Duration::from_secs(10)), AggFn::Avg)
.build()?;
let batch = db.execute(&plan)?;
println!(" {} buckets", batch.num_rows());
arrow::util::pretty::print_batches(&[batch])?;
db.flush()?;
let day_later = base_ts + 86_400_000_000_000;
let key = SeriesKey::new(
"http_requests",
tags! { "host" => "web-01", "region" => "us-east" },
)?;
let later: Vec<Point> = (0..60)
.map(|i| {
Point::new(
key.clone(),
fields! { "count" => 42.0, "latency_ms" => 4.2 },
day_later + i * 1_000_000_000,
)
.unwrap()
})
.collect();
assert!(db.insert_batch(&later)?.is_complete());
db.flush()?;
println!("\n─── 4. Execute with pruning statistics ───");
let plan = db
.query()
.measurement("http_requests")
.tag("host", "web-02")
.range(base_ts, base_ts + 30_000_000_000)
.build()?;
let (batch, stats) = db.execute_with_stats(&plan)?;
println!(" Rows returned : {}", batch.num_rows());
println!(" Segments total : {}", stats.segments_total);
println!(" Pruned by time : {}", stats.pruned_by_time);
println!(" Pruned by bloom : {}", stats.pruned_by_bloom);
println!(" Pruned by stats : {}", stats.pruned_by_stats);
println!(" Segments remaining : {}", stats.segments_remaining);
println!(" Total pruned : {}", stats.total_pruned());
db.close()?;
println!("\n✅ Done");
Ok(())
}