# Scepter
Composable Rust primitives for large-scale time-series routing, indexing,
aggregation, and query planning.
`scepter` is a small library for building observability, metrics, stream
processing, and distributed query systems. It packages the kinds of low-level
building blocks described in the public Monarch paper into independent Rust
APIs: ordered keys, range assignment, field-hint indexes, histogram-like
distributions, collection aggregation, ingest routing, pushdown planning, and
standing-query sharding.
The crate is inspired by Monarch-style system design, but it is not Google
Monarch and does not depend on any Google service or internal API. The name
keeps the theme without claiming ownership: a scepter is the control instrument
of a monarch; this crate focuses on control-plane and data-plane primitives for
distributed time-series systems.
## Use Cases
- Route metric writes to shards by lexicographic target ranges.
- Prune distributed query fanout with compact field-hint indexes.
- Represent and merge distribution-valued metrics with exemplars.
- Turn cumulative points into delta windows.
- Aggregate ingestion streams before storage.
- Split logical query plans into leaf, zone, and root execution fragments.
- Shard periodic standing queries across evaluator workers.
## Install
```sh
cargo add scepter
```
Or add it manually:
```toml
[dependencies]
scepter = "0.1"
```
## Quick Example
```rust
use scepter::{FieldHintIndex, FieldPredicate, RangeAssigner};
let mut ranges = RangeAssigner::new();
ranges.assign(b"a".to_vec()..b"m".to_vec(), "leaf-1")?;
ranges.assign(b"m".to_vec()..b"z".to_vec(), "leaf-2")?;
assert_eq!(ranges.worker_for("latency"), Some(&"leaf-1"));
let mut index = FieldHintIndex::new();
index.insert_value("ComputeTask", "job", "monarch", "leaf-1");
let candidates = index.candidates(
"ComputeTask",
"job",
&FieldPredicate::Equals("monarch".to_owned()),
);
assert!(candidates.contains("leaf-1"));
# Ok::<(), scepter::ShardError>(())
```
## Distribution Metrics
```rust
use scepter::{BucketLayout, Distribution};
let layout = BucketLayout::fixed_width(0.0, 10.0, 3)?;
let mut latency = Distribution::<()>::from_layout(&layout);
latency.record(4.2, 1)?;
latency.record(18.0, 2)?;
assert_eq!(latency.total_count(), 3);
assert!(latency.percentile(99.0)?.is_some());
# Ok::<(), scepter::DistributionError>(())
```
## Primitive Families
`scepter` is organized by concern:
- `key`: ordered key encoding with `LexicographicKey` and `KeyEncoder`.
- `model`: schema-rich time-series types such as `TargetSchema`,
`MetricSchema`, `TimeSeriesKey`, `MetricKind`, and `LocationResolver`.
- `shard`: range assignment, range load scoring, worker lookup, reassignment,
and range splitting.
- `hint`: compact field-hint indexing with trigrams, n-grams, full-string
excerpts, predicates, intersections, and unions.
- `distribution`: bucket layouts, distribution values, exemplars, cumulative
points, percentile estimates, and delta windows.
- `aggregate`: distributed aggregation traits, `Sum`, and
`CollectionAggregator`.
- `ingest`: write envelopes, stale-write drop policy, and range-based ingest
routing.
- `query`: logical plans, execution levels, fanout plans, and pushdown
fragments.
- `standing`: periodic standing queries and stable evaluator sharding.
## Design Principles
- No runtime dependencies for the library itself.
- Recoverable invalid input is returned as `Result`, not exposed as public API
panics.
- `unsafe` is forbidden.
- APIs are small and composable instead of tied to one database runtime.
- Tests include unit tests, property tests, and mutation-regression tests.
## What This Crate Is Not
`scepter` is not a complete time-series database. It does not provide storage,
replication, networking, persistence, query parsing, or a hosted service. It is
the reusable primitive layer you can use while building those systems.
## Test Strategy
Scepter uses three layers of tests:
- Example-sized unit tests live beside each module.
- Property tests in `tests/properties.rs` check invariants over generated
inputs.
- Mutation-regression tests in `tests/mutation_regression.rs` lock down
behavior that mutation testing has proven easy to under-specify.
The current mutation suite catches every viable mutant reported by
`cargo-mutants`.
Quality gates used before publishing:
```sh
cargo fmt --check
cargo test
cargo clippy --all-targets -- -D warnings
cargo audit
cargo deny check advisories bans licenses sources
cargo mutants --timeout 120 --jobs 2
cargo publish --dry-run
```
## License
Licensed under either of:
- Apache License, Version 2.0
- MIT license
at your option.