Skip to main content

summa_core/structures/postings/
positions.rs

1//! Packed element ordinals and token positions for indexed text.
2
3/// Maximum token position within an element (20 bits = 1,048,575)
4pub const MAX_TOKEN_POSITION: u32 = (1 << 20) - 1;
5
6/// Maximum element ordinal (12 bits = 4095)
7pub const MAX_ELEMENT_ORDINAL: u32 = (1 << 12) - 1;
8
9/// Encode element ordinal and token position into a single u32
10#[inline]
11pub fn encode_position(element_ordinal: u32, token_position: u32) -> u32 {
12    debug_assert!(
13        element_ordinal <= MAX_ELEMENT_ORDINAL,
14        "Element ordinal {} exceeds maximum {}",
15        element_ordinal,
16        MAX_ELEMENT_ORDINAL
17    );
18    debug_assert!(
19        token_position <= MAX_TOKEN_POSITION,
20        "Token position {} exceeds maximum {}",
21        token_position,
22        MAX_TOKEN_POSITION
23    );
24    (element_ordinal << 20) | (token_position & MAX_TOKEN_POSITION)
25}
26
27/// Decode element ordinal from encoded position
28#[inline]
29pub fn decode_element_ordinal(position: u32) -> u32 {
30    position >> 20
31}
32
33/// Decode token position from encoded position
34#[inline]
35pub fn decode_token_position(position: u32) -> u32 {
36    position & MAX_TOKEN_POSITION
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn test_position_encoding() {
45        // Element 0, position 5
46        let pos = encode_position(0, 5);
47        assert_eq!(decode_element_ordinal(pos), 0);
48        assert_eq!(decode_token_position(pos), 5);
49
50        // Element 3, position 100
51        let pos = encode_position(3, 100);
52        assert_eq!(decode_element_ordinal(pos), 3);
53        assert_eq!(decode_token_position(pos), 100);
54
55        // Max values
56        let pos = encode_position(MAX_ELEMENT_ORDINAL, MAX_TOKEN_POSITION);
57        assert_eq!(decode_element_ordinal(pos), MAX_ELEMENT_ORDINAL);
58        assert_eq!(decode_token_position(pos), MAX_TOKEN_POSITION);
59    }
60}