metric_engine/engine/
options.rsuse std::collections::HashMap;
use store_api::metric_engine_consts::{
METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION,
METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION_DEFAULT, METRIC_ENGINE_INDEX_TYPE_OPTION,
};
use store_api::mito_engine_options::MEMTABLE_PARTITION_TREE_PRIMARY_KEY_ENCODING;
use crate::error::{Error, ParseRegionOptionsSnafu, Result};
const SEG_ROW_COUNT_FOR_DATA_REGION: u32 = 256;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PhysicalRegionOptions {
pub index: IndexOptions,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum IndexOptions {
#[default]
None,
Inverted,
Skipping {
granularity: u32,
},
}
pub fn set_data_region_options(
options: &mut HashMap<String, String>,
sparse_primary_key_encoding_if_absent: bool,
) {
options.remove(METRIC_ENGINE_INDEX_TYPE_OPTION);
options.remove(METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION);
options.insert(
"index.inverted_index.segment_row_count".to_string(),
SEG_ROW_COUNT_FOR_DATA_REGION.to_string(),
);
options.insert("memtable.type".to_string(), "partition_tree".to_string());
if sparse_primary_key_encoding_if_absent
&& !options.contains_key(MEMTABLE_PARTITION_TREE_PRIMARY_KEY_ENCODING)
{
options.insert(
MEMTABLE_PARTITION_TREE_PRIMARY_KEY_ENCODING.to_string(),
"sparse".to_string(),
);
}
}
impl TryFrom<&HashMap<String, String>> for PhysicalRegionOptions {
type Error = Error;
fn try_from(value: &HashMap<String, String>) -> Result<Self> {
let index = match value
.get(METRIC_ENGINE_INDEX_TYPE_OPTION)
.map(|s| s.to_lowercase())
{
Some(ref index_type) if index_type == "inverted" => Ok(IndexOptions::Inverted),
Some(ref index_type) if index_type == "skipping" => {
let granularity = value
.get(METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION)
.map_or(
Ok(METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION_DEFAULT),
|g| {
g.parse().map_err(|_| {
ParseRegionOptionsSnafu {
reason: format!("Invalid granularity: {}", g),
}
.build()
})
},
)?;
Ok(IndexOptions::Skipping { granularity })
}
Some(index_type) => ParseRegionOptionsSnafu {
reason: format!("Invalid index type: {}", index_type),
}
.fail(),
None => Ok(IndexOptions::default()),
}?;
Ok(PhysicalRegionOptions { index })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_set_data_region_options_should_remove_metric_engine_options() {
let mut options = HashMap::new();
options.insert(
METRIC_ENGINE_INDEX_TYPE_OPTION.to_string(),
"inverted".to_string(),
);
options.insert(
METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION.to_string(),
"102400".to_string(),
);
set_data_region_options(&mut options, false);
for key in [
METRIC_ENGINE_INDEX_TYPE_OPTION,
METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION,
] {
assert_eq!(options.get(key), None);
}
}
#[test]
fn test_deserialize_physical_region_options_from_hashmap() {
let mut options = HashMap::new();
options.insert(
METRIC_ENGINE_INDEX_TYPE_OPTION.to_string(),
"inverted".to_string(),
);
options.insert(
METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION.to_string(),
"102400".to_string(),
);
let physical_region_options = PhysicalRegionOptions::try_from(&options).unwrap();
assert_eq!(physical_region_options.index, IndexOptions::Inverted);
let mut options = HashMap::new();
options.insert(
METRIC_ENGINE_INDEX_TYPE_OPTION.to_string(),
"skipping".to_string(),
);
options.insert(
METRIC_ENGINE_INDEX_SKIPPING_INDEX_GRANULARITY_OPTION.to_string(),
"102400".to_string(),
);
let physical_region_options = PhysicalRegionOptions::try_from(&options).unwrap();
assert_eq!(
physical_region_options.index,
IndexOptions::Skipping {
granularity: 102400
}
);
}
}