From edcc94bde61cdd05a387310b29828642cc4f4a7b Mon Sep 17 00:00:00 2001 From: Christopher Hotchkiss Date: Wed, 15 Sep 2021 23:54:54 -0400 Subject: [PATCH] Implementation of a split function. Been busy at work so this is an isolated commit the rest of the change is still intermingled --- src/engine/io/index_formats/split_branch.rs | 90 +++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/engine/io/index_formats/split_branch.rs diff --git a/src/engine/io/index_formats/split_branch.rs b/src/engine/io/index_formats/split_branch.rs new file mode 100644 index 0000000..b958c3e --- /dev/null +++ b/src/engine/io/index_formats/split_branch.rs @@ -0,0 +1,90 @@ +//! Utility function to correctly split a branch and return a new sub set +// Split out to make testing easier +use thiserror::Error; + +pub fn split_branch( + keys: &mut Vec, + pointers: &mut Vec, +) -> Result<(T, Vec, Vec), SplitBranchError> +where + T: Clone, + U: Clone, +{ + if keys.len() + 1 != pointers.len() { + return Err(SplitBranchError::KeysPointLen(keys.len(), pointers.len())); + } + + if keys.len() < 2 { + return Err(SplitBranchError::KeysTooShort(keys.len())); + } + + let middle_index = keys.len() / 2; + let middle = keys[middle_index].clone(); + + let mut right_keys = vec![middle.clone(); keys.len() - middle_index - 1]; + right_keys.clone_from_slice(&keys[(middle_index + 1)..]); + keys.truncate(middle_index); + + let mut right_pointers = vec![pointers[0].clone(); pointers.len() - middle_index - 1]; + right_pointers.clone_from_slice(&pointers[middle_index + 1..]); + pointers.truncate(middle_index + 1); + + Ok((middle, right_keys, right_pointers)) +} + +#[derive(Debug, Error)] +pub enum SplitBranchError { + #[error("Keys len {0}, must be one less than pointers len {1}")] + KeysPointLen(usize, usize), + #[error("Cannot split without at least 2 keys, have {0}")] + KeysTooShort(usize), +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_simple_split_even() -> Result<(), Box> { + let mut keys = vec![0, 1, 2, 3, 4, 5]; + let mut pointers = vec!["a", "b", "c", "d", "e", "f", "g"]; + + let left_keys = vec![0, 1, 2]; + let left_pointers = ["a", "b", "c", "d"]; + + let middle = 3; + let right_keys = vec![4, 5]; + let right_pointers = vec!["e", "f", "g"]; + + let (out_middle, out_keys, out_pointers) = split_branch(&mut keys, &mut pointers)?; + assert_eq!(keys, left_keys); + assert_eq!(pointers, left_pointers); + assert_eq!(out_middle, middle); + assert_eq!(out_keys, right_keys); + assert_eq!(out_pointers, right_pointers); + + Ok(()) + } + + #[test] + fn test_simple_split_odd() -> Result<(), Box> { + let mut keys = vec![0, 1, 2, 3, 4]; + let mut pointers = vec!["a", "b", "c", "d", "e", "f"]; + + let left_keys = vec![0, 1]; + let left_pointers = ["a", "b", "c"]; + + let middle = 2; + let right_keys = vec![3, 4]; + let right_pointers = vec!["d", "e", "f"]; + + let (out_middle, out_keys, out_pointers) = split_branch(&mut keys, &mut pointers)?; + assert_eq!(keys, left_keys); + assert_eq!(pointers, left_pointers); + assert_eq!(out_middle, middle); + assert_eq!(out_keys, right_keys); + assert_eq!(out_pointers, right_pointers); + + Ok(()) + } +}