use super::media_detector::{MediaDetector, MediaType};
use crate::backend::native::v3::constants::page_size;
#[derive(Debug, Clone)]
pub struct PageConfig {
pub page_size: u32,
pub media_type: MediaType,
}
impl PageConfig {
pub fn for_media(media_type: MediaType) -> Self {
let page_size = match media_type {
MediaType::SSD => page_size::SSD_PAGE_SIZE,
MediaType::HDD => page_size::HDD_PAGE_SIZE,
MediaType::Unknown => page_size::DEFAULT_PAGE_SIZE,
};
Self {
page_size,
media_type,
}
}
pub fn ssd() -> Self {
Self::for_media(MediaType::SSD)
}
pub fn hdd() -> Self {
Self::for_media(MediaType::HDD)
}
pub fn conservative() -> Self {
Self::for_media(MediaType::Unknown)
}
}
impl Default for PageConfig {
fn default() -> Self {
Self::conservative()
}
}
impl PageConfig {
pub fn is_valid(&self) -> bool {
self.page_size >= page_size::MIN_PAGE_SIZE
&& self.page_size <= page_size::MAX_PAGE_SIZE
&& self.page_size.is_power_of_two()
}
}
pub struct AdaptivePageManager {
db_path: std::path::PathBuf,
detector: MediaDetector,
config: Option<PageConfig>,
}
impl AdaptivePageManager {
pub fn new<P: AsRef<std::path::Path>>(db_path: P) -> Self {
Self {
db_path: db_path.as_ref().to_path_buf(),
detector: MediaDetector::new(),
config: None,
}
}
pub fn get_config(&mut self) -> &PageConfig {
if self.config.is_none() {
let media_type = self.detector.detect(&self.db_path);
self.config = Some(PageConfig::for_media(media_type));
}
self.config.as_ref().unwrap()
}
pub fn redetect(&mut self) {
self.config = None;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_page_config_for_ssd() {
let config = PageConfig::ssd();
assert_eq!(config.page_size, 4096);
assert_eq!(config.media_type, MediaType::SSD);
assert!(config.is_valid());
}
#[test]
fn test_page_config_for_hdd() {
let config = PageConfig::hdd();
assert_eq!(config.page_size, 16384);
assert_eq!(config.media_type, MediaType::HDD);
assert!(config.is_valid());
}
#[test]
fn test_page_config_default() {
let config = PageConfig::default();
assert_eq!(config.page_size, 4096);
assert!(config.is_valid());
}
#[test]
fn test_adaptive_page_manager_creation() {
let mut manager = AdaptivePageManager::new("/tmp/test.db");
let config = manager.get_config();
assert!(config.is_valid());
}
#[test]
fn test_adaptive_page_manager_redetect() {
let mut manager = AdaptivePageManager::new("/tmp/test.db");
let _ = manager.get_config();
manager.redetect();
let _ = manager.get_config();
}
}