pub mod encoder;
pub mod node;
pub mod nodes;
pub mod parser;
pub mod sized_ints;
pub use encoder::{BatchEncoder, ByteComparableEncoder, EncoderConfig, EncoderStats};
pub use node::{
BtiError, BtiNode, BtiNodeData, BtiNodeType, BtiResult, PayloadRef, SizedPointer, Transition,
TrieNavigator,
};
pub use parser::{BtiHeader, BtiIndexStats, PartitionsParser, RowsParser};
use crate::parser::header::CassandraVersion;
use std::collections::HashMap;
pub const BTI_MAGIC_NUMBER: u32 = 0x6461_0000;
pub const BTI_FORMAT_VERSION: u16 = 0x0001;
pub const MAX_TRIE_DEPTH: usize = 128;
pub const BTI_PAGE_SIZE: usize = 4096;
#[derive(Debug, Clone, PartialEq)]
pub enum FormatType {
Big,
Bti,
}
#[derive(Debug, Clone)]
pub struct BtiMetadata {
pub version: u16,
pub cassandra_version: CassandraVersion,
pub partition_trie_root: u64,
pub row_trie_root: Option<u64>,
pub partition_count: u64,
pub properties: HashMap<String, String>,
}
pub fn detect_format(magic_number: u32) -> FormatType {
match magic_number {
BTI_MAGIC_NUMBER => FormatType::Bti,
_ => FormatType::Big, }
}
pub fn is_bti_format(magic_number: u32) -> bool {
magic_number == BTI_MAGIC_NUMBER
}
#[derive(Debug, Clone)]
pub struct BtiLookupResult {
pub data_offset: u64,
pub data_size: Option<u32>,
pub row_index_offset: Option<u64>,
}
#[derive(Debug, Clone)]
pub struct BtiConfig {
pub page_aware_reading: bool,
pub max_cached_nodes: usize,
pub pointer_compression: bool,
}
impl Default for BtiConfig {
fn default() -> Self {
Self {
page_aware_reading: true,
max_cached_nodes: 1024,
pointer_compression: true,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bti_magic_number_detection() {
assert_eq!(detect_format(BTI_MAGIC_NUMBER), FormatType::Bti);
assert_eq!(detect_format(0x6F61_0000), FormatType::Big); assert_eq!(detect_format(0x0040_0000), FormatType::Big);
assert!(is_bti_format(BTI_MAGIC_NUMBER));
assert!(!is_bti_format(0x6F61_0000));
}
#[test]
fn test_bti_error_display() {
let err = node::BtiError::InvalidNodeType(0xFF);
assert!(err.to_string().contains("Invalid BTI trie node type: 0xFF"));
let err = node::BtiError::MaxDepthExceeded(150);
assert!(err
.to_string()
.contains("BTI trie depth exceeded maximum: 150"));
let err = node::BtiError::InvalidByteComparableKey("bad_key".to_string());
assert!(err
.to_string()
.contains("Invalid byte-comparable key: bad_key"));
}
#[test]
fn test_bti_config_default() {
let config = BtiConfig::default();
assert!(config.page_aware_reading);
assert_eq!(config.max_cached_nodes, 1024);
assert!(config.pointer_compression);
}
}