mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-19 01:24:20 +01:00
minor changes, add maximum time bound to the simulator, fix bug in the table create shadowing
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
use std::{
|
use std::{iter::Sum, ops::SubAssign};
|
||||||
iter::Sum,
|
|
||||||
ops::{Add, Sub, SubAssign},
|
|
||||||
};
|
|
||||||
|
|
||||||
use anarchist_readable_name_generator_lib::readable_name_custom;
|
use anarchist_readable_name_generator_lib::readable_name_custom;
|
||||||
use rand::{distributions::uniform::SampleUniform, Rng};
|
use rand::{distributions::uniform::SampleUniform, Rng};
|
||||||
@@ -48,7 +45,7 @@ pub(crate) fn one_of<'a, T, R: rand::Rng>(
|
|||||||
choices[index](rng)
|
choices[index](rng)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn pick<'a, T, R: rand::Rng>(choices: &'a Vec<T>, rng: &mut R) -> &'a T {
|
pub(crate) fn pick<'a, T, R: rand::Rng>(choices: &'a [T], rng: &mut R) -> &'a T {
|
||||||
let index = rng.gen_range(0..choices.len());
|
let index = rng.gen_range(0..choices.len());
|
||||||
&choices[index]
|
&choices[index]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ impl Interactions {
|
|||||||
match interaction {
|
match interaction {
|
||||||
Interaction::Query(query) => match query {
|
Interaction::Query(query) => match query {
|
||||||
Query::Create(create) => {
|
Query::Create(create) => {
|
||||||
env.tables.push(create.table.clone());
|
if !env.tables.iter().any(|t| t.name == create.table.name) {
|
||||||
|
env.tables.push(create.table.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Query::Insert(insert) => {
|
Query::Insert(insert) => {
|
||||||
let table = env
|
let table = env
|
||||||
@@ -175,7 +177,7 @@ impl ArbitraryFrom<SimulatorEnv> for InteractionPlan {
|
|||||||
rng: ChaCha8Rng::seed_from_u64(rng.next_u64()),
|
rng: ChaCha8Rng::seed_from_u64(rng.next_u64()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let num_interactions = rng.gen_range(0..env.opts.max_interactions);
|
let num_interactions = env.opts.max_interactions;
|
||||||
|
|
||||||
// First create at least one table
|
// First create at least one table
|
||||||
let create_query = Create::arbitrary(rng);
|
let create_query = Create::arbitrary(rng);
|
||||||
|
|||||||
@@ -121,6 +121,15 @@ fn main() {
|
|||||||
// Move the old database and plan file back
|
// Move the old database and plan file back
|
||||||
std::fs::rename(&old_db_path, &db_path).unwrap();
|
std::fs::rename(&old_db_path, &db_path).unwrap();
|
||||||
std::fs::rename(&old_plan_path, &plan_path).unwrap();
|
std::fs::rename(&old_plan_path, &plan_path).unwrap();
|
||||||
|
} else if let Ok(result) = result {
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
log::info!("simulation completed successfully");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("simulation failed: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Print the seed, the locations of the database and the plan file at the end again for easily accessing them.
|
// Print the seed, the locations of the database and the plan file at the end again for easily accessing them.
|
||||||
println!("database path: {:?}", db_path);
|
println!("database path: {:?}", db_path);
|
||||||
@@ -150,12 +159,26 @@ fn run_simulation(
|
|||||||
(create_percent, read_percent, write_percent, delete_percent)
|
(create_percent, read_percent, write_percent, delete_percent)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if cli_opts.minimum_size < 1 {
|
||||||
|
return Err(limbo_core::LimboError::InternalError(
|
||||||
|
"minimum size must be at least 1".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if cli_opts.maximum_size < 1 {
|
if cli_opts.maximum_size < 1 {
|
||||||
panic!("maximum size must be at least 1");
|
return Err(limbo_core::LimboError::InternalError(
|
||||||
|
"maximum size must be at least 1".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if cli_opts.maximum_size < cli_opts.minimum_size {
|
||||||
|
return Err(limbo_core::LimboError::InternalError(
|
||||||
|
"maximum size must be greater than or equal to minimum size".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let opts = SimulatorOpts {
|
let opts = SimulatorOpts {
|
||||||
ticks: rng.gen_range(1..=cli_opts.maximum_size),
|
ticks: rng.gen_range(cli_opts.minimum_size..=cli_opts.maximum_size),
|
||||||
max_connections: 1, // TODO: for now let's use one connection as we didn't implement
|
max_connections: 1, // TODO: for now let's use one connection as we didn't implement
|
||||||
// correct transactions procesing
|
// correct transactions procesing
|
||||||
max_tables: rng.gen_range(0..128),
|
max_tables: rng.gen_range(0..128),
|
||||||
@@ -164,7 +187,8 @@ fn run_simulation(
|
|||||||
write_percent,
|
write_percent,
|
||||||
delete_percent,
|
delete_percent,
|
||||||
page_size: 4096, // TODO: randomize this too
|
page_size: 4096, // TODO: randomize this too
|
||||||
max_interactions: rng.gen_range(1..=cli_opts.maximum_size),
|
max_interactions: rng.gen_range(cli_opts.minimum_size..=cli_opts.maximum_size),
|
||||||
|
max_time_simulation: cli_opts.maximum_time,
|
||||||
};
|
};
|
||||||
let io = Arc::new(SimulatorIO::new(seed, opts.page_size).unwrap());
|
let io = Arc::new(SimulatorIO::new(seed, opts.page_size).unwrap());
|
||||||
|
|
||||||
@@ -212,12 +236,19 @@ fn run_simulation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn execute_plans(env: &mut SimulatorEnv, plans: &mut [InteractionPlan]) -> Result<()> {
|
fn execute_plans(env: &mut SimulatorEnv, plans: &mut [InteractionPlan]) -> Result<()> {
|
||||||
|
let now = std::time::Instant::now();
|
||||||
// todo: add history here by recording which interaction was executed at which tick
|
// todo: add history here by recording which interaction was executed at which tick
|
||||||
for _tick in 0..env.opts.ticks {
|
for _tick in 0..env.opts.ticks {
|
||||||
// Pick the connection to interact with
|
// Pick the connection to interact with
|
||||||
let connection_index = pick_index(env.connections.len(), &mut env.rng);
|
let connection_index = pick_index(env.connections.len(), &mut env.rng);
|
||||||
// Execute the interaction for the selected connection
|
// Execute the interaction for the selected connection
|
||||||
execute_plan(env, connection_index, plans)?;
|
execute_plan(env, connection_index, plans)?;
|
||||||
|
// Check if the maximum time for the simulation has been reached
|
||||||
|
if now.elapsed().as_secs() >= env.opts.max_time_simulation as u64 {
|
||||||
|
return Err(limbo_core::LimboError::InternalError(
|
||||||
|
"maximum time for simulation reached".into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -15,10 +15,24 @@ pub struct SimulatorCLI {
|
|||||||
)]
|
)]
|
||||||
pub doublecheck: bool,
|
pub doublecheck: bool,
|
||||||
#[clap(
|
#[clap(
|
||||||
short,
|
short = 'n',
|
||||||
long,
|
long,
|
||||||
help = "change the maximum size of the randomly generated sequence of interactions",
|
help = "change the maximum size of the randomly generated sequence of interactions",
|
||||||
default_value_t = 1024
|
default_value_t = 1024
|
||||||
)]
|
)]
|
||||||
pub maximum_size: usize,
|
pub maximum_size: usize,
|
||||||
|
#[clap(
|
||||||
|
short = 'k',
|
||||||
|
long,
|
||||||
|
help = "change the minimum size of the randomly generated sequence of interactions",
|
||||||
|
default_value_t = 1
|
||||||
|
)]
|
||||||
|
pub minimum_size: usize,
|
||||||
|
#[clap(
|
||||||
|
short = 't',
|
||||||
|
long,
|
||||||
|
help = "change the maximum time of the simulation(in seconds)",
|
||||||
|
default_value_t = 60 * 60 // default to 1 hour
|
||||||
|
)]
|
||||||
|
pub maximum_time: usize,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,4 +36,5 @@ pub(crate) struct SimulatorOpts {
|
|||||||
pub(crate) delete_percent: f64,
|
pub(crate) delete_percent: f64,
|
||||||
pub(crate) max_interactions: usize,
|
pub(crate) max_interactions: usize,
|
||||||
pub(crate) page_size: usize,
|
pub(crate) page_size: usize,
|
||||||
|
pub(crate) max_time_simulation: usize,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user