diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-09-17 11:01:51 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-09-17 11:01:51 +0300 |
commit | d60b331f701e0714dff6343657910ae579e72c29 (patch) | |
tree | 767712b71b1dd46960440b9404f473125b857b80 /src | |
parent | 7c0fc1d786cafcbd4e9e9659089e633a7fc7c092 (diff) | |
download | obnam2-d60b331f701e0714dff6343657910ae579e72c29.tar.gz |
feat: store chunks persistently
Diffstat (limited to 'src')
-rw-r--r-- | src/chunkmeta.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/store.rs | 47 |
3 files changed, 49 insertions, 1 deletions
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<Self, Self::Err> { serde_json::from_str(s) } @@ -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<ChunkMeta> { + 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<Chunk> { + let meta = self.load_meta(id)?; + let data = std::fs::read(&self.filename(id, "data"))?; + Ok(Chunk::new(meta, data)) + } +} |