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