Skip to content

Commit

Permalink
Merge pull request #20 from Conflux-Chain/lvmt_value_option
Browse files Browse the repository at this point in the history
Support deletions in `LvmtStore` by using `Option<Box<[u8]>>` for `changes` and `LvmtValue.value`
  • Loading branch information
rongma7 authored Jan 8, 2025
2 parents 09587a2 + 30e91f8 commit d3122ee
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/lvmt/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'cache, 'db> LvmtStore<'cache, 'db> {
&mut self,
old_commit: Option<CommitID>,
new_commit: CommitID,
changes: impl Iterator<Item = (Box<[u8]>, Box<[u8]>)>,
changes: impl Iterator<Item = (Box<[u8]>, Option<Box<[u8]>>)>,
write_schema: &impl WriteSchemaTrait,
pp: &AmtParams<PE>,
) -> Result<()> {
Expand Down
28 changes: 22 additions & 6 deletions src/lvmt/types/lvmt_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,48 @@ use super::allocation::AllocatePosition;
pub struct LvmtValue {
pub(in crate::lvmt) allocation: AllocatePosition,
pub(in crate::lvmt) version: u64,
pub(in crate::lvmt) value: Box<[u8]>,
pub(in crate::lvmt) value: Option<Box<[u8]>>,
}

impl Encode for LvmtValue {
fn encode(&self) -> std::borrow::Cow<[u8]> {
let mut encoded: Vec<u8> = self.allocation.encode().into_owned();
encoded.extend(&self.version.to_le_bytes()[0..5]);
encoded.extend(&*self.value);

// Add a flag to indicate whether the value is present
let value_present = self.value.is_some() as u8;
encoded.push(value_present);
if let Some(value) = &self.value {
encoded.extend(&**value);
}

Cow::Owned(encoded)
}
}

impl Decode for LvmtValue {
fn decode(input: &[u8]) -> DecResult<Cow<Self>> {
if input.len() < 6 {
if input.len() < 7 {
return Err(DecodeError::TooShortHeader);
}
let (header, body) = input.split_at(6);
let (allocation_raw, version_raw) = header.split_at(1);

let (header, body) = input.split_at(7);
let (allocation_raw, version_raw_with_flag) = header.split_at(1);
let (version_raw, flag) = version_raw_with_flag.split_at(5);

let allocation = AllocatePosition::decode(allocation_raw)?.into_owned();

let mut version_bytes = [0u8; 8];
version_bytes[0..5].copy_from_slice(version_raw);

let version = u64::from_le_bytes(version_bytes);
let value = body.to_vec().into_boxed_slice();

let value_present = flag[0] != 0;
let value = if value_present {
Some(body.to_vec().into_boxed_slice())
} else {
None
};

Ok(Cow::Owned(Self {
allocation,
Expand Down
7 changes: 5 additions & 2 deletions src/lvmt/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ pub mod test_utils {
prop_oneof![0u64..10000, 0u64..(1 << 40)]
}

pub fn value_strategy() -> impl Strategy<Value = Box<[u8]>> {
vec(0u8..=255, 0..128).prop_map(|x| x.into_boxed_slice())
pub fn value_strategy() -> impl Strategy<Value = Option<Box<[u8]>>> {
prop_oneof![
vec(0u8..=255, 0..128).prop_map(|x| Some(x.into_boxed_slice())),
Just(None),
]
}

pub fn bytes32_strategy() -> impl Strategy<Value = H256> {
Expand Down

0 comments on commit d3122ee

Please sign in to comment.