block_db/
size.rs

1// Authors: Robert Lopez
2
3use crate::BlockDB;
4use std::collections::HashMap;
5
6/// Byte size meta-data for a `DataFile` or a `BlockDB`
7#[derive(Debug, Default, Clone, PartialEq, Eq)]
8pub struct ByteSize {
9    pub used_bytes: usize,
10    pub free_bytes: usize,
11}
12
13impl BlockDB {
14    /// Obtain the `ByteSize` of the entire `BlockDB`.
15    ///
16    /// ---
17    /// Example
18    /// ```
19    /// let block_db = BlockDB::open("./data", None).await?;
20    ///
21    /// let block_key: BlockKey = block_db.write(b"123").await?;
22    ///
23    /// let ByteSize {
24    ///     used_bytes,  // 4096 (Default chunk size)
25    ///     free_bytes,  // 0
26    /// } = block_db.byte_size().await;
27    /// ```
28    pub async fn byte_size(&self) -> ByteSize {
29        let mut used_bytes = 0;
30        let mut free_bytes = 0;
31
32        for (_, data_file) in self.data_files.read().await.clone() {
33            let reader = data_file.read().await;
34
35            used_bytes += reader.used_bytes;
36            free_bytes += reader.free_bytes;
37        }
38
39        ByteSize {
40            used_bytes,
41            free_bytes,
42        }
43    }
44
45    /// Obtain the `ByteSize` of a single `DataFile`.
46    ///
47    /// ---
48    /// Example
49    /// ```
50    /// let block_db = BlockDB::open("./data", None).await?;
51    ///
52    /// let BlockKey { data_file_id, .. } = block_db.write(b"123").await?;
53    ///
54    /// let ByteSize {
55    ///     used_bytes,  // 4096 (Default chunk size)
56    ///     free_bytes,  // 0
57    /// } = block_db.data_file_byte_size(data_file_id).await;
58    /// ```
59    pub async fn data_file_byte_size<S: AsRef<str>>(&self, data_file_id: S) -> Option<ByteSize> {
60        if let Some(data_file) = self
61            .data_files
62            .read()
63            .await
64            .get(data_file_id.as_ref())
65            .cloned()
66        {
67            return Some(data_file.read().await.byte_size());
68        }
69
70        None
71    }
72
73    /// Obtain a mapping of a `ByteSize` for each `DataFile`
74    ///
75    /// ---
76    /// Example
77    /// ```
78    /// let block_db = BlockDB::open("./data", None).await?;
79    ///
80    /// let BlockKey { data_file_id, .. } = block_db.write(b"123").await?;
81    ///
82    /// // {
83    /// //  "z-daZa": ByteSize {
84    /// //              used_bytes: 4096, (Default chunk size)
85    /// //              free_bytes: 0,
86    /// //            },
87    /// // }
88    /// let byte_size_map = block_db.data_file_byte_size_map().await?;
89    /// ```
90    pub async fn data_file_byte_size_map(&self) -> HashMap<String, ByteSize> {
91        let mut byte_size_map = HashMap::new();
92
93        for (data_file_id, data_file) in self.data_files.read().await.clone() {
94            byte_size_map.insert(data_file_id, data_file.read().await.byte_size());
95        }
96
97        byte_size_map
98    }
99
100    #[cfg(test)]
101    pub(crate) async fn free_chunk_count(&self) -> usize {
102        let mut chunks = 0;
103
104        for (_, data_file) in self.data_files.read().await.clone() {
105            chunks += data_file.read().await.free_chunk_count();
106        }
107
108        chunks
109    }
110
111    #[cfg(test)]
112    pub(crate) async fn used_chunk_count(&self) -> usize {
113        let mut chunks = 0;
114
115        for (_, data_file) in self.data_files.read().await.clone() {
116            chunks += data_file.read().await.used_chunk_count();
117        }
118
119        chunks
120    }
121}