pub const CHUNK_ROWID_MULTIPLIER: i64 = 1000; pub fn encode_rowid(document_id: i64, chunk_index: i64) -> i64 { document_id .checked_mul(CHUNK_ROWID_MULTIPLIER) .and_then(|v| v.checked_add(chunk_index)) .unwrap_or_else(|| { panic!("encode_rowid overflow: document_id={document_id}, chunk_index={chunk_index}") }) } pub fn decode_rowid(rowid: i64) -> (i64, i64) { let document_id = rowid / CHUNK_ROWID_MULTIPLIER; let chunk_index = rowid % CHUNK_ROWID_MULTIPLIER; (document_id, chunk_index) } #[cfg(test)] mod tests { use super::*; #[test] fn test_encode_single_chunk() { assert_eq!(encode_rowid(1, 0), 1000); } #[test] fn test_encode_multi_chunk() { assert_eq!(encode_rowid(1, 5), 1005); } #[test] fn test_encode_specific_values() { assert_eq!(encode_rowid(42, 0), 42000); assert_eq!(encode_rowid(42, 5), 42005); } #[test] fn test_decode_zero_chunk() { assert_eq!(decode_rowid(42000), (42, 0)); } #[test] fn test_decode_roundtrip() { for doc_id in [0, 1, 42, 100, 999, 10000] { for chunk_idx in [0, 1, 5, 99, 999] { let rowid = encode_rowid(doc_id, chunk_idx); let (decoded_doc, decoded_chunk) = decode_rowid(rowid); assert_eq!( (decoded_doc, decoded_chunk), (doc_id, chunk_idx), "Roundtrip failed for doc_id={doc_id}, chunk_idx={chunk_idx}" ); } } } #[test] fn test_multiplier_value() { assert_eq!(CHUNK_ROWID_MULTIPLIER, 1000); } }