asap_sketchlib 0.2.1

A high-performance sketching library for approximate stream processing
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
// @generated by tools/gen-proto -- DO NOT EDIT.
//
// Regenerate with:
//     cargo run --manifest-path tools/gen-proto/Cargo.toml
//
// Source of truth: proto/**/*.proto

// This file is @generated by prost-build.
/// ProducerInfo records which library version created this envelope.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ProducerInfo {
    /// One of "sketchlib-go" or "asap_sketchlib".
    #[prost(string, tag = "1")]
    pub library: ::prost::alloc::string::String,
    /// Semantic version string of the producing library, e.g. "0.1.0".
    #[prost(string, tag = "2")]
    pub version: ::prost::alloc::string::String,
}
/// HashSpec fully describes the hashing configuration so both sides can confirm
/// they will compute identical bucket indices.
///
/// Both libraries share:
///    canonical_seed_index = 5  (CanonicalHashSeed / CANONICAL_HASH_SEED)
///    seed_list            = the 20-entry table in hash.go / hash.rs
///    seed_derivation      = ADDITIVE_OFFSET for per-row seeds
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct HashSpec {
    /// Hash algorithm used for all sketch operations.
    #[prost(enumeration = "HashAlgorithm", tag = "1")]
    pub algorithm: i32,
    /// Index into seed_list used as the primary (canonical) hash seed.
    /// Both libraries default to 5.
    #[prost(uint32, tag = "2")]
    pub canonical_seed_index: u32,
    /// Complete seed table. Must be identical on both sides for correct results.
    /// Both libraries currently use exactly 20 seeds; producers always emit all 20.
    #[prost(uint64, repeated, tag = "3")]
    pub seed_list: ::prost::alloc::vec::Vec<u64>,
    /// How per-row seeds are derived from the base seed index.
    #[prost(enumeration = "SeedDerivation", tag = "4")]
    pub seed_derivation: i32,
}
/// HashAlgorithm enumerates supported hash algorithms.
/// Only XXH3_64 is cross-language stable for the current implementation.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum HashAlgorithm {
    Unspecified = 0,
    /// xxHash3 64-bit with seed (zeebo/xxh3 in Go; twox-hash XxHash3_64 in Rust).
    /// This is the standard algorithm for both libraries.
    Xxh364 = 1,
    /// xxHash3 128-bit with seed. Used for HLL register indexing and packed matrix
    /// hashes that exceed 64 bits.
    Xxh3128 = 2,
    /// xxHash 64-bit (non-XXH3). Reserved for legacy data; not produced by either
    /// current library.
    Xxhash64 = 3,
}
impl HashAlgorithm {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "HASH_ALGORITHM_UNSPECIFIED",
            Self::Xxh364 => "HASH_ALGORITHM_XXH3_64",
            Self::Xxh3128 => "HASH_ALGORITHM_XXH3_128",
            Self::Xxhash64 => "HASH_ALGORITHM_XXHASH64",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "HASH_ALGORITHM_UNSPECIFIED" => Some(Self::Unspecified),
            "HASH_ALGORITHM_XXH3_64" => Some(Self::Xxh364),
            "HASH_ALGORITHM_XXH3_128" => Some(Self::Xxh3128),
            "HASH_ALGORITHM_XXHASH64" => Some(Self::Xxhash64),
            _ => None,
        }
    }
}
/// SeedDerivation describes how per-row seed indices are produced.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum SeedDerivation {
    Unspecified = 0,
    /// Each row r uses seed_list\[(base + r) % len(seed_list)\].
    /// Standard derivation for multi-row sketches (CountMin, CountSketch).
    AdditiveOffset = 1,
    /// All rows share a single hash (Packed64 or Packed128 fast-path).
    /// Applicable only when the total bit-width fits in 64 or 128 bits.
    Packed = 2,
}
impl SeedDerivation {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "SEED_DERIVATION_UNSPECIFIED",
            Self::AdditiveOffset => "SEED_DERIVATION_ADDITIVE_OFFSET",
            Self::Packed => "SEED_DERIVATION_PACKED",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "SEED_DERIVATION_UNSPECIFIED" => Some(Self::Unspecified),
            "SEED_DERIVATION_ADDITIVE_OFFSET" => Some(Self::AdditiveOffset),
            "SEED_DERIVATION_PACKED" => Some(Self::Packed),
            _ => None,
        }
    }
}
/// CounterType identifies the numeric type used to store matrix counters.
/// Go defaults to FLOAT64; Rust defaults to INT32.
/// Determines which counts_* array is populated in CountMinState and
/// CountSketchState.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum CounterType {
    Unspecified = 0,
    /// Rust default for CountMin / CountSketch.
    Int32 = 1,
    Int64 = 2,
    /// INT128 is stored as pairs of int64 (hi, lo) interleaved in counts_int.
    Int128 = 3,
    /// Go default for CountMin / CountSketch.
    Float64 = 4,
}
impl CounterType {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "COUNTER_TYPE_UNSPECIFIED",
            Self::Int32 => "COUNTER_TYPE_INT32",
            Self::Int64 => "COUNTER_TYPE_INT64",
            Self::Int128 => "COUNTER_TYPE_INT128",
            Self::Float64 => "COUNTER_TYPE_FLOAT64",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "COUNTER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
            "COUNTER_TYPE_INT32" => Some(Self::Int32),
            "COUNTER_TYPE_INT64" => Some(Self::Int64),
            "COUNTER_TYPE_INT128" => Some(Self::Int128),
            "COUNTER_TYPE_FLOAT64" => Some(Self::Float64),
            _ => None,
        }
    }
}
/// CountMinState is the portable state of a Count-Min Sketch.
///
/// The counter matrix is stored flat in row-major order:
///    element [r][c] is at index r * cols + c.
///
/// The Go implementation tracks auxiliary sum/L1/L2 arrays that the Rust
/// implementation does not produce. These fields are optional; consumers
/// that need them must recompute from raw insertions if absent.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CountMinState {
    /// Matrix dimensions. Both must be > 0.
    #[prost(uint32, tag = "1")]
    pub rows: u32,
    #[prost(uint32, tag = "2")]
    pub cols: u32,
    /// Indicates which counts_* field below is populated.
    #[prost(enumeration = "CounterType", tag = "3")]
    pub counter_type: i32,
    /// Integer counters in row-major order, length = rows * cols.
    /// Populated when counter_type ∈ {INT32, INT64}.
    /// Use sint64 for efficient varint encoding of near-zero values.
    /// For INT128 counters, values are interleaved as (hi_i, lo_i) pairs,
    /// making the effective length 2 * rows * cols.
    #[prost(sint64, repeated, tag = "4")]
    pub counts_int: ::prost::alloc::vec::Vec<i64>,
    /// Floating-point counters in row-major order, length = rows * cols.
    /// Populated when counter_type = FLOAT64 (Go producer).
    #[prost(double, repeated, tag = "5")]
    pub counts_float: ::prost::alloc::vec::Vec<f64>,
    /// Sum-weighted counter matrix (same layout as counts_*), length = rows * cols.
    #[prost(double, repeated, tag = "6")]
    pub sum_counts: ::prost::alloc::vec::Vec<f64>,
    /// Sum-of-squares counter matrix, length = rows * cols.
    #[prost(double, repeated, tag = "7")]
    pub sum2_counts: ::prost::alloc::vec::Vec<f64>,
    /// Per-row L1 norms, length = rows.
    #[prost(double, repeated, tag = "8")]
    pub l1: ::prost::alloc::vec::Vec<f64>,
    /// Per-row L2 norms, length = rows. Recompute if absent.
    #[prost(double, repeated, tag = "9")]
    pub l2: ::prost::alloc::vec::Vec<f64>,
}
/// CountSketchState is the portable state of a Count (±1) Sketch.
///
/// The counter matrix is signed because Count Sketch uses ±1 increments.
/// The matrix layout is identical to CountMinState (row-major, flat).
///
/// L2 norms are derived values and must be recomputed on load:
///    l2\[r\] = sqrt( sum_c counts[r][c]^2 )
/// Producers may include them as a convenience for consumers that only query.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CountSketchState {
    /// Matrix dimensions. Both must be > 0.
    #[prost(uint32, tag = "1")]
    pub rows: u32,
    #[prost(uint32, tag = "2")]
    pub cols: u32,
    /// Indicates which counts_* field below is populated.
    #[prost(enumeration = "CounterType", tag = "3")]
    pub counter_type: i32,
    /// Signed integer counters in row-major order, length = rows * cols.
    /// Populated when counter_type ∈ {INT32, INT64}.
    #[prost(sint64, repeated, tag = "4")]
    pub counts_int: ::prost::alloc::vec::Vec<i64>,
    /// Floating-point counters in row-major order, length = rows * cols.
    /// Populated when counter_type = FLOAT64 (Go producer).
    #[prost(double, repeated, tag = "5")]
    pub counts_float: ::prost::alloc::vec::Vec<f64>,
    /// Per-row L2 norms, length = rows. Derived — recompute on load if absent.
    #[prost(double, repeated, tag = "6")]
    pub l2: ::prost::alloc::vec::Vec<f64>,
    /// Optional heavy-hitter (TopK min-heap) state.
    /// Absent when TopK tracking is disabled.
    #[prost(message, optional, tag = "7")]
    pub topk: ::core::option::Option<TopKState>,
}
/// TopKState is the serialized state of a min-heap heavy-hitter tracker.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TopKState {
    /// Maximum number of entries retained.
    #[prost(uint32, tag = "1")]
    pub k: u32,
    /// All retained entries. Order is not guaranteed (heap order is not preserved).
    #[prost(message, repeated, tag = "2")]
    pub entries: ::prost::alloc::vec::Vec<HeapEntry>,
}
/// HeapEntry is one heavy-hitter record inside a TopKState.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct HeapEntry {
    /// String key identifying the heavy hitter (e.g. flow ID, IP address).
    /// For binary keys, producers should use base64 or hex encoding and document
    /// their choice; a future bytes_key field is reserved at number 3.
    #[prost(string, tag = "1")]
    pub key: ::prost::alloc::string::String,
    /// Approximate frequency or weight accumulated for this key.
    #[prost(double, tag = "2")]
    pub count: f64,
}
/// HyperLogLogState is the portable state of a HyperLogLog cardinality sketch.
///
/// Precision p determines the register count: num_registers = 2^precision.
/// Both libraries default to precision = 14 (16 384 registers).
///
/// The variant field is required because the three estimator algorithms are
/// not interchangeable: loading an ErtlMLE state into a Regular estimator
/// (or vice versa) produces incorrect cardinality estimates.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct HyperLogLogState {
    /// HLL estimator variant. Required.
    #[prost(enumeration = "HllVariant", tag = "1")]
    pub variant: i32,
    /// Logâ‚‚ of the number of registers (precision parameter p).
    /// Default = 14 → 16 384 registers.
    #[prost(uint32, tag = "2")]
    pub precision: u32,
    /// Raw register values, length = 2^precision.
    /// Each byte stores the maximum (leading-zeros + 1) seen for that bucket.
    /// Stored as a raw byte string for compact encoding (1 byte per register).
    #[prost(bytes = "vec", tag = "3")]
    pub registers: ::prost::alloc::vec::Vec<u8>,
    /// HIP accumulator component kxq0.
    #[prost(double, tag = "4")]
    pub hip_kxq0: f64,
    /// HIP accumulator component kxq1.
    #[prost(double, tag = "5")]
    pub hip_kxq1: f64,
    /// HIP running cardinality estimate.
    #[prost(double, tag = "6")]
    pub hip_est: f64,
}
/// HLLVariant identifies which HLL estimator algorithm the registers belong to.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum HllVariant {
    Unspecified = 0,
    /// Classic HLL with bias-correction tables (Flajolet et al. 2007).
    Regular = 1,
    /// Otmar Ertl's MLE estimator (arXiv:1702.01284).
    /// Originally derived from Apache DataFusion's HLL implementation.
    /// Not compatible with REGULAR registers.
    ErtlMle = 2,
    /// Kevin Lang's HyperLogLog++ Improved Proposal (HIP).
    /// Requires hip_kxq0, hip_kxq1, hip_est to be populated.
    Hip = 3,
}
impl HllVariant {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "HLL_VARIANT_UNSPECIFIED",
            Self::Regular => "HLL_VARIANT_REGULAR",
            Self::ErtlMle => "HLL_VARIANT_ERTL_MLE",
            Self::Hip => "HLL_VARIANT_HIP",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "HLL_VARIANT_UNSPECIFIED" => Some(Self::Unspecified),
            "HLL_VARIANT_REGULAR" => Some(Self::Regular),
            "HLL_VARIANT_ERTL_MLE" => Some(Self::ErtlMle),
            "HLL_VARIANT_HIP" => Some(Self::Hip),
            _ => None,
        }
    }
}
/// KLLState is the portable state of a KLL quantile sketch.
///
/// The items array is partitioned into compaction levels by the levels\[\] array:
///    items\[ levels[i\] .. levels\[i+1\] )  are the retained items at level i.
///
/// Derived state that must be recomputed on load (not serialized):
///    capacity_cache  — computed from k, m, and level boundaries.
///    level0_capacity — computed from k and num_levels.
///    top_height      — equals num_levels - 1.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct KllState {
    /// Target compactor capacity k. Must be >= 8.
    #[prost(uint32, tag = "1")]
    pub k: u32,
    /// Minimum compactor size m. Must satisfy 2 <= m <= k.
    #[prost(uint32, tag = "2")]
    pub m: u32,
    /// Number of levels currently in use.
    #[prost(uint32, tag = "3")]
    pub num_levels: u32,
    /// Level boundary indices into items\[\], length = num_levels + 1.
    /// levels\[0\] is always 0; levels\[num_levels\] = len(items).
    #[prost(uint32, repeated, tag = "4")]
    pub levels: ::prost::alloc::vec::Vec<u32>,
    /// All retained samples in level order, length = levels\[num_levels\].
    #[prost(double, repeated, tag = "5")]
    pub items: ::prost::alloc::vec::Vec<f64>,
    /// Random bit generator state for deterministic compaction continuation.
    /// Required for sketches that will receive further updates after loading.
    /// Consumers that only query may ignore this field.
    #[prost(message, optional, tag = "6")]
    pub coin: ::core::option::Option<CoinState>,
}
/// CoinState is the RNG used by KLL's probabilistic compaction.
/// Both Go and Rust use an identical xorshift-based generator.
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct CoinState {
    /// Xorshift generator internal state word.
    #[prost(uint64, tag = "1")]
    pub state: u64,
    /// Up to 64 random bits buffered for single-bit coin flips.
    #[prost(uint64, tag = "2")]
    pub bit_cache: u64,
    /// Number of valid bits remaining in bit_cache (0–64).
    #[prost(uint32, tag = "3")]
    pub remaining_bits: u32,
}
/// DDSketchState is the portable state of a DDSketch quantile sketch.
///
/// Only alpha is required to reconstruct the index mapping. Consumers must
/// recompute all derived mapping values on load:
///    gamma        = (1.0 + alpha) / (1.0 - alpha)
///    log_gamma    = ln(gamma)
///    inv_log_gamma = 1.0 / log_gamma
///
/// Bucket indices: a value v maps to bucket floor(ln(v) * inv_log_gamma).
/// Stored bucket absolute_index = array_index + store_offset.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DdSketchState {
    /// Relative accuracy guarantee. Required. Must satisfy 0 < alpha < 1.
    #[prost(double, tag = "1")]
    pub alpha: f64,
    /// Bucket count array in index order (ascending absolute bucket index).
    /// Absolute index of store_counts\[i\] is i + store_offset.
    #[prost(uint64, repeated, tag = "2")]
    pub store_counts: ::prost::alloc::vec::Vec<u64>,
    /// Absolute bucket index corresponding to store_counts\[0\].
    /// May be negative (values < 1.0 map to negative bucket indices).
    #[prost(sint32, tag = "3")]
    pub store_offset: i32,
    /// Total number of values added.
    #[prost(uint64, tag = "4")]
    pub count: u64,
    /// Sum of all values added (for mean computation).
    #[prost(double, tag = "5")]
    pub sum: f64,
    /// Minimum value observed. +Inf when the sketch is empty.
    #[prost(double, tag = "6")]
    pub min: f64,
    /// Maximum value observed. -Inf when the sketch is empty.
    #[prost(double, tag = "7")]
    pub max: f64,
}
/// UnivMonState is the portable state of a Universal Monitoring (UnivMon) sketch.
///
/// UnivMon is a hierarchy of L Count Sketches paired with L heavy-hitter heaps.
/// An item's hash trailing-zero count determines which layers receive it, giving
/// each layer a geometrically decreasing sample of the stream.
///
/// All layers share the same sketch dimensions and heap capacity.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UnivMonState {
    /// Number of layers L in the hierarchy (inclusive of all levels).
    #[prost(uint32, tag = "1")]
    pub layer_size: u32,
    /// Count Sketch dimensions shared by all layers.
    #[prost(uint32, tag = "2")]
    pub sketch_rows: u32,
    #[prost(uint32, tag = "3")]
    pub sketch_cols: u32,
    /// Heavy-hitter heap capacity shared by all layers.
    #[prost(uint32, tag = "4")]
    pub heap_size: u32,
    /// Total items inserted across all layers (the "bucket size" counter).
    #[prost(uint64, tag = "5")]
    pub bucket_size: u64,
    /// Per-layer state, in order from layer 0 (finest) to layer_size-1 (coarsest).
    /// Length must equal layer_size.
    #[prost(message, repeated, tag = "6")]
    pub layers: ::prost::alloc::vec::Vec<UnivMonLayer>,
}
/// UnivMonLayer is the joint state of one UnivMon layer.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UnivMonLayer {
    /// The Count Sketch accumulating items at this layer.
    #[prost(message, optional, tag = "1")]
    pub sketch: ::core::option::Option<CountSketchState>,
    /// The heavy-hitter heap for this layer.
    #[prost(message, optional, tag = "2")]
    pub heap: ::core::option::Option<TopKState>,
}
/// HydraState is the portable state of a Hydra multi-sketch framework.
///
/// Hydra maintains a grid of row_num child sketches (cells), each of the
/// same type (counter_type). Items are routed to a specific row cell using a
/// position hash derived from the item's subkey. An optional global "big
/// counter" sketch aggregates the full stream.
///
/// Current implementations set col_num = 1 (one sketch per row). The field is
/// included for schema completeness and future extensions.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct HydraState {
    /// Number of sketch rows (D / number of subpopulations).
    #[prost(uint32, tag = "1")]
    pub row_num: u32,
    /// Number of sketch columns per row. Currently always 1.
    #[prost(uint32, tag = "2")]
    pub col_num: u32,
    /// The sketch type used for every cell.
    #[prost(enumeration = "HydraCounterType", tag = "3")]
    pub counter_type: i32,
    /// Serialized cells in row-major order, length = row_num * col_num.
    /// Each cell's oneof field must match counter_type.
    #[prost(message, repeated, tag = "4")]
    pub cells: ::prost::alloc::vec::Vec<HydraCell>,
    /// Optional global sketch covering the entire stream.
    /// Absent when global counter is disabled (enable_global_counter = false).
    #[prost(message, optional, tag = "5")]
    pub big_counter: ::core::option::Option<HydraCell>,
    /// Seed index used for subpopulation routing (Go: seedHydra, Rust: HYDRA_SEED).
    /// Both libraries default to 6.
    #[prost(uint32, tag = "6")]
    pub seed_index: u32,
    /// True when per-cell TopK tracking is enabled.
    #[prost(bool, tag = "7")]
    pub enable_topk: bool,
    /// True when fanout subkey expansion is active.
    #[prost(bool, tag = "8")]
    pub fanout_subkeys: bool,
}
/// HydraCell holds the serialized state of one Hydra grid cell.
/// Exactly one field in the oneof must be set, and it must match the parent
/// HydraState.counter_type.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct HydraCell {
    #[prost(oneof = "hydra_cell::Sketch", tags = "1, 2, 3, 4, 5")]
    pub sketch: ::core::option::Option<hydra_cell::Sketch>,
}
/// Nested message and enum types in `HydraCell`.
pub mod hydra_cell {
    #[derive(Clone, PartialEq, ::prost::Oneof)]
    pub enum Sketch {
        #[prost(message, tag = "1")]
        CountMin(super::CountMinState),
        #[prost(message, tag = "2")]
        CountSketch(super::CountSketchState),
        #[prost(message, tag = "3")]
        Hll(super::HyperLogLogState),
        #[prost(message, tag = "4")]
        Kll(super::KllState),
        #[prost(message, tag = "5")]
        Univmon(super::UnivMonState),
    }
}
/// HydraCounterType identifies the sketch algorithm used inside Hydra cells.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum HydraCounterType {
    Unspecified = 0,
    CountMin = 1,
    CountSketch = 2,
    Hll = 3,
    Kll = 4,
    Univmon = 5,
}
impl HydraCounterType {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "HYDRA_COUNTER_TYPE_UNSPECIFIED",
            Self::CountMin => "HYDRA_COUNTER_TYPE_COUNT_MIN",
            Self::CountSketch => "HYDRA_COUNTER_TYPE_COUNT_SKETCH",
            Self::Hll => "HYDRA_COUNTER_TYPE_HLL",
            Self::Kll => "HYDRA_COUNTER_TYPE_KLL",
            Self::Univmon => "HYDRA_COUNTER_TYPE_UNIVMON",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "HYDRA_COUNTER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
            "HYDRA_COUNTER_TYPE_COUNT_MIN" => Some(Self::CountMin),
            "HYDRA_COUNTER_TYPE_COUNT_SKETCH" => Some(Self::CountSketch),
            "HYDRA_COUNTER_TYPE_HLL" => Some(Self::Hll),
            "HYDRA_COUNTER_TYPE_KLL" => Some(Self::Kll),
            "HYDRA_COUNTER_TYPE_UNIVMON" => Some(Self::Univmon),
            _ => None,
        }
    }
}
/// CocoSketchState is the portable state of a CocoSketch flow-size estimator.
///
/// The bucket table is stored flat in row-major order (d rows × width cols).
/// Element [r][c] is at index r * width + c.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CocoSketchState {
    /// Number of hash rows.
    #[prost(uint32, tag = "1")]
    pub d: u32,
    /// Number of buckets per row.
    #[prost(uint32, tag = "2")]
    pub width: u32,
    /// Full hash stored in each bucket, length = d * width.
    /// Zero means the bucket is empty (has_keys\[i\] == false).
    #[prost(uint64, repeated, tag = "3")]
    pub hashes: ::prost::alloc::vec::Vec<u64>,
    /// Cumulative count value per bucket, length = d * width.
    #[prost(uint64, repeated, tag = "4")]
    pub vals: ::prost::alloc::vec::Vec<u64>,
    /// Whether each bucket holds a valid key entry, length = d * width.
    #[prost(bool, repeated, tag = "5")]
    pub has_keys: ::prost::alloc::vec::Vec<bool>,
}
/// ElasticState is the portable state of an Elastic Sketch.
///
/// The Elastic Sketch has a heavy part (one bucket per index) and a light
/// Count-Min layer. The heavy part is serialized as parallel arrays.
/// The light layer is stored as a CountMinState with FLOAT64 counters.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ElasticState {
    /// Number of heavy buckets.
    #[prost(uint32, tag = "1")]
    pub bucket_count: u32,
    /// Per-bucket flow identifiers (strings), length = bucket_count.
    /// Empty string means the bucket is unoccupied.
    #[prost(string, repeated, tag = "2")]
    pub flow_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// Positive vote counts per bucket, length = bucket_count.
    #[prost(sint32, repeated, tag = "3")]
    pub vote_pos: ::prost::alloc::vec::Vec<i32>,
    /// Negative vote counts per bucket, length = bucket_count.
    #[prost(sint32, repeated, tag = "4")]
    pub vote_neg: ::prost::alloc::vec::Vec<i32>,
    /// Whether each bucket is in eviction state, length = bucket_count.
    #[prost(bool, repeated, tag = "5")]
    pub evictions: ::prost::alloc::vec::Vec<bool>,
    /// Light Count-Min layer (FLOAT64 counters).
    #[prost(message, optional, tag = "6")]
    pub light: ::core::option::Option<CountMinState>,
}
/// SketchEnvelope is the portable container for all sketch transfers.
/// Producers fill exactly one field inside sketch_state.
/// Consumers check format_version first, then dispatch on the oneof.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SketchEnvelope {
    /// Schema version. Consumers should reject envelopes whose version exceeds
    /// the highest version they understand.
    ///    1 = CountMin, Count, HLL, KLL, DDSketch
    ///    2 = UnivMon, Hydra (reserved)
    ///    3 = CocoSketch, ElasticSketch (reserved)
    #[prost(uint32, tag = "1")]
    pub format_version: u32,
    /// Library and build info of the producing side.
    #[prost(message, optional, tag = "2")]
    pub producer: ::core::option::Option<ProducerInfo>,
    /// Complete hashing configuration. Consumers must validate this against their
    /// own configuration before performing updates or queries on the loaded sketch.
    /// Mismatches do not prevent loading but will cause diverging results.
    #[prost(message, optional, tag = "3")]
    pub hash_spec: ::core::option::Option<HashSpec>,
    /// The sketch payload. Exactly one field must be set.
    #[prost(
        oneof = "sketch_envelope::SketchState",
        tags = "10, 11, 12, 13, 14, 15, 16, 17, 18"
    )]
    pub sketch_state: ::core::option::Option<sketch_envelope::SketchState>,
}
/// Nested message and enum types in `SketchEnvelope`.
pub mod sketch_envelope {
    /// The sketch payload. Exactly one field must be set.
    #[derive(Clone, PartialEq, ::prost::Oneof)]
    pub enum SketchState {
        #[prost(message, tag = "10")]
        CountMin(super::CountMinState),
        #[prost(message, tag = "11")]
        CountSketch(super::CountSketchState),
        #[prost(message, tag = "12")]
        Hll(super::HyperLogLogState),
        #[prost(message, tag = "13")]
        Kll(super::KllState),
        #[prost(message, tag = "14")]
        Ddsketch(super::DdSketchState),
        #[prost(message, tag = "15")]
        Univmon(super::UnivMonState),
        #[prost(message, tag = "16")]
        Hydra(super::HydraState),
        #[prost(message, tag = "17")]
        Coco(super::CocoSketchState),
        #[prost(message, tag = "18")]
        Elastic(super::ElasticState),
    }
}