Skip to content
This repository has been archived by the owner on Apr 15, 2023. It is now read-only.

Commit

Permalink
Implementation of a split function.
Browse files Browse the repository at this point in the history
Been busy at work so this is an isolated commit the rest of the change is still intermingled
  • Loading branch information
chotchki committed Sep 16, 2021
1 parent 53cda6d commit edcc94b
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions src/engine/io/index_formats/split_branch.rs
Original file line number Diff line number Diff line change
@@ -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<T, U>(
keys: &mut Vec<T>,
pointers: &mut Vec<U>,
) -> Result<(T, Vec<T>, Vec<U>), 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<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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(())
}
}

0 comments on commit edcc94b

Please sign in to comment.