block_db/read.rs
1// Authors: Robert Lopez
2
3use super::{error::Error, BlockDB, BlockKey};
4use std::collections::HashMap;
5
6impl BlockDB {
7 /// Reads the bytes of a `DataBlock` from a `DataFile`.
8 ///
9 /// Returns `None` if either the `data_file_id` or `data_block_id` does not exist.
10 ///
11 /// ---
12 /// - **Atomic**
13 /// - **Non-corruptible**
14 ///
15 /// ---
16 /// Example
17 /// ``` let block_db = BlockDB::open("./data", None).await?;
18 ///
19 /// // BlockKey { data_file_id, data_block_id }
20 /// let block_key = block_db.write(b"Hello World").await?;
21 ///
22 /// // b"Hello World".to_vec()
23 /// let data = block_db.read(&block_key).await?.unwrap();
24 /// ```
25 /// ---
26 pub async fn read(
27 &self,
28 BlockKey {
29 data_file_id,
30 data_block_id,
31 }: &BlockKey,
32 ) -> Result<Option<Vec<u8>>, Error> {
33 if let Some(data_file) = self.data_files.read().await.get(data_file_id).cloned() {
34 return data_file.write().await.read(data_block_id).await;
35 }
36
37 Ok(None)
38 }
39
40 /// Reads the bytes of multiple `DataBlock`s in a single, consistent view.
41 ///
42 /// ---
43 /// - **Atomic**
44 /// - **Non-corruptible**
45 ///
46 /// ---
47 /// Example
48 /// ``` let block_db = BlockDB::open("./data", None).await?;
49 ///
50 /// let block_key_one = block_db.write(b"Hello").await?;
51 /// let block_key_two = block_db.write(b"World").await?;
52 ///
53 /// // {
54 /// // BlockKey { .. } : Some(b"Hello"),
55 /// // BlockKey { .. } : Some(b"World"),
56 /// // }
57 /// let read_many_map = block_db.read_many(vec![&block_key_one, &block_key_two]).await?;
58 /// ```
59 /// ---
60 pub async fn read_many(
61 &self,
62 keys: Vec<&BlockKey>,
63 ) -> Result<HashMap<BlockKey, Option<Vec<u8>>>, Error> {
64 let data_files = self.data_files.read().await.clone();
65 let mut data_file_locks = HashMap::new();
66
67 for BlockKey { data_file_id, .. } in keys.iter() {
68 if !data_file_locks.contains_key(data_file_id) {
69 if let Some(data_file) = data_files.get(data_file_id) {
70 data_file_locks.insert(data_file_id, data_file.write().await);
71 }
72 }
73 }
74
75 let mut data_blocks_map = HashMap::new();
76
77 for block_key in keys {
78 if let Some(data_file_lock) = data_file_locks.get_mut(&block_key.data_file_id) {
79 data_blocks_map.insert(
80 block_key.clone(),
81 data_file_lock.read(&block_key.data_block_id).await?,
82 );
83 } else {
84 data_blocks_map.insert(block_key.clone(), None);
85 }
86 }
87
88 Ok(data_blocks_map)
89 }
90}