libblobd_direct/backing_store/
file.rs1use super::BackingStore;
2use crate::pages::Pages;
3use async_trait::async_trait;
4use bufpool::buf::Buf;
5use off64::usz;
6use std::fs::File;
7use std::os::unix::prelude::FileExt;
8use std::sync::Arc;
9use tokio::task::spawn_blocking;
10
11#[derive(Clone)]
12pub(crate) struct FileBackingStore {
13 file: Arc<File>,
14 pages: Pages,
15}
16
17impl FileBackingStore {
18 pub fn new(file: File, pages: Pages) -> Self {
20 Self {
21 file: Arc::new(file),
22 pages,
23 }
24 }
25}
26
27#[async_trait]
28impl BackingStore for FileBackingStore {
29 async fn read_at(&self, offset: u64, len: u64) -> Buf {
30 let mut buf = self.pages.allocate_uninitialised(len);
31 spawn_blocking({
32 let file = self.file.clone();
33 move || {
34 let n = file.read_at(&mut buf, offset).unwrap();
35 assert_eq!(n, usz!(len));
36 buf
37 }
38 })
39 .await
40 .unwrap()
41 }
42
43 async fn write_at(&self, offset: u64, data: Buf) -> Buf {
44 spawn_blocking({
45 let file = self.file.clone();
46 move || {
47 let n = file.write_at(&data, offset).unwrap();
48 assert_eq!(n, data.len());
49 data
50 }
51 })
52 .await
53 .unwrap()
54 }
55
56 async fn sync(&self) {
57 spawn_blocking({
58 let file = self.file.clone();
59 move || {
60 file.sync_data().unwrap();
61 }
62 })
63 .await
64 .unwrap();
65 }
66}