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/store.rs | |
parent | 7c0fc1d786cafcbd4e9e9659089e633a7fc7c092 (diff) | |
download | obnam2-d60b331f701e0714dff6343657910ae579e72c29.tar.gz |
feat: store chunks persistently
Diffstat (limited to 'src/store.rs')
-rw-r--r-- | src/store.rs | 47 |
1 files changed, 47 insertions, 0 deletions
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)) + } +} |