From 79ed8a52671077ef72da7db3b57e78132213c8c6 Mon Sep 17 00:00:00 2001 From: "hinto.janai" <hinto.janai@protonmail.com> Date: Fri, 29 Mar 2024 20:21:17 -0400 Subject: [PATCH] add `{Benchmarker, Config, Stats}` and main() --- database/benchmark/src/benchmarks.rs | 99 ++++++++++++++++++++++++++++ database/benchmark/src/cli.rs | 74 ++++++++++++--------- database/benchmark/src/config.rs | 32 ++++++--- database/benchmark/src/main.rs | 43 ++++++++++-- database/benchmark/src/state.rs | 13 ++++ 5 files changed, 214 insertions(+), 47 deletions(-) create mode 100644 database/benchmark/src/benchmarks.rs create mode 100644 database/benchmark/src/state.rs diff --git a/database/benchmark/src/benchmarks.rs b/database/benchmark/src/benchmarks.rs new file mode 100644 index 00000000..6abead93 --- /dev/null +++ b/database/benchmark/src/benchmarks.rs @@ -0,0 +1,99 @@ +//! TODO + +//---------------------------------------------------------------------------------------------------- Import +use std::{ + borrow::Cow, + collections::BTreeSet, + path::{Path, PathBuf}, +}; + +use serde::{Deserialize, Serialize}; +use strum::{ + Display, EnumCount, EnumIs, EnumIter, EnumString, IntoStaticStr, VariantArray, VariantIterator, +}; + +use cuprate_database::ConcreteEnv; + +use crate::config::Config; + +//---------------------------------------------------------------------------------------------------- TODO +/// TODO +#[derive( + Clone, + Copy, + PartialEq, + PartialOrd, + Ord, + Eq, + Serialize, + Deserialize, + Debug, + Hash, + Display, + EnumCount, + EnumIs, + EnumIter, + EnumString, + IntoStaticStr, + VariantArray, +)] +pub(crate) enum Benchmarks { + /// TODO + EnvOpen, +} + +//---------------------------------------------------------------------------------------------------- Stats +/// TODO +#[derive(Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, Debug)] +struct Stats { + /// TODO + env_open: Option<f32>, +} + +impl Stats { + /// TODO + const fn new() -> Self { + Self { env_open: None } + } +} + +//---------------------------------------------------------------------------------------------------- TODO +/// TODO +pub(crate) struct Benchmarker { + /// TODO + env: ConcreteEnv, + /// TODO + config: Config, + /// TODO + stats: Stats, +} + +//---------------------------------------------------------------------------------------------------- Drop +impl Drop for Benchmarker { + fn drop(&mut self) { + let stats_json = serde_json::to_string_pretty(&self.stats).unwrap(); + println!("{stats_json}"); + } +} + +//---------------------------------------------------------------------------------------------------- Impl +impl Benchmarker { + /// TODO + pub(crate) const fn new(env: ConcreteEnv, config: Config) -> Self { + Self { + env, + config, + stats: Stats::new(), + } + } + + /// TODO + pub(crate) fn bench(self) { + todo!() + } + + /// TODO + pub(crate) fn todo(&mut self) { + println!("TODO"); + } +} diff --git a/database/benchmark/src/cli.rs b/database/benchmark/src/cli.rs index 36420b14..43a2b6a2 100644 --- a/database/benchmark/src/cli.rs +++ b/database/benchmark/src/cli.rs @@ -5,6 +5,8 @@ use std::path::PathBuf; use clap::{crate_name, Args, Parser, Subcommand}; +use cuprate_helper::fs::cuprate_database_dir; + use crate::config::Config; //---------------------------------------------------------------------------------------------------- Constants @@ -16,60 +18,70 @@ use crate::config::Config; /// - parsing/validating input values /// - routing certain `--flags` to function paths (and exiting) /// - possibly handing `Config` back off to `main()` for continued execution -#[derive(Parser)] +#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Parser)] #[allow(clippy::struct_excessive_bools)] pub struct Cli { - //------------------------------------------------------------------------------ TODO + //------------------------------------------------------------------------------ Config options /// Set filter level for console logs. #[arg( long, value_name = "OFF|ERROR|INFO|WARN|DEBUG|TRACE", verbatim_doc_comment )] - log_level: Option<String>, // FIXME: tracing::Level{Filter} doesn't work with clap? + pub(crate) log_level: Option<String>, // FIXME: tracing::Level{Filter} doesn't work with clap? + + /// TODO + #[arg(long, value_name = "PATH", verbatim_doc_comment)] + pub(crate) config: Option<PathBuf>, + + /// TODO + #[arg(long, value_name = "PATH", verbatim_doc_comment)] + pub(crate) db_config: Option<PathBuf>, //------------------------------------------------------------------------------ Early Return - // These are flags that do something - // then immediately return, e.g `--docs`. + // These are flags that do something then immediately return. // // Regardless of other flags provided, these will force a return. #[arg(long, verbatim_doc_comment)] - /// Print the configuration `cuprate` would have used, but don't actually startup + /// Print the configuration `cuprate-database-benchmark` + /// would have used, but don't actually startup. /// /// This will go through the regular process of: - /// - Reading disk for config /// - Reading command-line - /// - Merging options together - /// - Validating options + /// - Reading disk for config /// - /// and then print them out as TOML, and exit. - dry_run: bool, + /// and then print the config out as TOML, and exit. + pub(crate) dry_run: bool, #[arg(long, verbatim_doc_comment)] - /// Print the PATHs used by `cuprate` - /// - /// All data saved by `cuprate` is saved in these directories. - /// For more information, see: <https://TODO> - path: bool, + /// Print the PATH used by `cuprate-database`. + pub(crate) path: bool, #[arg(long, verbatim_doc_comment)] - /// Delete all `cuprate` files that are on disk + /// Delete all `cuprated-database` files that are on disk. /// - /// This deletes all `daemon` Cuprate folders. - /// The PATHs deleted will be printed on success. - delete: bool, + /// This deletes the PATH returned by `--path`, aka, the + /// directory that stores all database related files. + pub(crate) delete: bool, #[arg(short, long)] - /// Print version and exit. - version: bool, + /// Print various stats and exit. + pub(crate) version: bool, } //---------------------------------------------------------------------------------------------------- CLI default -impl Default for Cli { - fn default() -> Self { - todo!() - } -} +// impl Default for Cli { +// fn default() -> Self { +// Self { +// log_level: None, +// db_config: None, +// dry_run: false, +// path: false, +// delete: false, +// version: false, +// } +// } +// } //---------------------------------------------------------------------------------------------------- CLI argument handling impl Cli { @@ -93,20 +105,20 @@ impl Cli { //-------------------------------------------------- Version. if self.version { - println!("TODO"); + todo!(); return Err(0); } //-------------------------------------------------- Path. if self.path { - let p: PathBuf = todo!(); - println!("{}", p.display()); + let path = cuprate_database_dir(); + println!("{}", path.display()); return Err(0); } //-------------------------------------------------- Delete. if self.delete { - let path = cuprate_helper::fs::cuprate_database_dir(); + let path = cuprate_database_dir(); if path.exists() { println!( diff --git a/database/benchmark/src/config.rs b/database/benchmark/src/config.rs index e7d93379..9828a640 100644 --- a/database/benchmark/src/config.rs +++ b/database/benchmark/src/config.rs @@ -3,29 +3,41 @@ //---------------------------------------------------------------------------------------------------- Import use std::{ borrow::Cow, + collections::BTreeSet, path::{Path, PathBuf}, }; +use serde::{Deserialize, Serialize}; +use strum::IntoEnumIterator; + +use crate::{benchmarks::Benchmarks, cli::Cli}; + //---------------------------------------------------------------------------------------------------- Config /// TODO -#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Config {} +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Serialize, Deserialize)] +pub struct Config { + /// TODO + iterations: usize, + /// TODO + benchmark_set: BTreeSet<Benchmarks>, +} impl Config { /// Create a new [`Config`] with sane default settings. - pub fn new() -> Self { + pub(crate) fn new() -> Self { + Self { + iterations: 100_000, + benchmark_set: Benchmarks::iter().collect(), + } + } + + /// TODO + pub(crate) fn merge(&mut self, cli: &Cli) { todo!() } } impl Default for Config { - /// Same as `Self::new(None)`. - /// - /// ```rust - /// # use cuprate_database_benchmark::config::*; - /// assert_eq!(Config::default(), Config::new(None)); - /// ``` fn default() -> Self { Self::new() } diff --git a/database/benchmark/src/main.rs b/database/benchmark/src/main.rs index 5ba79563..01e62766 100644 --- a/database/benchmark/src/main.rs +++ b/database/benchmark/src/main.rs @@ -69,14 +69,18 @@ // Import private modules, export public types. // // Documentation for each module is located in the respective file. +mod benchmarks; mod cli; mod config; mod constants; mod free; +mod state; //---------------------------------------------------------------------------------------------------- Private //---------------------------------------------------------------------------------------------------- Import +use cuprate_database::Env; + use crate::{cli::Cli, config::Config}; //---------------------------------------------------------------------------------------------------- Main @@ -86,13 +90,40 @@ fn main() { // Some arguments were passed, run all the `clap` code. Cli::init() } else { - // No arguments were passed, use the default config. + // No arguments were passed, use the default. Cli::default() }; - // // If `dry_run`, print config/stats/etc and exit cleanly. - // if config.dry_run { - // println!("{}", serde_json::to_string_pretty(CONFIG).unwrap()); - // std::process::exit(0); - // } + // Load the benchmark config. + let config = if let Some(path) = cli.config.as_ref() { + let bytes = std::fs::read(path).unwrap(); + let mut disk: Config = toml_edit::de::from_slice(&bytes).unwrap(); + disk.merge(&cli); + disk + } else { + Config::new() + }; + + // Load the database config. + let db_config = if let Some(path) = cli.db_config { + let bytes = std::fs::read(path).unwrap(); + toml_edit::de::from_slice(&bytes).unwrap() + } else { + cuprate_database::config::Config::new(None) + }; + + // Print config before starting. + println!("{config:#?}"); + + // If `dry_run`, exit cleanly. + if cli.dry_run { + std::process::exit(0); + } + + // Create database. + let env = cuprate_database::ConcreteEnv::open(db_config).unwrap(); + + // Start benchmarking/tests. + let mut benchmarker = crate::benchmarks::Benchmarker::new(env, todo!()); + benchmarker.todo(); } diff --git a/database/benchmark/src/state.rs b/database/benchmark/src/state.rs new file mode 100644 index 00000000..45fa7521 --- /dev/null +++ b/database/benchmark/src/state.rs @@ -0,0 +1,13 @@ +//! TODO + +//---------------------------------------------------------------------------------------------------- Import +use std::{ + borrow::Cow, + path::{Path, PathBuf}, +}; + +//---------------------------------------------------------------------------------------------------- Config +/// TODO +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct State {}