use std::collections::{HashMap, HashSet};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum FileType {
LSMData,
SSTable,
BTreeIndex,
TimestampIndex,
TextIndexLSM,
TextIndexDict,
VectorIndex,
SpatialIndex,
Blob,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileMetadata {
pub file_id: u64,
pub file_type: FileType,
pub path: String,
pub size: u64,
pub checksum: u32,
pub min_key: Option<u64>,
pub max_key: Option<u64>,
pub level: Option<u32>,
}
impl FileMetadata {
pub fn file_name(&self) -> String {
if !self.path.is_empty() {
return self.path.clone();
}
match self.file_type {
FileType::LSMData => format!("lsm_{:05}.sst", self.file_id),
FileType::SSTable => format!("sstable_{:05}.sst", self.file_id),
FileType::BTreeIndex => format!("btree_{:05}.btree", self.file_id),
FileType::TimestampIndex => format!("timestamp_idx_{:05}.idx", self.file_id),
FileType::TextIndexLSM => format!("text_{:05}.lsm", self.file_id),
FileType::TextIndexDict => format!("text_{:05}.dict", self.file_id),
FileType::VectorIndex => format!("vector_idx_{:05}.idx", self.file_id),
FileType::SpatialIndex => format!("spatial_idx_{:05}.idx", self.file_id),
FileType::Blob => format!("blob_{:05}.blob", self.file_id),
}
}
}
#[derive(Debug, Clone)]
pub struct Version {
pub version_number: u64,
pub files: HashMap<FileType, Vec<FileMetadata>>,
}
impl Version {
pub fn new(version_number: u64) -> Self {
Self {
version_number,
files: HashMap::new(),
}
}
pub fn add_file(&mut self, meta: FileMetadata) {
self.files
.entry(meta.file_type.clone())
.or_default()
.push(meta);
}
pub fn delete_file(&mut self, file_id: u64, file_type: &FileType) {
if let Some(files) = self.files.get_mut(file_type) {
files.retain(|f| f.file_id != file_id);
}
}
pub fn all_file_names(&self) -> HashSet<String> {
self.files
.values()
.flatten()
.map(|f| f.file_name())
.collect()
}
}
pub struct VersionEdit {
pub add_files: Vec<FileMetadata>,
pub delete_files: Vec<(u64, FileType)>,
}
impl VersionEdit {
pub fn new() -> Self {
Self {
add_files: Vec::new(),
delete_files: Vec::new(),
}
}
pub fn add_file(&mut self, meta: FileMetadata) {
self.add_files.push(meta);
}
pub fn delete_file(&mut self, file_id: u64, file_type: FileType) {
self.delete_files.push((file_id, file_type));
}
pub fn is_empty(&self) -> bool {
self.add_files.is_empty() && self.delete_files.is_empty()
}
}
impl Default for VersionEdit {
fn default() -> Self {
Self::new()
}
}