#![allow(dead_code)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum SchemaKind {
S1Narrow,
S2Wide,
}
pub const N_WIDE_DOUBLES: usize = 5;
pub const N_WIDE_SYMS: usize = 5;
impl SchemaKind {
pub fn parse(s: &str) -> Option<Self> {
match s {
"s1-narrow" => Some(SchemaKind::S1Narrow),
"s2-wide" => Some(SchemaKind::S2Wide),
_ => None,
}
}
pub fn name(self) -> &'static str {
match self {
SchemaKind::S1Narrow => "s1-narrow",
SchemaKind::S2Wide => "s2-wide",
}
}
pub fn table(self) -> &'static str {
match self {
SchemaKind::S1Narrow => "bench_s1_narrow",
SchemaKind::S2Wide => "bench_s2_wide",
}
}
pub fn columns(self) -> usize {
match self {
SchemaKind::S1Narrow => 5,
SchemaKind::S2Wide => 5 + N_WIDE_DOUBLES + N_WIDE_SYMS,
}
}
pub fn is_wide(self) -> bool {
matches!(self, SchemaKind::S2Wide)
}
pub fn create_table_sql(self) -> &'static str {
match self {
SchemaKind::S1Narrow => {
"CREATE TABLE bench_s1_narrow (\
id LONG, price DOUBLE, sym SYMBOL, note VARCHAR, ts TIMESTAMP\
) TIMESTAMP(ts) PARTITION BY HOUR WAL DEDUP UPSERT KEYS(ts)"
}
SchemaKind::S2Wide => {
"CREATE TABLE bench_s2_wide (\
id LONG, price DOUBLE, sym SYMBOL, note VARCHAR, \
d1 DOUBLE, d2 DOUBLE, d3 DOUBLE, d4 DOUBLE, d5 DOUBLE, \
s1 SYMBOL CAPACITY 200000, s2 SYMBOL CAPACITY 200000, \
s3 SYMBOL CAPACITY 200000, s4 SYMBOL CAPACITY 200000, \
s5 SYMBOL CAPACITY 200000, ts TIMESTAMP\
) TIMESTAMP(ts) PARTITION BY HOUR WAL DEDUP UPSERT KEYS(ts)"
}
}
}
pub fn select_sql(self) -> &'static str {
match self {
SchemaKind::S1Narrow => "SELECT ts, id, price, sym, note FROM bench_s1_narrow",
SchemaKind::S2Wide => {
"SELECT ts, id, price, sym, note, \
d1, d2, d3, d4, d5, s1, s2, s3, s4, s5 FROM bench_s2_wide"
}
}
}
}
pub fn note_template_count(rows: usize) -> usize {
rows.clamp(1, 1024)
}
pub fn note_template(idx: usize, varchar_len: usize) -> String {
format!("note_{idx:03}_")
.repeat(varchar_len)
.chars()
.take(varchar_len)
.collect()
}
pub fn wide_double(i: usize, k: usize) -> f64 {
i as f64 * (0.5 + k as f64)
}
pub fn sym_label(v: usize) -> String {
format!("sym_{v:04}")
}
pub fn hi_sym_label(col: usize, v: usize) -> String {
format!("s{}_{:06}", col - 1, v)
}
#[allow(dead_code)] pub fn sym_pool(card: usize) -> Vec<String> {
(0..card).map(sym_label).collect()
}
#[allow(dead_code)]
pub fn hi_sym_pools(card: usize) -> Vec<Vec<String>> {
(1..=N_WIDE_SYMS)
.map(|col| (0..card).map(|v| hi_sym_label(col, v)).collect())
.collect()
}
#[allow(dead_code)] pub fn sender_ranges(rows: usize, senders: usize) -> Vec<(usize, usize)> {
let n = senders.max(1);
let ranges: Vec<(usize, usize)> = (0..n).map(|k| (rows * k / n, rows * (k + 1) / n)).collect();
assert_eq!(ranges[0].0, 0, "first range must start at 0");
assert_eq!(ranges[n - 1].1, rows, "last range must end at rows");
for pair in ranges.windows(2) {
assert_eq!(pair[0].1, pair[1].0, "ranges must tile without gaps");
}
ranges
}