mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-07 18:24:20 +01:00
Merge 'Fix non-determinism in simulator ' from Pedro Muniz
Use IndexSet for order preserving iteration instead of HashSet Closes #2934
This commit is contained in:
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -1800,9 +1800,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.10.0"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
||||
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
@@ -1822,7 +1822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"indexmap 2.10.0",
|
||||
"indexmap 2.11.0",
|
||||
"is-terminal",
|
||||
"itoa",
|
||||
"log",
|
||||
@@ -2192,7 +2192,7 @@ dependencies = [
|
||||
"env_logger 0.10.2",
|
||||
"garde",
|
||||
"hex",
|
||||
"indexmap 2.10.0",
|
||||
"indexmap 2.11.0",
|
||||
"itertools 0.14.0",
|
||||
"json5",
|
||||
"log",
|
||||
@@ -2774,7 +2774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"indexmap 2.10.0",
|
||||
"indexmap 2.11.0",
|
||||
"quick-xml 0.32.0",
|
||||
"serde",
|
||||
"time",
|
||||
@@ -3672,6 +3672,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"garde",
|
||||
"hex",
|
||||
"indexmap 2.11.0",
|
||||
"itertools 0.14.0",
|
||||
"rand 0.9.2",
|
||||
"rand_chacha 0.9.0",
|
||||
@@ -4064,7 +4065,7 @@ version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
|
||||
dependencies = [
|
||||
"indexmap 2.10.0",
|
||||
"indexmap 2.11.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -4086,7 +4087,7 @@ version = "0.22.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
|
||||
dependencies = [
|
||||
"indexmap 2.10.0",
|
||||
"indexmap 2.11.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -4371,7 +4372,7 @@ dependencies = [
|
||||
"cc",
|
||||
"env_logger 0.11.7",
|
||||
"fallible-iterator",
|
||||
"indexmap 2.10.0",
|
||||
"indexmap 2.11.0",
|
||||
"log",
|
||||
"memchr",
|
||||
"miette",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fmt::{Debug, Display},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
vec,
|
||||
};
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use sql_generation::{
|
||||
@@ -166,13 +166,13 @@ impl Interactions {
|
||||
}
|
||||
|
||||
impl Interactions {
|
||||
pub(crate) fn dependencies(&self) -> HashSet<String> {
|
||||
pub(crate) fn dependencies(&self) -> IndexSet<String> {
|
||||
match self {
|
||||
Interactions::Property(property) => {
|
||||
property
|
||||
.interactions()
|
||||
.iter()
|
||||
.fold(HashSet::new(), |mut acc, i| match i {
|
||||
.fold(IndexSet::new(), |mut acc, i| match i {
|
||||
Interaction::Query(q) => {
|
||||
acc.extend(q.dependencies());
|
||||
acc
|
||||
@@ -181,7 +181,7 @@ impl Interactions {
|
||||
})
|
||||
}
|
||||
Interactions::Query(query) => query.dependencies(),
|
||||
Interactions::Fault(_) => HashSet::new(),
|
||||
Interactions::Fault(_) => IndexSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::{collections::HashSet, fmt::Display};
|
||||
use std::fmt::Display;
|
||||
|
||||
use anyhow::Context;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sql_generation::model::{
|
||||
@@ -32,19 +33,19 @@ pub enum Query {
|
||||
}
|
||||
|
||||
impl Query {
|
||||
pub fn dependencies(&self) -> HashSet<String> {
|
||||
pub fn dependencies(&self) -> IndexSet<String> {
|
||||
match self {
|
||||
Query::Select(select) => select.dependencies(),
|
||||
Query::Create(_) => HashSet::new(),
|
||||
Query::Create(_) => IndexSet::new(),
|
||||
Query::Insert(Insert::Select { table, .. })
|
||||
| Query::Insert(Insert::Values { table, .. })
|
||||
| Query::Delete(Delete { table, .. })
|
||||
| Query::Update(Update { table, .. })
|
||||
| Query::Drop(Drop { table, .. }) => HashSet::from_iter([table.clone()]),
|
||||
| Query::Drop(Drop { table, .. }) => IndexSet::from_iter([table.clone()]),
|
||||
Query::CreateIndex(CreateIndex { table_name, .. }) => {
|
||||
HashSet::from_iter([table_name.clone()])
|
||||
IndexSet::from_iter([table_name.clone()])
|
||||
}
|
||||
Query::Begin(_) | Query::Commit(_) | Query::Rollback(_) => HashSet::new(),
|
||||
Query::Begin(_) | Query::Commit(_) | Query::Rollback(_) => IndexSet::new(),
|
||||
}
|
||||
}
|
||||
pub fn uses(&self) -> Vec<String> {
|
||||
|
||||
@@ -185,59 +185,6 @@ impl SimulatorEnv {
|
||||
) -> Self {
|
||||
let mut rng = ChaCha8Rng::seed_from_u64(seed);
|
||||
|
||||
let total = 100.0;
|
||||
|
||||
let mut create_percent = 0.0;
|
||||
let mut create_index_percent = 0.0;
|
||||
let mut drop_percent = 0.0;
|
||||
let mut delete_percent = 0.0;
|
||||
let mut update_percent = 0.0;
|
||||
|
||||
let read_percent = rng.random_range(0.0..=total);
|
||||
let write_percent = total - read_percent;
|
||||
|
||||
if !cli_opts.disable_create {
|
||||
// Create percent should be 5-15% of the write percent
|
||||
create_percent = rng.random_range(0.05..=0.15) * write_percent;
|
||||
}
|
||||
if !cli_opts.disable_create_index {
|
||||
// Create indexpercent should be 2-5% of the write percent
|
||||
create_index_percent = rng.random_range(0.02..=0.05) * write_percent;
|
||||
}
|
||||
if !cli_opts.disable_drop {
|
||||
// Drop percent should be 2-5% of the write percent
|
||||
drop_percent = rng.random_range(0.02..=0.05) * write_percent;
|
||||
}
|
||||
if !cli_opts.disable_delete {
|
||||
// Delete percent should be 10-20% of the write percent
|
||||
delete_percent = rng.random_range(0.1..=0.2) * write_percent;
|
||||
}
|
||||
if !cli_opts.disable_update {
|
||||
// Update percent should be 10-20% of the write percent
|
||||
// TODO: freestyling the percentage
|
||||
update_percent = rng.random_range(0.1..=0.2) * write_percent;
|
||||
}
|
||||
|
||||
let write_percent = write_percent
|
||||
- create_percent
|
||||
- create_index_percent
|
||||
- delete_percent
|
||||
- drop_percent
|
||||
- update_percent;
|
||||
|
||||
let summed_total: f64 = read_percent
|
||||
+ write_percent
|
||||
+ create_percent
|
||||
+ create_index_percent
|
||||
+ drop_percent
|
||||
+ update_percent
|
||||
+ delete_percent;
|
||||
|
||||
let abs_diff = (summed_total - total).abs();
|
||||
if abs_diff > 0.0001 {
|
||||
panic!("Summed total {summed_total} is not equal to total {total}");
|
||||
}
|
||||
|
||||
let opts = SimulatorOpts {
|
||||
seed,
|
||||
ticks: rng.random_range(cli_opts.minimum_tests..=cli_opts.maximum_tests),
|
||||
|
||||
@@ -21,6 +21,7 @@ anyhow = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
garde = { workspace = true, features = ["derive", "serde"] }
|
||||
indexmap = { version = "2.11.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = "0.9.0"
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::model::query::select::{
|
||||
use crate::model::query::update::Update;
|
||||
use crate::model::query::{Create, CreateIndex, Delete, Drop, Insert, Select};
|
||||
use crate::model::table::{JoinTable, JoinType, JoinedTable, SimValue, Table, TableContext};
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools;
|
||||
use rand::Rng;
|
||||
use turso_parser::ast::{Expr, SortOrder};
|
||||
@@ -104,7 +105,7 @@ impl Arbitrary for SelectInner {
|
||||
if order_by_col_count == 0 {
|
||||
return None;
|
||||
}
|
||||
let mut col_names = std::collections::HashSet::new();
|
||||
let mut col_names = IndexSet::new();
|
||||
let mut order_by_cols = Vec::new();
|
||||
while order_by_cols.len() < order_by_col_count {
|
||||
let table = pick(&order_by_table_candidates, rng);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use rand::Rng;
|
||||
use turso_core::Value;
|
||||
|
||||
@@ -28,7 +27,7 @@ impl Arbitrary for Table {
|
||||
} else {
|
||||
rng.random_range(opts.column_range)
|
||||
} as usize;
|
||||
let mut column_set = HashSet::with_capacity(column_size);
|
||||
let mut column_set = IndexSet::with_capacity(column_size);
|
||||
for col in std::iter::repeat_with(|| Column::arbitrary(rng, context)) {
|
||||
column_set.insert(col);
|
||||
if column_set.len() == column_size {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::{collections::HashSet, fmt::Display};
|
||||
use std::fmt::Display;
|
||||
|
||||
pub use ast::Distinctness;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use turso_parser::ast::{
|
||||
@@ -105,12 +106,12 @@ impl Select {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dependencies(&self) -> HashSet<String> {
|
||||
pub fn dependencies(&self) -> IndexSet<String> {
|
||||
if self.body.select.from.is_none() {
|
||||
return HashSet::new();
|
||||
return IndexSet::new();
|
||||
}
|
||||
let from = self.body.select.from.as_ref().unwrap();
|
||||
let mut tables = HashSet::new();
|
||||
let mut tables = IndexSet::new();
|
||||
tables.insert(from.table.clone());
|
||||
|
||||
tables.extend(from.dependencies());
|
||||
|
||||
Reference in New Issue
Block a user