From d60b331f701e0714dff6343657910ae579e72c29 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Thu, 17 Sep 2020 11:01:51 +0300 Subject: feat: store chunks persistently --- src/chunkmeta.rs | 2 +- src/lib.rs | 1 + src/store.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/store.rs (limited to 'src') diff --git a/src/chunkmeta.rs b/src/chunkmeta.rs index 952dc8d..b48b9a3 100644 --- a/src/chunkmeta.rs +++ b/src/chunkmeta.rs @@ -92,7 +92,7 @@ impl ChunkMeta { impl FromStr for ChunkMeta { type Err = serde_json::error::Error; - /// Parse a JSON representation metdata. + /// Parse a JSON representation metadata. fn from_str(s: &str) -> Result { serde_json::from_str(s) } diff --git a/src/lib.rs b/src/lib.rs index 720306d..6955243 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,3 +2,4 @@ pub mod chunk; pub mod chunkid; pub mod chunkmeta; pub mod index; +pub mod store; diff --git a/src/store.rs b/src/store.rs new file mode 100644 index 0000000..0c15f02 --- /dev/null +++ b/src/store.rs @@ -0,0 +1,47 @@ +use crate::chunk::Chunk; +use crate::chunkid::ChunkId; +use crate::chunkmeta::ChunkMeta; +use std::path::{Path, PathBuf}; + +/// Store chunks, with metadata, persistently. +/// +/// The chunks and their metadata are stored persistently on disk +/// under a directory specified as the Store struct is created. To +/// store or retrieve a chunk its identifier must be used. +pub struct Store { + dir: PathBuf, +} + +impl Store { + /// Create a new Store to represent on-disk storage of chunks.x + pub fn new(dir: &Path) -> Self { + Store { + dir: dir.to_path_buf(), + } + } + + // Construct name for a file in the store from chunk id and suffix. + fn filename(&self, id: &ChunkId, suffix: &str) -> PathBuf { + self.dir.join(format!("{}.{}", id, suffix)) + } + + /// Save a chunk into a store. + pub fn save(&self, id: &ChunkId, chunk: &Chunk) -> anyhow::Result<()> { + std::fs::write(&self.filename(id, "meta"), chunk.meta().to_json())?; + std::fs::write(&self.filename(id, "data"), chunk.data())?; + Ok(()) + } + + /// Load a chunk's metadata from a store. + pub fn load_meta(&self, id: &ChunkId) -> anyhow::Result { + let meta = std::fs::read(&self.filename(id, "meta"))?; + Ok(serde_json::from_slice(&meta)?) + } + + /// Load a chunk from a store. + pub fn load(&self, id: &ChunkId) -> anyhow::Result { + let meta = self.load_meta(id)?; + let data = std::fs::read(&self.filename(id, "data"))?; + Ok(Chunk::new(meta, data)) + } +} -- cgit v1.2.1