tegdb 0.5.0

The name TegridyDB (short for TegDB) is inspired by the Tegridy Farm in South Park and tries to correct some of the wrong database implementations, such as null support, implicit conversion support, etc.
Documentation
use std::collections::HashMap;
use std::time::Instant;
use tegdb::storage_format::StorageFormat;
use tegdb::{ColumnConstraint, ColumnInfo, DataType, SqlValue, TableSchema};

fn main() {
    println!("=== TegDB Fixed-Length Storage Format Performance Demo ===\n");

    // Create a test schema with fixed-length columns
    let mut schema = TableSchema {
        name: "users".to_string(),
        columns: vec![
            ColumnInfo {
                name: "id".to_string(),
                data_type: DataType::Integer,
                constraints: vec![ColumnConstraint::PrimaryKey],
                storage_offset: 0,
                storage_size: 8,
                storage_type_code: 1,
            },
            ColumnInfo {
                name: "name".to_string(),
                data_type: DataType::Text(None),
                constraints: vec![],
                storage_offset: 8,
                storage_size: 32,
                storage_type_code: 2,
            },
            ColumnInfo {
                name: "email".to_string(),
                data_type: DataType::Text(None),
                constraints: vec![],
                storage_offset: 40,
                storage_size: 64,
                storage_type_code: 2,
            },
        ],
        indexes: vec![], // Initialize indexes as empty
    };
    let _ = tegdb::catalog::Catalog::compute_table_metadata(&mut schema);

    let storage = StorageFormat::new();

    // Calculate record size
    let record_size = storage.get_record_size(&schema).unwrap();
    println!("📏 Record size: {record_size} bytes (predictable!)");
    println!("📊 Layout: 3x Integer (24 bytes) + 2x Text (150 bytes) = 174 bytes\n");

    // Create test data
    let test_row = {
        let mut row = HashMap::new();
        row.insert("id".to_string(), SqlValue::Integer(12345));
        row.insert("name".to_string(), SqlValue::Text("John Doe".to_string()));
        row.insert(
            "email".to_string(),
            SqlValue::Text("john.doe@example.com".to_string()),
        );
        row.insert("age".to_string(), SqlValue::Integer(30));
        row.insert("score".to_string(), SqlValue::Real(95.5));
        row
    };

    // Benchmark 1: Serialization
    println!("🚀 Benchmarking Serialization...");
    let iterations = 1_000_000;

    let start = Instant::now();
    for _ in 0..iterations {
        let _serialized = storage.serialize_row(&test_row, &schema).unwrap();
    }
    let serialization_time = start.elapsed();

    let serialized_data = storage.serialize_row(&test_row, &schema).unwrap();
    println!("   ✅ Serialized {iterations} rows in {serialization_time:?}");
    println!(
        "   ⚡ Average: {:?} per row",
        serialization_time / iterations
    );

    // Benchmark 2: Deserialization
    println!("\n🔄 Benchmarking Deserialization...");
    let start = Instant::now();
    for _ in 0..iterations {
        let _deserialized = storage
            .deserialize_row_full(&serialized_data, &schema)
            .unwrap();
    }
    let deserialization_time = start.elapsed();

    println!("   ✅ Deserialized {iterations} rows in {deserialization_time:?}");
    println!(
        "   ⚡ Average: {:?} per row",
        deserialization_time / iterations
    );

    // Benchmark 3: Partial Column Access
    println!("\n🎯 Benchmarking Partial Column Access...");
    let column_names = ["id".to_string(), "name".to_string()];
    let column_refs: Vec<&str> = column_names.iter().map(|s| s.as_str()).collect();

    let start = Instant::now();
    for _ in 0..iterations {
        let _values = storage
            .get_columns(&serialized_data, &schema, &column_refs)
            .unwrap();
    }
    let partial_time = start.elapsed();

    println!("   ✅ Accessed {iterations} partial columns in {partial_time:?}");
    println!("   ⚡ Average: {:?} per access", partial_time / iterations);

    // Benchmark 4: Single Column Access
    println!("\n🎯 Benchmarking Single Column Access...");
    let start = Instant::now();
    for _ in 0..iterations {
        let _value = storage
            .get_column_by_index(&serialized_data, &schema, 0)
            .unwrap();
    }
    let single_time = start.elapsed();

    println!("   ✅ Accessed {iterations} single columns in {single_time:?}");
    println!("   ⚡ Average: {:?} per access", single_time / iterations);

    // Benchmark 5: Large Dataset Simulation
    println!("\n📊 Benchmarking Large Dataset...");
    let mut large_schema = TableSchema {
        name: "large_table".to_string(),
        columns: vec![
            ColumnInfo {
                name: "id".to_string(),
                data_type: DataType::Integer,
                constraints: vec![ColumnConstraint::PrimaryKey],
                storage_offset: 0,
                storage_size: 0,
                storage_type_code: 0,
            },
            ColumnInfo {
                name: "data1".to_string(),
                data_type: DataType::Text(Some(200)),
                constraints: vec![],
                storage_offset: 0,
                storage_size: 0,
                storage_type_code: 0,
            },
            ColumnInfo {
                name: "data2".to_string(),
                data_type: DataType::Text(Some(200)),
                constraints: vec![],
                storage_offset: 0,
                storage_size: 0,
                storage_type_code: 0,
            },
            ColumnInfo {
                name: "value1".to_string(),
                data_type: DataType::Integer,
                constraints: vec![],
                storage_offset: 0,
                storage_size: 0,
                storage_type_code: 0,
            },
            ColumnInfo {
                name: "value2".to_string(),
                data_type: DataType::Real,
                constraints: vec![],
                storage_offset: 0,
                storage_size: 0,
                storage_type_code: 0,
            },
        ],
        indexes: vec![], // Initialize indexes as empty
    };
    let _ = tegdb::catalog::Catalog::compute_table_metadata(&mut large_schema);

    let large_row = {
        let mut row = HashMap::new();
        row.insert("id".to_string(), SqlValue::Integer(999999));
        row.insert(
            "data1".to_string(),
            SqlValue::Text("A".to_string().repeat(150)),
        );
        row.insert(
            "data2".to_string(),
            SqlValue::Text("B".to_string().repeat(150)),
        );
        row.insert("value1".to_string(), SqlValue::Integer(123456));
        row.insert("value2".to_string(), SqlValue::Real(987.654));
        row
    };

    let large_record_size = storage.get_record_size(&large_schema).unwrap();
    println!("   📏 Large record size: {large_record_size} bytes");

    let large_iterations = 100_000;
    let start = Instant::now();
    for _ in 0..large_iterations {
        let _serialized = storage.serialize_row(&large_row, &large_schema).unwrap();
    }
    let large_serialization_time = start.elapsed();

    let large_serialized = storage.serialize_row(&large_row, &large_schema).unwrap();
    let start = Instant::now();
    for _ in 0..large_iterations {
        let _deserialized = storage
            .deserialize_row_full(&large_serialized, &large_schema)
            .unwrap();
    }
    let large_deserialization_time = start.elapsed();

    println!(
        "   ✅ Large serialization: {:?} per row",
        large_serialization_time / large_iterations
    );
    println!(
        "   ✅ Large deserialization: {:?} per row",
        large_deserialization_time / large_iterations
    );

    // Performance Summary
    println!();
    println!("{}", "=".repeat(60));
    println!("📈 PERFORMANCE SUMMARY");
    println!("{}", "=".repeat(60));
    println!(
        "🔹 Serialization:     {:?} per row",
        serialization_time / iterations
    );
    println!(
        "🔹 Deserialization:   {:?} per row",
        deserialization_time / iterations
    );
    println!(
        "🔹 Partial Access:    {:?} per access",
        partial_time / iterations
    );
    println!(
        "🔹 Single Column:     {:?} per access",
        single_time / iterations
    );
    println!(
        "🔹 Large Records:     {:?} per row",
        large_serialization_time / large_iterations
    );
    println!();
    println!("🚀 This demonstrates NANOSECOND-level performance!");
    println!("💡 Fixed-length format enables:");
    println!("   • Direct offset-based access");
    println!("   • Zero-copy deserialization");
    println!("   • Predictable memory layout");
    println!("   • Maximum cache efficiency");
}