use std::path::PathBuf; use std::sync::{Arc, Mutex}; use super::{RaidLevel, MemberStatus, RaidAlgorithm, RaidError}; #[derive(Debug, Clone)] pub struct RaidMember { pub device_id: String, pub device_path: PathBuf, pub size: u64, pub status: MemberStatus, } #[derive(Debug)] pub struct RaidArray { pub raid_level: RaidLevel, pub members: Vec, pub stripe_size: u64, pub total_size: u64, } pub struct RaidController { arrays: Mutex>>, } impl RaidController { pub fn new() -> Self { RaidController { arrays: Mutex::new(Vec::new()), } } pub fn create_array( &self, level: RaidLevel, member_paths: Vec, stripe_size: u64, ) -> Result { let members: Vec = member_paths .iter() .enumerate() .map(|(i, path)| { let size = if path.exists() { std::fs::metadata(path).unwrap().len() } else { 0 }; RaidMember { device_id: format!("member_{}", i), device_path: path.clone(), size, status: MemberStatus::Online, } }) .collect(); let total_size = calculate_total_size(level, &members, stripe_size); let array = RaidArray { raid_level: level, members, stripe_size, total_size, }; let array_id = format!("raid_{}", chrono::Utc::now().timestamp()); let mut arrays = self.arrays.lock().unwrap(); arrays.push(Arc::new(array)); Ok(array_id) } pub fn get_array(&self, _array_id: &str) -> Option> { let arrays = self.arrays.lock().unwrap(); arrays.iter().find(|_a| true).cloned() } pub fn read(&self, array_id: &str, offset: u64, size: u64) -> Result, RaidError> { let array = self.get_array(array_id) .ok_or("RAID array not found")?; match array.raid_level { RaidLevel::RAID0 => { let mut raid0 = super::level_0::Raid0::new(array.clone()); raid0.read(offset, size) }, RaidLevel::RAID1 => { let mut raid1 = super::level_1::Raid1::new(array.clone()); raid1.read(offset, size) }, RaidLevel::RAID5 => { let mut raid5 = super::level_5::Raid5::new(array.clone())?; raid5.read(offset, size) }, _ => Err("RAID level not implemented yet".into()), } } pub fn write(&self, array_id: &str, offset: u64, data: &[u8]) -> Result<(), RaidError> { let array = self.get_array(array_id) .ok_or("RAID array not found")?; match array.raid_level { RaidLevel::RAID0 => { let mut raid0 = super::level_0::Raid0::new(array.clone()); raid0.write(offset, data) }, RaidLevel::RAID1 => { let mut raid1 = super::level_1::Raid1::new(array.clone()); raid1.write(offset, data) }, RaidLevel::RAID5 => { let mut raid5 = super::level_5::Raid5::new(array.clone())?; raid5.write(offset, data) }, _ => Err("RAID level not implemented yet".into()), } } } fn calculate_total_size(level: RaidLevel, members: &[RaidMember], _stripe_size: u64) -> u64 { match level { RaidLevel::RAID0 => { members.iter().map(|m| m.size).sum() }, RaidLevel::RAID1 => { members.iter().map(|m| m.size).min().unwrap_or(0) }, RaidLevel::RAID5 => { let min_size = members.iter().map(|m| m.size).min().unwrap_or(0); min_size * (members.len() - 1) as u64 }, _ => 0, } }