pub struct CachedBlockStore<S: BlockStore> { /* private fields */ }Expand description
Write-back LRU block cache.
Wraps an arbitrary BlockStore and serves reads from an in-memory LRU
cache. Writes are marked dirty and batched to the inner store on
sync(). If the cache is full and a dirty entry must
be evicted, it is written-back to the inner store immediately.
Implementations§
Source§impl<S: BlockStore> CachedBlockStore<S>
impl<S: BlockStore> CachedBlockStore<S>
Sourcepub fn new(inner: S, capacity: usize) -> Self
pub fn new(inner: S, capacity: usize) -> Self
Create a new cache of capacity blocks in front of inner.
capacity is clamped to a minimum of 16.
Examples found in repository?
examples/network_mount.rs (line 82)
21fn main() {
22 let args: Vec<String> = std::env::args().collect();
23
24 let mut addr = "127.0.0.1:9100";
25 let mut server_name = "localhost";
26 let mut ca = "certs/ca.pem";
27 let mut master_key_hex = "";
28 let mut init = false;
29
30 let mut i = 1;
31 while i < args.len() {
32 match args[i].as_str() {
33 "--addr" => {
34 addr = &args[i + 1];
35 i += 2;
36 }
37 "--server-name" => {
38 server_name = &args[i + 1];
39 i += 2;
40 }
41 "--ca" => {
42 ca = &args[i + 1];
43 i += 2;
44 }
45 "--master-key" => {
46 master_key_hex = &args[i + 1];
47 i += 2;
48 }
49 "--init" => {
50 init = true;
51 i += 1;
52 }
53 other => {
54 eprintln!("unknown argument: {other}");
55 std::process::exit(1);
56 }
57 }
58 }
59
60 if master_key_hex.is_empty() || master_key_hex.len() != 64 {
61 eprintln!("--master-key must be a 64-character hex string (32 bytes)");
62 std::process::exit(1);
63 }
64
65 let master_key: Vec<u8> = (0..32)
66 .map(|i| u8::from_str_radix(&master_key_hex[i * 2..i * 2 + 2], 16).unwrap())
67 .collect();
68
69 // ── Connect ─────────────────────────────────────────────
70 println!("Connecting to {addr} (SNI: {server_name})...");
71 let net = NetworkBlockStore::connect(addr, server_name, Path::new(ca), &master_key)
72 .expect("failed to connect to server");
73
74 println!(
75 "Connected: {} blocks × {} bytes ({} MiB)",
76 net.total_blocks(),
77 net.block_size(),
78 net.total_blocks() as usize * net.block_size() / (1024 * 1024)
79 );
80
81 // ── Wrap with cache ─────────────────────────────────────
82 let store = Arc::new(CachedBlockStore::new(net, 1024));
83 let crypto = Arc::new(ChaChaEngine::new(&master_key).expect("invalid master key"));
84 let mut fs = FilesystemCore::new(store.clone(), crypto);
85
86 // ── Mount or init ───────────────────────────────────────
87 if init {
88 println!("Initializing new filesystem...");
89 fs.init_filesystem().expect("init_filesystem failed");
90 } else {
91 println!("Mounting existing filesystem...");
92 fs.open().expect("open failed");
93 }
94
95 // ── Demo operations ─────────────────────────────────────
96 println!("\nCreating file 'hello.txt'...");
97 match fs.create_file("hello.txt") {
98 Ok(()) => {}
99 Err(e) => println!(" (skipped: {e})"),
100 }
101
102 fs.write_file("hello.txt", 0, b"Hello from the network!")
103 .expect("write failed");
104
105 let data = fs.read_file("hello.txt", 0, 4096).expect("read failed");
106 println!("Read back: {:?}", String::from_utf8_lossy(&data));
107
108 println!("\nListing root directory:");
109 for entry in fs.list_directory().expect("list failed") {
110 println!(
111 " {:?} {:>10} bytes {}",
112 entry.kind, entry.size, entry.name
113 );
114 }
115
116 // ── Sync ────────────────────────────────────────────────
117 fs.sync().expect("sync failed");
118 println!("\nAll data synced to server.");
119}Trait Implementations§
Source§impl<S: BlockStore> BlockStore for CachedBlockStore<S>
impl<S: BlockStore> BlockStore for CachedBlockStore<S>
Source§fn block_size(&self) -> usize
fn block_size(&self) -> usize
Block size in bytes.
Source§fn total_blocks(&self) -> u64
fn total_blocks(&self) -> u64
Total number of blocks in the store.
Source§fn read_block(&self, block_id: u64) -> FsResult<Vec<u8>>
fn read_block(&self, block_id: u64) -> FsResult<Vec<u8>>
Read a full block. Returns exactly
block_size() bytes.Source§fn write_block(&self, block_id: u64, data: &[u8]) -> FsResult<()>
fn write_block(&self, block_id: u64, data: &[u8]) -> FsResult<()>
Write a full block.
data must be exactly block_size() bytes.Auto Trait Implementations§
impl<S> !Freeze for CachedBlockStore<S>
impl<S> RefUnwindSafe for CachedBlockStore<S>where
S: RefUnwindSafe,
impl<S> Send for CachedBlockStore<S>
impl<S> Sync for CachedBlockStore<S>
impl<S> Unpin for CachedBlockStore<S>where
S: Unpin,
impl<S> UnsafeUnpin for CachedBlockStore<S>where
S: UnsafeUnpin,
impl<S> UnwindSafe for CachedBlockStore<S>where
S: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more