summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-09-17 11:01:51 +0300
committerLars Wirzenius <liw@liw.fi>2020-09-17 11:01:51 +0300
commitd60b331f701e0714dff6343657910ae579e72c29 (patch)
tree767712b71b1dd46960440b9404f473125b857b80 /src
parent7c0fc1d786cafcbd4e9e9659089e633a7fc7c092 (diff)
downloadobnam2-d60b331f701e0714dff6343657910ae579e72c29.tar.gz
feat: store chunks persistently
Diffstat (limited to 'src')
-rw-r--r--src/chunkmeta.rs2
-rw-r--r--src/lib.rs1
-rw-r--r--src/store.rs47
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)
}
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<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))
+ }
+}