optify 1.2.0

Simplifies getting the right configuration options for a process using pre-loaded configurations from files (JSON, YAML, etc.) to manage options for experiments or flights. This library is mainly made to support building implementations for other languages such as Node.js, Python, and Ruby. It is not meant to be consumed directly yet.
Documentation
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use optify::provider::{CacheOptions, GetOptionsPreferences, OptionsProvider, OptionsRegistry};

fn get_simple_provider() -> OptionsProvider {
    OptionsProvider::build("../../tests/test_suites/simple/configs").unwrap()
}

fn benchmark_cache_vs_no_cache(c: &mut Criterion) {
    let provider = get_simple_provider();
    let cache_options = CacheOptions {};

    let mut group = c.benchmark_group("cache_performance");
    let features_a = ["a"];

    // Benchmark without caching
    group.bench_function("get_all_options/no_cache", |b| {
        b.iter(|| {
            let _ = provider
                .get_all_options(black_box(&features_a), None, None)
                .unwrap();
        })
    });

    // Benchmark with caching (should be faster after first call)
    group.bench_function("get_all_options/with_cache", |b| {
        // Pre-populate cache
        let _ = provider
            .get_all_options(&features_a, Some(&cache_options), None)
            .unwrap();

        b.iter(|| {
            let _ = provider
                .get_all_options(black_box(&features_a), Some(&cache_options), None)
                .unwrap();
        })
    });

    // Benchmark specific config retrieval without cache
    group.bench_function("specific_config/no_cache", |b| {
        b.iter(|| {
            let _ = provider
                .get_options_with_preferences(
                    black_box("myConfig"),
                    black_box(&features_a),
                    None,
                    None,
                )
                .unwrap();
        })
    });

    // Benchmark specific config retrieval with cache
    group.bench_function("specific_config/with_cache", |b| {
        // Pre-populate cache
        let _ = provider
            .get_options_with_preferences("myConfig", &features_a, Some(&cache_options), None)
            .unwrap();

        b.iter(|| {
            let _ = provider
                .get_options_with_preferences(
                    black_box("myConfig"),
                    black_box(&features_a),
                    Some(&cache_options),
                    None,
                )
                .unwrap();
        })
    });

    group.finish();
}

fn benchmark_cache_with_preferences(c: &mut Criterion) {
    let features_a = ["a"];
    let provider = get_simple_provider();
    let cache_options = CacheOptions {};

    let mut group = c.benchmark_group("cache_with_preferences");

    // Benchmark without caching
    group.bench_function("no_cache_with_preferences", |b| {
        let mut preferences = GetOptionsPreferences::new();
        preferences.skip_feature_name_conversion = false;

        b.iter(|| {
            let _ = provider
                .get_all_options(black_box(&features_a), None, Some(&preferences))
                .unwrap();
        })
    });

    // Benchmark with caching and preferences (cache hit)
    group.bench_function("cache_hit_with_preferences", |b| {
        let mut preferences = GetOptionsPreferences::new();
        preferences.skip_feature_name_conversion = false;

        // Pre-populate cache
        let _ = provider
            .get_all_options(&features_a, Some(&cache_options), Some(&preferences))
            .unwrap();

        b.iter(|| {
            let _ = provider
                .get_all_options(
                    black_box(&features_a),
                    Some(&cache_options),
                    Some(&preferences),
                )
                .unwrap();
        })
    });

    group.finish();
}

fn benchmark_cache_multiple_features(c: &mut Criterion) {
    let features_a_b = ["a", "b"];
    let provider = get_simple_provider();
    let cache_options = CacheOptions {};

    let mut group = c.benchmark_group("cache_multiple_features");

    // Benchmark without caching for multiple features
    group.bench_function("no_cache_multiple_features", |b| {
        b.iter(|| {
            let _ = provider
                .get_all_options(black_box(&features_a_b), None, None)
                .unwrap();
        })
    });

    // Benchmark with caching for multiple features (cache hit)
    group.bench_function("cache_hit_multiple_features", |b| {
        // Pre-populate cache
        let _ = provider
            .get_all_options(&features_a_b, Some(&cache_options), None)
            .unwrap();

        b.iter(|| {
            let _ = provider
                .get_all_options(black_box(&features_a_b), Some(&cache_options), None)
                .unwrap();
        })
    });

    group.finish();
}

fn benchmark_cache_performance_scaling(c: &mut Criterion) {
    let features_a = ["a"];
    let provider = get_simple_provider();
    let cache_options = CacheOptions {};

    let mut group = c.benchmark_group("cache_performance_scaling");

    // Benchmark repeated calls without caching
    group.bench_function("repeated_calls_no_cache", |b| {
        b.iter(|| {
            for _ in 0..10 {
                let _ = provider
                    .get_all_options(black_box(&features_a), None, None)
                    .unwrap();
            }
        })
    });

    // Benchmark repeated calls with caching (should show significant improvement)
    group.bench_function("repeated_calls_with_cache", |b| {
        // Pre-populate cache
        let _ = provider
            .get_all_options(&features_a, Some(&cache_options), None)
            .unwrap();

        b.iter(|| {
            for _ in 0..10 {
                let _ = provider
                    .get_all_options(black_box(&features_a), Some(&cache_options), None)
                    .unwrap();
            }
        })
    });

    group.finish();
}

criterion_group!(
    benches,
    benchmark_cache_vs_no_cache,
    benchmark_cache_with_preferences,
    benchmark_cache_multiple_features,
    benchmark_cache_performance_scaling
);
criterion_main!(benches);