tiny-counter 0.1.0

Track event counts across time windows with fixed memory and fast queries
Documentation
// Resource tracking and capacity management.
//
// This example shows how to:
// - Track resource allocation/deallocation (connections, tasks, etc.)
// - Calculate current resource usage with query_delta
// - Enforce capacity limits
// - Balance opposing events

use tiny_counter::{EventId, EventStore};

// Resource management events
#[derive(Debug, Clone, Copy)]
enum ResourceEvent {
    ConnectionOpen,
    ConnectionClose,
    TaskStart,
    TaskComplete,
}

impl AsRef<str> for ResourceEvent {
    fn as_ref(&self) -> &str {
        match self {
            ResourceEvent::ConnectionOpen => "resource:connection:open",
            ResourceEvent::ConnectionClose => "resource:connection:close",
            ResourceEvent::TaskStart => "resource:task:start",
            ResourceEvent::TaskComplete => "resource:task:complete",
        }
    }
}

impl EventId for ResourceEvent {}

fn main() {
    println!("=== Resource Tracking Examples ===\n");

    // 1. Connection pool tracking
    println!("1. Connection pool tracking:");
    let store = EventStore::new();

    // Open some connections
    store.record_count(ResourceEvent::ConnectionOpen, 5);
    println!("  Opened 5 connections");

    // Close some connections
    store.record_count(ResourceEvent::ConnectionClose, 2);
    println!("  Closed 2 connections");

    // Current open connections (delta)
    let open_connections = store
        .query_delta(
            ResourceEvent::ConnectionOpen,
            ResourceEvent::ConnectionClose,
        )
        .ever()
        .sum();

    println!("  Current open connections: {}\n", open_connections.max(0));

    // 2. Capacity enforcement
    println!("2. Enforcing capacity limits:");
    let store = EventStore::new();

    // Open connections up to limit
    for i in 1..=12 {
        let current = store
            .query_delta(
                ResourceEvent::ConnectionOpen,
                ResourceEvent::ConnectionClose,
            )
            .ever()
            .sum()
            .max(0);

        if current < 10 {
            store.record(ResourceEvent::ConnectionOpen);
            println!(
                "  Connection {}: ✓ Opened (capacity: {}/10)",
                i,
                current + 1
            );
        } else {
            println!("  Connection {}: ✗ Pool exhausted (10/10)", i);
        }
    }

    // 3. Task tracking
    println!("\n3. Task tracking:");
    let store = EventStore::new();

    // Start several tasks
    store.record_count(ResourceEvent::TaskStart, 8);
    println!("  Started 8 tasks");

    // Complete some tasks
    store.record_count(ResourceEvent::TaskComplete, 5);
    println!("  Completed 5 tasks");

    // Current running tasks
    let running_tasks = store
        .query_delta(ResourceEvent::TaskStart, ResourceEvent::TaskComplete)
        .ever()
        .sum()
        .max(0);

    println!("  Currently running: {} tasks", running_tasks);

    // Historical view
    let total_started = store
        .query(ResourceEvent::TaskStart)
        .ever()
        .sum()
        .unwrap_or(0);
    let total_completed = store
        .query(ResourceEvent::TaskComplete)
        .ever()
        .sum()
        .unwrap_or(0);

    println!(
        "  Historical: {} started, {} completed\n",
        total_started, total_completed
    );

    // 4. Time-windowed resource usage
    println!("4. Resource usage over time:");
    let store = EventStore::new();

    // Simulate activity
    for _ in 0..20 {
        store.record(ResourceEvent::ConnectionOpen);
    }
    for _ in 0..15 {
        store.record(ResourceEvent::ConnectionClose);
    }

    println!("  Simulated connection activity");

    // Check usage at different time scales
    let last_hour = store
        .query_delta(
            ResourceEvent::ConnectionOpen,
            ResourceEvent::ConnectionClose,
        )
        .last_hours(1)
        .sum()
        .max(0);

    let last_day = store
        .query_delta(
            ResourceEvent::ConnectionOpen,
            ResourceEvent::ConnectionClose,
        )
        .last_days(1)
        .sum()
        .max(0);

    let all_time = store
        .query_delta(
            ResourceEvent::ConnectionOpen,
            ResourceEvent::ConnectionClose,
        )
        .ever()
        .sum()
        .max(0);

    println!("  Net change last hour: {}", last_hour);
    println!("  Net change last day: {}", last_day);
    println!("  Net change all time: {}\n", all_time);

    // 5. Balancing deltas
    println!("5. Balancing operations:");
    let store = EventStore::new();

    // Create imbalance
    store.record_count(ResourceEvent::TaskStart, 100);
    store.record_count(ResourceEvent::TaskComplete, 30);

    let before = store
        .query_delta(ResourceEvent::TaskStart, ResourceEvent::TaskComplete)
        .ever()
        .sum();

    println!("  Started 100 tasks, completed 30");
    println!("  Delta before balance: {}", before);

    // Balance to zero
    store
        .balance_delta(ResourceEvent::TaskStart, ResourceEvent::TaskComplete)
        .unwrap();

    let after = store
        .query_delta(ResourceEvent::TaskStart, ResourceEvent::TaskComplete)
        .ever()
        .sum();

    println!("  After balancing: {}", after);
    println!("  (Added {} completions to balance)\n", before);

    // 6. Capacity monitoring with alerts
    println!("6. Capacity monitoring:");
    let store = EventStore::new();

    // Simulate load
    for i in 1..=8 {
        store.record(ResourceEvent::ConnectionOpen);

        let current = store
            .query_delta(
                ResourceEvent::ConnectionOpen,
                ResourceEvent::ConnectionClose,
            )
            .ever()
            .sum()
            .max(0);

        let capacity = 10;
        let utilization = (current as f64 / capacity as f64) * 100.0;

        print!(
            "  Connection {}: {} open ({:.0}% utilization)",
            i, current, utilization
        );

        if utilization >= 80.0 {
            print!(" ⚠️ High utilization!");
        }
        println!();
    }

    println!("\n✓ Resource tracking complete!");
}