Crate tiny_counter

Crate tiny_counter 

Source
Expand description

Track event counts across multiple time windows with fixed memory and fast queries.

This library solves the problem of tracking events (like user actions, API calls, or system events) when you need to answer questions like “how many times did this happen in the last week?” without storing every individual timestamp.

§Key Features

  • Fixed memory: Each event uses ~2KB regardless of event count
  • Multiple time windows: Query at different granularities (minutes, hours, days, weeks, months, years)
  • Fast queries: All queries run in O(buckets) time, independent of event count
  • Persistence: Save to SQLite, JSON, or custom storage backends
  • Merge-friendly: Combine event data from multiple sources for distributed systems

§Quick Start

use tiny_counter::EventStore;
use chrono::Duration;

let mut store = EventStore::new();

// Record events
store.record("app_launch");
store.record("app_launch");

// Query last 7 days
let launches = store
    .query("app_launch")
    .last_days(7)
    .sum()
    .unwrap_or(0);

assert_eq!(launches, 2);

§Recording Events

Record events that just happened:

let mut store = EventStore::new();
store.record("button_click");
store.record_count("api_call", 5);

Record events from the past:

let mut store = EventStore::new();
let timestamp = Utc::now() - Duration::days(2);
store.record_at("feature_used", timestamp).unwrap();
store.record_ago("sync", Duration::hours(3));

§Querying Events

Query event counts across different time ranges:

let mut store = EventStore::new();
store.record("app_launch");

// Different time granularities
let last_hour = store.query("app_launch").last_minutes(60).sum().unwrap();
let last_day = store.query("app_launch").last_hours(24).sum().unwrap();
let last_week = store.query("app_launch").last_days(7).sum().unwrap();

§Rate Limiting

Enforce rate limits with multiple constraints:

let mut store = EventStore::new();

let result = store
    .limit()
    .at_most("api_call", 10, TimeUnit::Minutes)
    .at_most("api_call", 100, TimeUnit::Hours)
    .check_and_record("api_call");

assert!(result.is_ok());

§Persistence

Save and load event data (requires serde feature with a storage backend like storage-fs):

let mut store = EventStore::builder()
    .with_storage(MemoryStorage::new())
    .build()
    .unwrap();

store.record("event");
store.persist().unwrap();

Re-exports§

pub use formatter::Formatter;

Modules§

formatter
Serialization format abstraction.
storage

Structs§

DeltaQuery
Builder for calculating deltas (net changes) between two events.
DeltaRangeQuery
Range query for delta calculations.
EventStore
Top-level store for tracking multiple events with automatic counter creation.
EventStoreBuilder
Builder for creating an EventStore with custom configuration.
LimitExceeded
Error returned when a rate limit is exceeded.
LimitUsage
Usage information for a rate limit constraint.
Limiter
Fluent builder for rate limiting with multiple constraints.
MultiQuery
Builder for querying multiple events.
MultiRangeQuery
Range query over multiple events.
Query
Builder for constructing queries on a single event.
RangeQuery
Builder for querying a specific time range.
RatioQuery
Builder for calculating ratios between two events.
Reservation
A reservation for a rate-limited event.
SystemClock
Clock implementations for time abstraction.
TestClock
Test clock that allows manual time control for testing.
TimeWindow
Represents a time window for rate limiting constraints.

Enums§

Constraint
A rate limiting constraint.
Error
Error types for the event-counter library.
Schedule
A time-based schedule for constraint checking.
TimeUnit
Time unit definitions for interval configuration.

Traits§

Clock
Clock trait for abstracting time operations.
EventId
A generic event id trait for type-safe event identification.
Storage
Storage backend trait for persisting event data.

Type Aliases§

Result
Convenience type for Results in this library.