Skip to content

Commit ca1fb9d

Browse files
jdygert-spokGitHub Enterprise
authored andcommitted
storage: higher level IO interface for linear storage (#691)
Closes #626.
1 parent fd3385c commit ca1fb9d

File tree

7 files changed

+422
-243
lines changed

7 files changed

+422
-243
lines changed

crates/crypto/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,6 @@ pub use keystore::{KeyStore, KeyStoreExt};
102102
pub use mac::MacError;
103103
pub use policy::*;
104104
pub use signer::SignerError;
105+
pub use siphasher;
105106
pub use subtle;
106107
pub use typenum;

crates/runtime/src/storage/linear/io.rs

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,53 +6,45 @@
66
//! example, accidentally running two instances of the program will cause
77
//! issues.
88
9-
use buggy::BugExt;
109
use serde::{de::DeserializeOwned, Serialize};
1110

12-
use crate::{Id, StorageError};
11+
use crate::{Id, Location, StorageError};
1312

14-
pub trait FileManager {
15-
type File: Write;
16-
/// Create new file for the id. Should error if already exists.
17-
fn create(&mut self, id: Id) -> Result<Self::File, StorageError>;
18-
/// Open existing file for the id.
19-
fn open(&mut self, id: Id) -> Result<Option<Self::File>, StorageError>;
13+
/// IO manager for creating and opening writers for a graph.
14+
pub trait IoManager {
15+
type Writer: Write;
16+
/// Create new writer for the graph ID. Should error if already exists.
17+
fn create(&mut self, id: Id) -> Result<Self::Writer, StorageError>;
18+
/// Open existing writer for the graph ID.
19+
fn open(&mut self, id: Id) -> Result<Option<Self::Writer>, StorageError>;
2020
}
2121

22+
/// Exclusive writer for a linear storage graph.
2223
pub trait Write {
24+
/// A `Read`er for this writer's shared data.
2325
type ReadOnly: Read;
26+
/// Get a [`Read`]er for this writer's shared data.
2427
fn readonly(&self) -> Self::ReadOnly;
2528

26-
fn write_all(&mut self, offset: u64, buf: &[u8]) -> Result<(), StorageError>;
27-
fn sync(&mut self) -> Result<(), StorageError>;
28-
29-
fn dump<T: Serialize>(&mut self, offset: u64, value: &T) -> Result<u64, StorageError> {
30-
let bytes = postcard::to_allocvec(value).map_err(|_| StorageError::IoError)?;
31-
let len: u32 = bytes
32-
.len()
33-
.try_into()
34-
.assume("serialized objects should fit in u32")?;
35-
self.write_all(offset, &len.to_be_bytes())?;
36-
let offset2 = offset.checked_add(4).assume("offset not near u64::MAX")?;
37-
self.write_all(offset2, &bytes)?;
38-
Ok(offset2
39-
.checked_add(u64::from(len))
40-
.assume("offset valid after write")?)
41-
}
29+
/// Get the commit head.
30+
fn head(&self) -> Result<Location, StorageError>;
31+
32+
/// Append an item (e.g. segment or fact-index) onto the writer.
33+
///
34+
/// A function is used to allow the item to contain its offset.
35+
fn append<F, T>(&mut self, builder: F) -> Result<T, StorageError>
36+
where
37+
F: FnOnce(usize) -> T,
38+
T: Serialize;
39+
40+
/// Set the commit head.
41+
fn commit(&mut self, head: Location) -> Result<(), StorageError>;
4242
}
4343

44+
/// A share-able reader for a linear storage graph.
4445
pub trait Read: Clone {
45-
fn read_exact(&self, offset: u64, buf: &mut [u8]) -> Result<(), StorageError>;
46-
47-
fn load<T: DeserializeOwned>(&self, offset: u64) -> Result<T, StorageError> {
48-
let mut bytes = [0u8; 4];
49-
self.read_exact(offset, &mut bytes)?;
50-
let len = u32::from_be_bytes(bytes);
51-
let mut bytes = alloc::vec![0u8; len as usize];
52-
self.read_exact(
53-
offset.checked_add(4).assume("offset not near u64::MAX")?,
54-
&mut bytes,
55-
)?;
56-
postcard::from_bytes(&bytes).map_err(|_| StorageError::IoError)
57-
}
46+
/// Fetch an item written by `Write::append`.
47+
fn fetch<T>(&self, offset: usize) -> Result<T, StorageError>
48+
where
49+
T: DeserializeOwned;
5850
}

0 commit comments

Comments
 (0)