structured-zstd 0.0.49

Pure Rust zstd implementation — managed fork of ruzstd. Dictionary decompression, no FFI.
Documentation
use super::*;
use std::format;

fn corpus() -> Vec<u8> {
    let mut data = Vec::new();
    for i in 0..500u32 {
        data.extend_from_slice(
            format!("tenant=demo table=orders key={i} region=eu payload=aaaaabbbbbccccdddd\n")
                .as_bytes(),
        );
    }
    data
}

#[test]
fn fastcover_raw_produces_non_empty_dict() {
    let sample = corpus();
    let dict = train_fastcover_raw(
        sample.as_slice(),
        4096,
        FastCoverParams {
            k: 256,
            d: 8,
            f: 20,
            accel: 1,
        },
    );
    assert!(!dict.is_empty());
    assert!(dict.len() <= 4096);
}

#[test]
fn fastcover_raw_returns_empty_for_empty_or_zero_budget() {
    let sample = corpus();
    let params = FastCoverParams {
        k: 256,
        d: 8,
        f: 20,
        accel: 1,
    };
    assert!(train_fastcover_raw(&[], 1024, params).is_empty());
    assert!(train_fastcover_raw(sample.as_slice(), 0, params).is_empty());
}

#[test]
fn fastcover_optimizer_selects_valid_params() {
    let sample = corpus();
    let (dict, tuned) = optimize_fastcover_raw(
        sample.as_slice(),
        4096,
        0.75,
        1,
        &[6, 8],
        &[18, 20],
        &[128, 256],
    );
    assert!(!dict.is_empty());
    assert!([6, 8].contains(&tuned.d));
    assert!([18, 20].contains(&tuned.f));
    assert!([128, 256].contains(&tuned.k));
}

#[test]
fn fastcover_optimizer_falls_back_when_k_candidates_empty() {
    let sample = corpus();
    let (dict, tuned) =
        optimize_fastcover_raw(sample.as_slice(), 4096, 0.75, 1, &[6, 8], &[18, 20], &[]);
    assert!(!dict.is_empty());
    assert!(DEFAULT_K_CANDIDATES.contains(&tuned.k));
}

#[test]
fn fastcover_optimizer_handles_one_byte_sample_without_panic() {
    let sample = [0xAB];
    let (dict, tuned) = optimize_fastcover_raw(&sample, 16, 0.75, 1, &[], &[], &[]);
    assert!(!dict.is_empty());
    assert!(dict.len() <= 16);
    assert!(DEFAULT_K_CANDIDATES.contains(&tuned.k));
    assert!(DEFAULT_D_CANDIDATES.contains(&tuned.d));
    assert!(DEFAULT_F_CANDIDATES.contains(&tuned.f));
}

#[test]
fn fastcover_optimizer_seeds_winner_when_all_scores_are_zero() {
    let sample = b"abcdefghijklmnopqrst";
    let (dict, tuned) = optimize_fastcover_raw(sample, 16, 0.9, 1, &[6], &[16], &[8]);
    assert!(!dict.is_empty());
    assert_eq!(tuned.k, 16);
    assert_eq!(tuned.d, 6);
    assert_eq!(tuned.f, 16);
    assert_eq!(tuned.score, 0);
}

#[test]
fn fastcover_optimizer_handles_zero_dict_budget() {
    let sample = corpus();
    let (dict, tuned) = optimize_fastcover_raw(
        sample.as_slice(),
        0,
        0.75,
        1,
        &[6, 8],
        &[18, 20],
        &[128, 256],
    );
    assert!(dict.is_empty());
    assert!([6, 8].contains(&tuned.d));
    assert!([18, 20].contains(&tuned.f));
    assert!([128, 256].contains(&tuned.k));
}

#[test]
fn fastcover_optimizer_clamps_extreme_split_points() {
    let sample = corpus();
    let (dict_low, tuned_low) =
        optimize_fastcover_raw(sample.as_slice(), 2048, 0.0, 1, &[6], &[18], &[128]);
    let (dict_high, tuned_high) =
        optimize_fastcover_raw(sample.as_slice(), 2048, 1.0, 1, &[6], &[18], &[128]);
    assert!(!dict_low.is_empty());
    assert!(!dict_high.is_empty());
    assert_eq!(tuned_low.k, 128);
    assert_eq!(tuned_high.k, 128);
}

#[test]
fn fastcover_optimizer_reports_normalized_params() {
    let sample = corpus();
    let (dict, tuned) =
        optimize_fastcover_raw(sample.as_slice(), 1024, 0.75, 1, &[64], &[42], &[8]);
    assert!(!dict.is_empty());
    assert_eq!(tuned.d, 32);
    assert_eq!(tuned.f, 20);
    assert_eq!(tuned.k, 32);
}