Skip to main content

sshash_lib/
lib.rs

1// SSHash: Sparse and Skew Hashing of k-mers
2//
3// A Rust implementation of the SSHash compressed k-mer dictionary,
4// providing efficient storage and querying of k-mer sets.
5
6#![doc = include_str!("../README.md")]
7#![warn(missing_docs)]
8
9pub mod constants;
10pub mod encoding;
11pub mod hasher;
12pub mod kmer;
13pub mod minimizer;
14pub mod mphf_config;
15pub mod offsets;
16pub mod minimizers_control_map;
17pub mod spectrum_preserving_string_set;
18pub mod partitioned_mphf;
19pub mod sparse_and_skew_index;
20pub mod streaming_query;
21pub mod dictionary;
22pub mod builder;
23pub mod serialization;
24
25// Re-export common types at crate root 
26pub use kmer::{Kmer, Kmer21, Kmer31, Kmer63, KmerBits};
27pub use minimizer::{MinimizerInfo, MinimizerIterator};
28pub use minimizers_control_map::{MinimizersControlMap, MinimizersControlMapBuilder, BucketType};
29pub use streaming_query::{LookupResult, StreamingQuery};
30pub use dictionary::Dictionary;
31pub use builder::{BuildConfiguration, CfSegData, DictionaryBuilder, parse_cf_seg};
32pub use partitioned_mphf::PartitionedMphf;
33
34/// Dispatch to the correct const generic `K` based on a runtime `k` value.
35///
36/// The const generic `K` determines both the storage type (`u64` for K ≤ 31,
37/// `u128` for K > 31) **and** the k-mer length used in operations like
38/// `reverse_complement()`, `from_str()`, and `decode_kmer()`.  Therefore `K`
39/// must always equal the actual k value, not merely the maximum for the
40/// storage class.
41///
42/// `k` must be an odd value in \[3, 63\]; these are the only values for which
43/// [`KmerBits`] is implemented.
44///
45/// # Usage
46///
47/// ```ignore
48/// use sshash_lib::dispatch_on_k;
49///
50/// dispatch_on_k!(k, K => {
51///     let kmer = Kmer::<K>::from_string(s)?;
52///     dict.lookup::<K>(&kmer)
53/// })
54/// ```
55///
56/// # Panics
57///
58/// Panics at runtime if `k` is even or outside the \[3, 63\] range.
59#[macro_export]
60macro_rules! dispatch_on_k {
61    ($k:expr, $K:ident => $body:expr) => {{
62        match $k {
63            3  => { const $K: usize = 3;  $body }
64            5  => { const $K: usize = 5;  $body }
65            7  => { const $K: usize = 7;  $body }
66            9  => { const $K: usize = 9;  $body }
67            11 => { const $K: usize = 11; $body }
68            13 => { const $K: usize = 13; $body }
69            15 => { const $K: usize = 15; $body }
70            17 => { const $K: usize = 17; $body }
71            19 => { const $K: usize = 19; $body }
72            21 => { const $K: usize = 21; $body }
73            23 => { const $K: usize = 23; $body }
74            25 => { const $K: usize = 25; $body }
75            27 => { const $K: usize = 27; $body }
76            29 => { const $K: usize = 29; $body }
77            31 => { const $K: usize = 31; $body }
78            33 => { const $K: usize = 33; $body }
79            35 => { const $K: usize = 35; $body }
80            37 => { const $K: usize = 37; $body }
81            39 => { const $K: usize = 39; $body }
82            41 => { const $K: usize = 41; $body }
83            43 => { const $K: usize = 43; $body }
84            45 => { const $K: usize = 45; $body }
85            47 => { const $K: usize = 47; $body }
86            49 => { const $K: usize = 49; $body }
87            51 => { const $K: usize = 51; $body }
88            53 => { const $K: usize = 53; $body }
89            55 => { const $K: usize = 55; $body }
90            57 => { const $K: usize = 57; $body }
91            59 => { const $K: usize = 59; $body }
92            61 => { const $K: usize = 61; $body }
93            63 => { const $K: usize = 63; $body }
94            other => panic!(
95                "Unsupported k value: {}. k must be an odd value between 3 and 63.",
96                other,
97            ),
98        }
99    }};
100}
101
102/// Version information
103pub fn version() -> (u8, u8, u8) {
104    constants::VERSION
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_version() {
113        let (major, minor, patch) = version();
114        assert_eq!(major, 0);
115        assert_eq!(minor, 1);
116        assert_eq!(patch, 0);
117    }
118}