|
1 |
| -use bincode; |
| 1 | +use crate::constants::{OPTION_PREFIX, OPTION_TOMBSTONE_MARKER}; |
| 2 | +use crate::utils::prefix_key; |
| 3 | +use crate::{deserialize_option, serialize_option}; |
2 | 4 | use serde::de::DeserializeOwned;
|
3 | 5 | use serde::Serialize;
|
4 | 6 | use simd_r_drive::DataStore;
|
5 | 7 | use std::io::{self, ErrorKind};
|
6 | 8 |
|
7 |
| -/// Special marker for explicitly storing `None` values in binary storage. |
8 |
| -/// This ensures that `None` is distinguishable from an empty or default value. |
9 |
| -const OPTION_TOMBSTONE_MARKER: [u8; 2] = [0xFF, 0xFE]; |
10 |
| - |
11 | 9 | #[cfg(any(test, debug_assertions))]
|
12 | 10 | pub const TEST_OPTION_TOMBSTONE_MARKER: [u8; 2] = OPTION_TOMBSTONE_MARKER;
|
13 | 11 |
|
| 12 | +#[cfg(any(test, debug_assertions))] |
| 13 | +pub const TEST_OPTION_PREFIX: &[u8] = OPTION_PREFIX; |
| 14 | + |
14 | 15 | /// # Storage Utilities for Handling `Option<T>`
|
15 | 16 | ///
|
16 | 17 | /// This trait provides methods to store and retrieve `Option<T>` values
|
@@ -122,32 +123,22 @@ pub trait StorageOptionExt {
|
122 | 123 |
|
123 | 124 | /// Implements `StorageOptionExt` for `DataStore`
|
124 | 125 | impl StorageOptionExt for DataStore {
|
125 |
| - fn write_option<T: Serialize>(&self, key: &[u8], value: Option<&T>) -> std::io::Result<u64> { |
126 |
| - let serialized = match value { |
127 |
| - Some(v) => bincode::serialize(v).unwrap_or_else(|_| OPTION_TOMBSTONE_MARKER.to_vec()), |
128 |
| - None => OPTION_TOMBSTONE_MARKER.to_vec(), |
129 |
| - }; |
| 126 | + fn write_option<T: Serialize>(&self, key: &[u8], value: Option<&T>) -> io::Result<u64> { |
| 127 | + let key = &prefix_key(OPTION_PREFIX, key); |
130 | 128 |
|
| 129 | + let serialized = serialize_option(value)?; |
131 | 130 | self.write(key, &serialized)
|
132 | 131 | }
|
133 | 132 |
|
134 | 133 | fn read_option<T: DeserializeOwned>(&self, key: &[u8]) -> Result<Option<T>, io::Error> {
|
| 134 | + let key = &prefix_key(OPTION_PREFIX, key); |
| 135 | + |
135 | 136 | match self.read(key) {
|
136 |
| - Some(entry) => { |
137 |
| - let data = entry.as_slice(); |
138 |
| - if data == OPTION_TOMBSTONE_MARKER { |
139 |
| - return Ok(None); |
140 |
| - } |
141 |
| - bincode::deserialize::<T>(data) |
142 |
| - .map(Some) |
143 |
| - .map_err(|e| io::Error::new(ErrorKind::InvalidData, e)) |
144 |
| - } |
145 |
| - None => { |
146 |
| - return Err(io::Error::new( |
147 |
| - ErrorKind::NotFound, |
148 |
| - "Key not found in storage", |
149 |
| - )) |
150 |
| - } |
| 137 | + Some(entry) => deserialize_option::<T>(entry.as_slice()), |
| 138 | + None => Err(io::Error::new( |
| 139 | + ErrorKind::NotFound, |
| 140 | + "Key not found in storage", |
| 141 | + )), |
151 | 142 | }
|
152 | 143 | }
|
153 | 144 | }
|
0 commit comments