use reifydb_codec::row::shape::{RowFamily, RowShape};
use reifydb_value::value::{blob::Blob, date::Date, int::Int, uuid::Uuid4, value_type::ValueType};
#[test]
fn test_large_row() {
let field_counts = [10, 50, 100, 200, 500];
for count in field_counts {
let types: Vec<ValueType> = (0..count)
.map(|i| match i % 10 {
0 => ValueType::Boolean,
1 => ValueType::Int1,
2 => ValueType::Int2,
3 => ValueType::Int4,
4 => ValueType::Int8,
5 => ValueType::Float4,
6 => ValueType::Float8,
7 => ValueType::Date,
8 => ValueType::Uuid4,
_ => ValueType::Utf8,
})
.collect();
let shape = RowShape::testing(RowFamily::Pod, &types);
let mut row = shape.allocate_pod();
for i in 0..count {
match i % 10 {
0 => shape.set::<bool>(&mut row, i, true),
1 => shape.set::<i8>(&mut row, i, 42i8),
2 => shape.set::<i16>(&mut row, i, 1234i16),
3 => shape.set::<i32>(&mut row, i, 123456i32),
4 => shape.set::<i64>(&mut row, i, 1234567890i64),
5 => shape.set::<f32>(&mut row, i, 3.14f32),
6 => shape.set::<f64>(&mut row, i, 3.14159f64),
7 => shape.set::<Date>(&mut row, i, Date::from_ymd(2024, 12, 25).unwrap()),
8 => shape.set::<Uuid4>(&mut row, i, Uuid4::generate()),
_ => shape.set_utf8(&mut row, i, "test"),
}
}
for i in 0..count {
match i % 10 {
0 => {
shape.get::<bool>(&row, i);
}
1 => {
shape.get::<i8>(&row, i);
}
2 => {
shape.get::<i16>(&row, i);
}
3 => {
shape.get::<i32>(&row, i);
}
4 => {
shape.get::<i64>(&row, i);
}
5 => {
shape.get::<f32>(&row, i);
}
6 => {
shape.get::<f64>(&row, i);
}
7 => {
shape.get::<Date>(&row, i);
}
8 => {
shape.get::<Uuid4>(&row, i);
}
_ => {
shape.get_utf8(&row, i);
}
}
}
}
}
#[test]
fn test_dynamic_field_reallocation() {
let shape = RowShape::testing(RowFamily::Pod, &[ValueType::Utf8, ValueType::Blob, ValueType::Int]);
let iterations = 1000;
let mut rows = Vec::with_capacity(iterations);
for i in 0..iterations {
let mut row = shape.allocate_pod();
let size = (i % 100) + 1;
let string = "x".repeat(size);
let bytes = vec![0u8; size];
let int = Int::from(i as i64);
shape.set_utf8(&mut row, 0, &string);
shape.set_blob(&mut row, 1, &Blob::from(bytes));
shape.set_int(&mut row, 2, &int);
assert_eq!(shape.get_utf8(&row, 0).len(), size);
assert_eq!(shape.get_blob(&row, 1).len(), size);
rows.push(row);
}
for (i, row) in rows.iter().enumerate().step_by(100) {
let expected_size = (i % 100) + 1;
assert_eq!(shape.get_utf8(row, 0).len(), expected_size);
assert_eq!(shape.get_blob(row, 1).len(), expected_size);
assert_eq!(shape.get_int(row, 2), Int::from(i as i64));
}
}
#[test]
fn test_memory_efficiency() {
let shape = RowShape::testing(
RowFamily::Pod,
&[
ValueType::Boolean, ValueType::Int4, ValueType::Float8, ],
);
let row = shape.allocate_pod();
assert!(row.len() < 56, "Static row too large: {} bytes", row.len());
let shape = RowShape::testing(RowFamily::Pod, &[ValueType::Utf8]);
let initial_size = shape.allocate_pod().len();
let mut row1 = shape.allocate_pod();
shape.set_utf8(&mut row1, 0, "short");
let small_size = row1.len();
let mut row2 = shape.allocate_pod();
shape.set_utf8(&mut row2, 0, &"x".repeat(1000));
let large_size = row2.len();
assert!(small_size > initial_size, "Dynamic field didn't grow");
assert!(large_size > small_size, "Dynamic field didn't grow for larger data");
assert!(large_size < 1200, "Dynamic field used too much memory");
let sizes = [10, 100, 500, 1000];
let mut row_sizes = Vec::new();
for size in sizes {
let mut row = shape.allocate_pod();
shape.set_utf8(&mut row, 0, &"x".repeat(size));
row_sizes.push(row.len());
}
for i in 1..row_sizes.len() {
assert!(row_sizes[i] >= row_sizes[i - 1], "Row size should increase with content size");
}
}