limbo_core/storage/
database.rs1use crate::error::LimboError;
2use crate::{io::Completion, Buffer, Result};
3use std::{cell::RefCell, sync::Arc};
4
5pub trait DatabaseStorage: Send + Sync {
11 fn read_page(&self, page_idx: usize, c: Arc<Completion>) -> Result<()>;
12 fn write_page(
13 &self,
14 page_idx: usize,
15 buffer: Arc<RefCell<Buffer>>,
16 c: Arc<Completion>,
17 ) -> Result<()>;
18 fn sync(&self, c: Arc<Completion>) -> Result<()>;
19}
20
21#[cfg(feature = "fs")]
22pub struct DatabaseFile {
23 file: Arc<dyn crate::io::File>,
24}
25
26#[cfg(feature = "fs")]
27unsafe impl Send for DatabaseFile {}
28#[cfg(feature = "fs")]
29unsafe impl Sync for DatabaseFile {}
30
31#[cfg(feature = "fs")]
32impl DatabaseStorage for DatabaseFile {
33 fn read_page(&self, page_idx: usize, c: Arc<Completion>) -> Result<()> {
34 let r = c.as_read();
35 let size = r.buf().len();
36 assert!(page_idx > 0);
37 if !(512..=65536).contains(&size) || size & (size - 1) != 0 {
38 return Err(LimboError::NotADB);
39 }
40 let pos = (page_idx - 1) * size;
41 self.file.pread(pos, c)?;
42 Ok(())
43 }
44
45 fn write_page(
46 &self,
47 page_idx: usize,
48 buffer: Arc<RefCell<Buffer>>,
49 c: Arc<Completion>,
50 ) -> Result<()> {
51 let buffer_size = buffer.borrow().len();
52 assert!(page_idx > 0);
53 assert!(buffer_size >= 512);
54 assert!(buffer_size <= 65536);
55 assert_eq!(buffer_size & (buffer_size - 1), 0);
56 let pos = (page_idx - 1) * buffer_size;
57 self.file.pwrite(pos, buffer, c)?;
58 Ok(())
59 }
60
61 fn sync(&self, c: Arc<Completion>) -> Result<()> {
62 self.file.sync(c)
63 }
64}
65
66#[cfg(feature = "fs")]
67impl DatabaseFile {
68 pub fn new(file: Arc<dyn crate::io::File>) -> Self {
69 Self { file }
70 }
71}
72
73pub struct FileMemoryStorage {
74 file: Arc<dyn crate::io::File>,
75}
76
77unsafe impl Send for FileMemoryStorage {}
78unsafe impl Sync for FileMemoryStorage {}
79
80impl DatabaseStorage for FileMemoryStorage {
81 fn read_page(&self, page_idx: usize, c: Arc<Completion>) -> Result<()> {
82 let r = match *c {
83 Completion::Read(ref r) => r,
84 _ => unreachable!(),
85 };
86 let size = r.buf().len();
87 assert!(page_idx > 0);
88 if !(512..=65536).contains(&size) || size & (size - 1) != 0 {
89 return Err(LimboError::NotADB);
90 }
91 let pos = (page_idx - 1) * size;
92 self.file.pread(pos, c)?;
93 Ok(())
94 }
95
96 fn write_page(
97 &self,
98 page_idx: usize,
99 buffer: Arc<RefCell<Buffer>>,
100 c: Arc<Completion>,
101 ) -> Result<()> {
102 let buffer_size = buffer.borrow().len();
103 assert!(buffer_size >= 512);
104 assert!(buffer_size <= 65536);
105 assert_eq!(buffer_size & (buffer_size - 1), 0);
106 let pos = (page_idx - 1) * buffer_size;
107 self.file.pwrite(pos, buffer, c)?;
108 Ok(())
109 }
110
111 fn sync(&self, c: Arc<Completion>) -> Result<()> {
112 self.file.sync(c)
113 }
114}
115
116impl FileMemoryStorage {
117 pub fn new(file: Arc<dyn crate::io::File>) -> Self {
118 Self { file }
119 }
120}