fix and test the early exit in case a grenad ends with a deletion

This commit is contained in:
Tamo 2023-02-14 18:23:57 +01:00
parent 8de3c9f737
commit fb5e4957a6
No known key found for this signature in database
GPG Key ID: 20CD8020AFA88D69

View File

@ -784,14 +784,13 @@ impl<'a, 'i> Transform<'a, 'i> {
fn merge_obkvs_and_operations<'a>(_key: &[u8], obkvs: &[Cow<'a, [u8]>]) -> Result<Cow<'a, [u8]>> { fn merge_obkvs_and_operations<'a>(_key: &[u8], obkvs: &[Cow<'a, [u8]>]) -> Result<Cow<'a, [u8]>> {
// [add, add, delete, add, add] // [add, add, delete, add, add]
// we can ignore everything that happened before the last delete. // we can ignore everything that happened before the last delete.
let starting_position = obkvs let starting_position =
.iter() obkvs.iter().rposition(|obkv| obkv[0] == Operation::Deletion as u8).unwrap_or(0);
.rposition(|obkv| obkv[0] == Operation::Deletion as u8)
.unwrap_or(0);
// [add, add, delete] // [add, add, delete]
// if the last operation was a deletion then we simply return the deletion // if the last operation was a deletion then we simply return the deletion
if starting_position == obkvs.len() { if starting_position == obkvs.len() - 1 && obkvs.last().unwrap()[0] == Operation::Deletion as u8
{
return Ok(obkvs[obkvs.len() - 1].clone()); return Ok(obkvs[obkvs.len() - 1].clone());
} }
let mut buffer = Vec::new(); let mut buffer = Vec::new();
@ -836,3 +835,45 @@ impl TransformOutput {
.collect()) .collect())
} }
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn merge_obkvs() {
let mut doc_0 = Vec::new();
let mut kv_writer = KvWriter::new(&mut doc_0);
kv_writer.insert(0_u8, [0]).unwrap();
kv_writer.finish().unwrap();
doc_0.insert(0, Operation::Addition as u8);
let ret = merge_obkvs_and_operations(&[], &[Cow::from(doc_0.as_slice())]).unwrap();
assert_eq!(*ret, doc_0);
let ret = merge_obkvs_and_operations(
&[],
&[Cow::from([Operation::Deletion as u8].as_slice()), Cow::from(doc_0.as_slice())],
)
.unwrap();
assert_eq!(*ret, doc_0);
let ret = merge_obkvs_and_operations(
&[],
&[Cow::from(doc_0.as_slice()), Cow::from([Operation::Deletion as u8].as_slice())],
)
.unwrap();
assert_eq!(*ret, [Operation::Deletion as u8]);
let ret = merge_obkvs_and_operations(
&[],
&[
Cow::from([Operation::Addition as u8, 1].as_slice()),
Cow::from([Operation::Deletion as u8].as_slice()),
Cow::from(doc_0.as_slice()),
],
)
.unwrap();
assert_eq!(*ret, doc_0);
}
}