block_db/data_file/
mod.rs1#![allow(clippy::suspicious_open_options)]
3pub mod clear;
4pub mod compact;
5pub mod data_block;
6pub mod delete;
7pub mod free;
8pub mod read;
9pub mod recover;
10pub mod size;
11pub mod util;
12pub mod wal;
13pub mod write;
14
15use super::{error::Error, options::store::OptionsStore, util::fs::create_directory};
16use data_block::DataBlock;
17use std::{
18 collections::{HashMap, VecDeque},
19 io::SeekFrom,
20 path::PathBuf,
21 sync::Arc,
22};
23use tokio::{
24 fs::{File, OpenOptions},
25 io::AsyncSeekExt,
26};
27use wal::{DataFileState, DataFileWAL};
28
29#[derive(Debug)]
30pub struct DataFile {
31 pub id: String,
32 pub wal: DataFileWAL,
33 pub file: File,
34 pub path: PathBuf,
35 pub size: usize,
36 pub directory: PathBuf,
37 pub free_bytes: usize,
38 pub used_bytes: usize,
39 pub data_blocks: HashMap<String, DataBlock>,
40 pub options_store: Arc<OptionsStore>,
41 pub free_chunk_offsets: VecDeque<usize>,
42}
43
44impl DataFile {
45 pub async fn open(
46 id: String,
47 directory: PathBuf,
48 options_store: Arc<OptionsStore>,
49 ) -> Result<Self, Error> {
50 create_directory(&directory).await?;
51
52 let path = directory.join("df");
53 let mut file = OpenOptions::new()
54 .read(true)
55 .write(true)
56 .create(true)
57 .open(&path)
58 .await?;
59
60 file.seek(SeekFrom::Start(0)).await?;
61
62 let mut wal = DataFileWAL::open(directory.join("wal")).await?;
63 let DataFileState {
64 used_bytes,
65 free_bytes,
66 data_blocks,
67 free_chunk_offsets,
68 } = wal.replay(Some(options_store.clone())).await?;
69
70 Ok(Self {
71 id,
72 wal,
73 file,
74 path,
75 size: used_bytes + free_bytes,
76 directory,
77 free_bytes,
78 used_bytes,
79 data_blocks,
80 options_store,
81 free_chunk_offsets,
82 })
83 }
84}