import { type Entry } from '../entry/entry.js';
import { type TimeseriesReport } from './timeseries.js';
export interface LatencyStats {
    count: number;
    p50: number;
    p95: number;
    p99: number;
    max: number;
    slow: number;
}
export interface FamilyLatency {
    familyHash: string;
    label: string;
    count: number;
    p50: number;
    p99: number;
}
export interface CacheStats {
    hits: number;
    misses: number;
    sets: number;
    deletes: number;
    hitRatio: number;
    topKeys: {
        key: string;
        count: number;
    }[];
    /** Gets served from a stale/grace value (subset of `hits`). Caches without a
     *  stale-while-revalidate concept leave this 0. */
    staleHits: number;
    /** Per-tier hit/miss split for layered caches (e.g. `l1`/`l2`). Empty `{}` for
     *  single-tier caches that don't report a tier. */
    byTier: Record<string, {
        hits: number;
        misses: number;
    }>;
}
export interface StatusBreakdown {
    '2xx': number;
    '3xx': number;
    '4xx': number;
    '5xx': number;
    other: number;
}
export interface ExceptionGroupStats {
    /** The family key — the entry's `familyHash` when present, else `${class}: ${message}`. */
    key: string;
    class: string;
    message: string;
    count: number;
    /** Most recent occurrence in the window. */
    lastAt: Date;
    /** Per-bucket occurrence counts, aligned to the report's `overTime` buckets. */
    overTime: number[];
}
export interface StatsResult {
    type: string;
    windowMs: number;
    total: number;
    /** Throughput over the window — reuses {@link bucketTimeseries}. */
    overTime: TimeseriesReport;
    /** Present for types whose entries carry a `durationMs`. */
    latency?: LatencyStats;
    /** Query only: top families by p99. */
    families?: FamilyLatency[];
    /** Cache only. */
    cache?: CacheStats;
    /** Request only. */
    status?: StatusBreakdown;
    /** Exception only: top groups by class+message, with count, last-seen, over-time. */
    exceptions?: ExceptionGroupStats[];
    /** Caller-supplied: whether the scan hit its cap. */
    truncated: boolean;
}
/** Pre-estimated p50/p95/p99 (ms), supplied by a rollup-backed caller to replace
 *  the raw-scan percentiles in {@link LatencyStats}. count/max/slow stay raw. */
export interface LatencyPercentilesOverride {
    p50: number;
    p95: number;
    p99: number;
}
export interface SummarizeStatsInput {
    entries: Entry[];
    type: string;
    windowStart: Date;
    windowEnd: Date;
    windowMs: number;
    buckets: number;
    slowMs: number;
    truncated: boolean;
    topFamilies?: number;
    topKeys?: number;
    topExceptions?: number;
    /** When provided, p50/p95/p99 in the latency block are taken from these
     *  rollup-histogram estimates instead of the raw-scan computation. The latency
     *  block's count/max/slow remain raw-derived. */
    latencyPercentiles?: LatencyPercentilesOverride;
}
/** Nearest-rank percentile over a NON-EMPTY ascending array; 0 for empty.
 *  `q` in [0,1]; `idx = clamp(ceil(q*n)-1, 0, n-1)`. */
export declare function percentile(sortedAscending: number[], q: number): number;
/** Aggregate a window of entries into per-type analytics: latency percentiles,
 *  query-family breakdown, cache hit/miss, request status breakdown, and a
 *  throughput time-series. Pure: callers fetch the windowed entries and supply
 *  the window bounds + `truncated` flag. */
export declare function summarizeStats(input: SummarizeStatsInput): StatsResult;
//# sourceMappingURL=stats.d.ts.map