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
//! Constants used throughout the rype library for safety limits and performance tuning.
//!
//! Centralizing these constants ensures consistency across the codebase and makes
//! it easy to adjust values when needed.
// ============================================================================
// Safety Limits for Parquet Inverted Index
// ============================================================================
/// Maximum minimizers in inverted index (1 trillion).
pub const MAX_INVERTED_MINIMIZERS: usize = 1_000_000_000_000;
/// Maximum total bucket ID entries in inverted index (4 billion).
pub const MAX_INVERTED_BUCKET_IDS: usize = 4_000_000_000;
// ============================================================================
// Batch Processing
// ============================================================================
/// Default batch size for Parquet writes (rows per batch).
pub const PARQUET_BATCH_SIZE: usize = 100_000;
/// Default row group size for Parquet files.
pub const DEFAULT_ROW_GROUP_SIZE: usize = 100_000;
// ============================================================================
// Workspace Defaults
// ============================================================================
/// Default capacity for minimizer deques (typical window size range).
pub const DEFAULT_DEQUE_CAPACITY: usize = 128;
/// Size of the fixed ring buffer for minimizer extraction (covers w up to ~200).
pub const RING_BUFFER_SIZE: usize = 256;
/// Estimated minimizers per sequence (conservative).
pub const ESTIMATED_MINIMIZERS_PER_SEQUENCE: usize = 32;
// ============================================================================
// Classification Tuning
// ============================================================================
/// Threshold for switching to HashSet-based lookup in filtered loading.
/// Above this many query minimizers, use HashSet instead of binary search.
pub const QUERY_HASHSET_THRESHOLD: usize = 1000;
/// Threshold for using HashSet vs binary search for bounded query filtering
/// during row group loading. When the bounded query slice exceeds this size,
/// build a local HashSet for O(1) lookups instead of O(log n) binary search.
pub const BOUNDED_QUERY_HASHSET_THRESHOLD: usize = 100;
/// Estimated buckets per read for HashMap pre-allocation.
pub const ESTIMATED_BUCKETS_PER_READ: usize = 4;
/// Maximum bucket count for using dense (array-based) accumulators.
/// Indices with more buckets fall back to sparse (HashMap-based) accumulators.
/// At 256 buckets, a dense accumulator uses 2 KB per read (256 × 8 bytes).
pub const DENSE_ACCUMULATOR_MAX_BUCKETS: usize = 256;
/// Size ratio threshold for switching from merge-join to galloping search.
/// When one index is more than GALLOP_THRESHOLD times larger, galloping is used.
pub const GALLOP_THRESHOLD: usize = 16;
/// Maximum bucket count for using COO merge-join in the shard loop.
/// Indices with more buckets use CSR merge-join, which iterates only unique
/// minimizers and does compact bucket-slice lookups — much faster when the
/// reference COO would be N× larger than the unique minimizer array.
///
/// Set to 10 based on the Phase 2 regression analysis: at 160 buckets, COO
/// merge-join was 8× slower than CSR (COO pairs are ~160× larger than unique
/// minimizers). At 10 buckets, COO overhead is ≤10× — comparable to the
/// CSR conversion cost it avoids. Conservative to avoid regressions; could
/// potentially be raised to ~20 with further benchmarking.
pub const COO_MERGE_JOIN_MAX_BUCKETS: usize = 10;
/// Minimum reference shard size (COO pairs) for parallel within-shard merge-join.
/// Shards smaller than this use single-threaded merge-join to avoid parallelism
/// overhead (thread spawning, chunk splitting, sparse hit merging).
///
/// At 10K pairs with 8 threads, each chunk gets ~1.25K pairs — enough work to
/// amortize rayon overhead (~10μs per task) against merge-join cost (~1μs per pair).
pub const MIN_PARALLEL_SHARD_SIZE: usize = 10_000;
// ============================================================================
// Delimiters
// ============================================================================
/// Delimiter between filename and sequence name in bucket sources.
/// Format: `path/to/file.fa::sequence_name`
pub const BUCKET_SOURCE_DELIM: &str = "::";
// ============================================================================
// C API Limits
// ============================================================================
/// Maximum sequence length for C API (2GB on 64-bit systems).
pub const MAX_SEQUENCE_LENGTH: usize = 2_000_000_000;
// ============================================================================
// QueryInvertedIndex Bit-Packing
// ============================================================================
/// Mask to extract read index from packed value (lower 31 bits).
pub const READ_INDEX_MASK: u32 = 0x7FFFFFFF;
/// Flag bit indicating reverse-complement strand (bit 31).
pub const RC_FLAG_BIT: u32 = 0x80000000;
/// Maximum number of reads supported by bit-packing (2^31 - 1).
pub const MAX_READS: usize = 0x7FFFFFFF;
// ============================================================================
// Parallel Processing
// ============================================================================
/// Minimum entries per parallel partition before parallel sharding is enabled.
///
/// When total_entries > MIN_ENTRIES_PER_PARALLEL_PARTITION * num_cpus and
/// multiple CPUs are available, parallel range-partitioned sharding is used.
/// This ensures each parallel worker has enough data to amortize the overhead
/// of spawning threads and coordinating output file renaming.
pub const MIN_ENTRIES_PER_PARALLEL_PARTITION: usize = 1_000_000;
// ============================================================================
// Tests
// ============================================================================