You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.3 KiB
90 lines
2.3 KiB
//! Inserting into the persistant cache.
|
|
use super::*;
|
|
use ::bytes::BytesMut;
|
|
use std::path::Path;
|
|
use tokio::fs::{self, File};
|
|
use std::io;
|
|
use tokio::io::AsyncWrite;
|
|
|
|
use mem::MemoryMut;
|
|
|
|
|
|
/// The write rule used for cache insertion operations.
|
|
/// This ensures the number of bytes returned corresponds to the number written into memory.
|
|
///
|
|
/// This is because we care more about the integrity of memcached data, because we can dump that to disk later if the integrity of the disk copy is incorrect.
|
|
#[derive(Debug)]
|
|
enum CacheWriteRule{}
|
|
|
|
impl plex::WriteRule for CacheWriteRule
|
|
{
|
|
#[inline(always)] fn compare_byte_sizes(a: usize, b: usize) -> Result<usize, Self::CompareFailedError> {
|
|
Ok(std::cmp::max(a,b))
|
|
}
|
|
}
|
|
|
|
/// A partially formed cache entry that can be mutated.
|
|
/// It has not yet been inserted into a persistant `ByteCache` cache, and is write-only.
|
|
pub struct PartialCacheEntry<K>
|
|
{
|
|
cfg: Arc<Config>,
|
|
|
|
id: Uuid,
|
|
key: K,
|
|
|
|
file: Option<File>,
|
|
memory: MemoryMut,
|
|
}
|
|
|
|
/// The writer type for writing to a `PartialCacheEntry`.
|
|
pub type PartialCacheEntrySink<'a> = Box<dyn AsyncWrite + Send + Sync + Unpin + 'a>;
|
|
|
|
impl<K: Key> PartialCacheEntry<K>
|
|
{
|
|
#[inline(always)] pub(super) fn new_uninit(owner: &ByteCache<K>, key: K) -> Self
|
|
{
|
|
Self {
|
|
cfg: Arc::clone(&owner.cfg),
|
|
id: Uuid::new_v4(),
|
|
|
|
file: None,
|
|
memory: MemoryMut::new(),
|
|
|
|
key,
|
|
}
|
|
}
|
|
#[inline(always)] pub(super) async fn init(&mut self) -> io::Result<()>
|
|
{
|
|
//self.memory.reserve(PAGE_SIZE);
|
|
if let Some(root) = &self.cfg.disk_location {
|
|
self.file = Some(fs::OpenOptions::new()
|
|
.write(true)
|
|
.open(gen_temp_path(root, &self.id)).await?);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Create a writer for this entry
|
|
pub fn writer(&mut self) -> PartialCacheEntrySink<'_>
|
|
{
|
|
if let Some(file) = self.file.as_mut()
|
|
{
|
|
Box::new((&mut self.memory).multiplex_ruled::<_, CacheWriteRule>(file))
|
|
} else {
|
|
Box::new(&mut self.memory)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Create a path for a **non-completed** entry
|
|
pub(super) fn gen_temp_path(root: impl AsRef<Path>, from: &Uuid) -> PathBuf
|
|
{
|
|
root.as_ref().join(format!("{}.open", from))
|
|
}
|
|
|
|
/// Create a path for a **completed** entry
|
|
pub(super) fn gen_path(root: impl AsRef<Path>, from: &Uuid) -> PathBuf
|
|
{
|
|
root.as_ref().join(format!("{}.entry", from))
|
|
}
|