use alloc::collections::VecDeque;
use alloc::vec::Vec;
use lazy_static::lazy_static;
use spin::Mutex;
#[derive(Clone, Copy)]
pub struct TrimRange {
pub offset: u64,
pub length: u64,
}
pub struct TrimEngine {
pub queue: VecDeque<TrimRange>,
pub is_running: bool,
}
lazy_static! {
pub static ref TRIM_REACTOR: Mutex<TrimEngine> = Mutex::new(TrimEngine::new());
}
impl Default for TrimEngine {
fn default() -> Self {
Self::new()
}
}
impl TrimEngine {
pub const fn new() -> Self {
Self {
queue: VecDeque::new(),
is_running: false,
}
}
pub fn queue_discard(&mut self, offset: u64, length: u64) {
self.queue.push_back(TrimRange { offset, length });
if !self.is_running && self.queue.len() > 100 {
self.ignite();
}
}
fn ignite(&mut self) {
self.is_running = true;
crate::spawn_on_core(Self::run_batch, Some(3));
crate::lcpfs_println!("[ TRIM ] Reactor Ignited.");
}
fn run_batch() {
let mut ranges = Vec::new();
{
let mut engine = TRIM_REACTOR.lock();
for _ in 0..256 {
if let Some(r) = engine.queue.pop_front() {
ranges.push(r);
} else {
break;
}
}
if engine.queue.is_empty() {
engine.is_running = false;
}
}
if ranges.is_empty() {
return;
}
crate::lcpfs_println!("[ TRIM ] Discarded {} ranges.", ranges.len());
let remaining = TRIM_REACTOR.lock().queue.len();
if remaining > 0 {
crate::spawn_on_core(Self::run_batch, Some(3));
}
}
}