use std::path::Path;
use std::sync::Arc;
use tokio::sync::oneshot;
use super::Compactions;
use crate::db::flush_job::table_path;
use crate::db::installer::Flusher;
use crate::db::view::TableFile;
use crate::{Error, Result};
pub(crate) struct Request {
pub(super) keyspace: u32,
pub(super) start: Vec<u8>,
pub(super) end: Option<Vec<u8>>,
pub(super) done: oneshot::Sender<Result<()>>,
}
impl Request {
pub(crate) fn new(
keyspace: u32,
start: &[u8],
end: Option<&[u8]>,
) -> (Self, oneshot::Receiver<Result<()>>) {
let (done, outcome) = oneshot::channel();
let request = Self {
keyspace,
start: start.to_vec(),
end: end.map(<[u8]>::to_vec),
done,
};
(request, outcome)
}
fn refuse(self) {
let keyspace = self.keyspace;
let _ = self.done.send(Err(Error::UnknownKeyspace { keyspace }));
}
}
impl Compactions {
pub(super) fn refuse_unheld(&mut self, flusher: &Flusher) {
if let Some(active) = self.active.take() {
if flusher.holds(active.request().keyspace) {
self.active = Some(active);
} else {
active.into_request().refuse();
}
}
let (held, unheld) = std::mem::take(&mut self.queued)
.into_iter()
.partition(|request| flusher.holds(request.keyspace));
self.queued = held;
unheld.into_iter().for_each(Request::refuse);
}
pub(crate) fn retire(&mut self, files: Vec<TableFile>, dir: &Path) {
self.obsolete.extend(files.iter().map(|file| {
(
Arc::downgrade(&file.blocks),
file.meta.id,
table_path(dir, file.meta.id),
)
}));
}
}