use super::index_format::{
KvCheckpointCompositeIndex, KvCheckpointFieldIndex, KvCheckpointIndexEntry,
KvCheckpointIndexes, KvCheckpointSortColumn, KvCheckpointSortedEntry, KvCheckpointSortedIndex,
};
use crate::engine::kv::KvEngine;
use crate::engine::kv::index::{KvCompositeIndex, KvFieldIndex, KvIndexTree};
use crate::engine::kv::sorted_index::key::SortDirection;
use crate::engine::kv::sorted_index::window::WindowType;
pub(super) fn export_collection_indexes(engine: &KvEngine, table_key: u64) -> KvCheckpointIndexes {
let (fields, composites) = match engine.index_set(table_key) {
Some(set) => (
set.field_indexes().iter().map(export_field_index).collect(),
set.composite_indexes()
.iter()
.map(export_composite_index)
.collect(),
),
None => (Vec::new(), Vec::new()),
};
let sorted = engine
.sorted_index_snapshots(table_key)
.into_iter()
.map(|snapshot| {
let def = snapshot.def;
let (window_type, window_start_ms, window_end_ms) =
export_window_type(&def.window.window_type);
KvCheckpointSortedIndex {
name: def.name.clone(),
collection: def.collection.clone(),
key_column: def.key_column.clone(),
sort_columns: def
.encoder
.columns()
.iter()
.map(|col| KvCheckpointSortColumn {
name: col.name.clone(),
direction: export_direction(col.direction).to_string(),
})
.collect(),
window_type: window_type.to_string(),
window_timestamp_column: def.window.timestamp_column.clone(),
window_start_ms,
window_end_ms,
entries: snapshot
.entries
.into_iter()
.map(|(sort_key, primary_key)| KvCheckpointSortedEntry {
sort_key,
primary_key,
})
.collect(),
}
})
.collect();
KvCheckpointIndexes {
fields,
composites,
sorted,
}
}
fn export_field_index(index: &KvFieldIndex) -> KvCheckpointFieldIndex {
KvCheckpointFieldIndex {
field: index.field().to_string(),
field_position: index.field_position() as u64,
entries: export_entries(index.entries()),
}
}
fn export_composite_index(index: &KvCompositeIndex) -> KvCheckpointCompositeIndex {
KvCheckpointCompositeIndex {
fields: index.fields().to_vec(),
field_positions: index.field_positions().iter().map(|p| *p as u64).collect(),
entries: export_entries(index.entries()),
}
}
fn export_entries(tree: &KvIndexTree) -> Vec<KvCheckpointIndexEntry> {
tree.iter()
.map(|(key, primary_keys)| KvCheckpointIndexEntry {
key: key.clone(),
primary_keys: primary_keys.iter().cloned().collect(),
})
.collect()
}
fn export_direction(direction: SortDirection) -> &'static str {
match direction {
SortDirection::Asc => "ASC",
SortDirection::Desc => "DESC",
}
}
fn export_window_type(window_type: &WindowType) -> (&'static str, u64, u64) {
match window_type {
WindowType::None => ("", 0, 0),
WindowType::Daily => ("DAILY", 0, 0),
WindowType::Weekly => ("WEEKLY", 0, 0),
WindowType::Monthly => ("MONTHLY", 0, 0),
WindowType::Custom { start_ms, end_ms } => ("CUSTOM", *start_ms, *end_ms),
}
}