Compare commits

..

No commits in common. "d63222a6ef1906a51685e104c6dc602e60976671" and "325c491691117f65b2ddb2189f9efa327647d90a" have entirely different histories.

2 changed files with 18 additions and 139 deletions

View file

@ -1,20 +1,9 @@
use std::mem;
use crate::vec::Vec; use crate::vec::Vec;
pub const DEFAULT_DEGREE: usize = 1;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct BTree<T: Ord + Clone> { pub struct BTree<T> {
root: Node<T>, root: Node<T>,
properties: BTreeProperties,
}
#[derive(Clone, Debug, Copy)]
pub struct BTreeProperties {
degree: usize, degree: usize,
max_keys: usize,
mid_key_index: usize,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -23,63 +12,6 @@ struct Node<T> {
children: Vec<Node<T>>, children: Vec<Node<T>>,
} }
impl BTreeProperties {
fn new(degree: usize) -> Self {
Self {
degree,
max_keys: degree - 1,
mid_key_index: (degree - 1) / 2,
}
}
fn split_child<T: Ord + Clone>(&self, parent: &mut Node<T>, child_index: usize) {
let child = &mut parent.children[child_index];
let middle_key: T = child.keys[self.mid_key_index].clone();
let right_keys = match child.keys.split_off(self.mid_key_index).split_first() {
Some((_first, _others)) => {
// We don't need _first, as it will move to parent node.
_others.into()
}
None => Vec::<T>::with_capacity(self.max_keys),
};
let right_children = if !child.is_leaf() {
Some(child.children.split_off(self.mid_key_index + 1))
} else {
None
};
let new_child_node: Node<T> = Node::new(self.degree, Some(right_keys), right_children);
parent.keys.insert(child_index, middle_key);
parent.children.insert(child_index + 1, new_child_node);
}
fn is_maxed_out<T: Ord>(&self, node: &Node<T>) -> bool {
node.keys.len() == self.max_keys
}
fn insert_non_full<T: Ord + Clone>(&mut self, node: &mut Node<T>, key: T) {
let mut index: isize = isize::try_from(node.keys.len()).ok().unwrap() - 1;
while index >= 0 && node.keys[index as usize] >= key {
index -= 1;
}
let mut u_index: usize = usize::try_from(index + 1).ok().unwrap();
if node.is_leaf() {
// Just insert it, as we know this method will be called only when node is not full
node.keys.insert(u_index, key);
} else {
if self.is_maxed_out(&node.children[u_index]) {
self.split_child(node, u_index);
if node.keys[u_index] < key {
u_index += 1;
}
}
self.insert_non_full(&mut node.children[u_index], key);
}
}
}
impl<T> Node<T> impl<T> Node<T>
where where
T: Ord, T: Ord,
@ -102,63 +34,47 @@ where
} }
} }
impl<T: Ord + Clone> BTree<T> { impl<T: Ord> BTree<T> {
pub fn new(branch_factor: usize) -> Self { pub fn new(branch_factor: usize) -> Self {
let degree = 2 * branch_factor; let degree = 2 * branch_factor;
Self { Self {
root: Node::new(degree, None, None), root: Node::new(degree, None, None),
properties: BTreeProperties::new(degree), degree,
} }
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.root = Node::new(self.properties.degree, None, None); self.root = Node::new(self.degree, None, None);
} }
pub fn insert(&mut self, key: T) { fn rebalance() {
if self.properties.is_maxed_out(&self.root) { todo!()
// Create an empty root and split the old root...
let mut new_root = Node::new(self.properties.degree, None, None);
mem::swap(&mut new_root, &mut self.root);
self.root.children.insert(0, new_root);
self.properties.split_child(&mut self.root, 0);
}
self.properties.insert_non_full(&mut self.root, key)
} }
#[must_use] pub fn insert(&mut self, value: T) -> Option<T> {
pub fn has(&self, key: T) -> bool { todo!()
let mut current_node = &self.root; }
loop {
match current_node.keys.binary_search(&key) { pub fn has(&self, value: T) -> bool {
Ok(_) => return true, todo!()
Err(idx) => {
if current_node.is_leaf() {
return false;
}
current_node = &current_node.children[idx];
}
}
}
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
#[test] #[test]
fn test_create() { fn test_create() {
let _tree = BTree::<u32>::new(DEFAULT_DEGREE); let _tree = BTree::<u32>::new();
} }
#[test] #[test]
fn test_insert() { fn test_insert() {
let mut tree = BTree::<u32>::new(DEFAULT_DEGREE); let mut tree = BTree::<u32>::new();
let data = &[19, 125, 25, 16, 2, 73, 384, 435, 12924, 42, 125251, 2548]; let data = &[19, 125, 25, 16, 2, 73, 384, 435, 12924, 42, 125251, 2548];
for d in data { for d in data {
tree.insert(*d) assert!(tree.insert(*d).is_none())
} }
for d in data { for d in data {

View file

@ -4,6 +4,7 @@
//! https://doc.rust-lang.org/nomicon/vec/vec.html //! https://doc.rust-lang.org/nomicon/vec/vec.html
use std::{ use std::{
marker::PhantomData,
mem, mem,
ops::{Deref, DerefMut, Index, IndexMut}, ops::{Deref, DerefMut, Index, IndexMut},
ptr, ptr,
@ -14,6 +15,7 @@ use crate::raw_vec::RawVec;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Vec<T> { pub struct Vec<T> {
used: usize, used: usize,
marker: PhantomData<T>,
buf: RawVec<T>, buf: RawVec<T>,
} }
@ -30,6 +32,7 @@ impl<T> Vec<T> {
} }
Vec { Vec {
used: 0, used: 0,
marker: PhantomData,
buf: RawVec::new(), buf: RawVec::new(),
} }
} }
@ -44,14 +47,6 @@ impl<T> Vec<T> {
v v
} }
pub fn from_slice(data: &[T]) -> Self {
let mut v = Vec::<T>::with_capacity(data.len());
unsafe {
ptr::copy_nonoverlapping(data.as_ptr(), v.as_mut_ptr(), data.len());
}
v
}
pub fn pop(&mut self) -> Option<T> { pub fn pop(&mut self) -> Option<T> {
if self.used == 0 { if self.used == 0 {
None None
@ -126,32 +121,6 @@ impl<T> Vec<T> {
pub fn reserve(&mut self, added_capacity: usize) { pub fn reserve(&mut self, added_capacity: usize) {
self.buf.grow_by(added_capacity); self.buf.grow_by(added_capacity);
} }
#[must_use]
pub fn split_off(&mut self, at: usize) -> Self {
let other_len = self.used - at;
let mut other = Self::with_capacity(other_len);
unsafe {
self.set_len(at);
other.set_len(other_len);
ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len());
}
other
}
unsafe fn set_len(&mut self, new_length: usize) {
self.used = new_length
}
#[must_use]
pub const fn as_ptr(&self) -> *const T {
self.buf.ptr.as_ptr()
}
#[must_use]
pub const fn as_mut_ptr(&mut self) -> *mut T {
self.buf.ptr.as_ptr()
}
} }
impl<T> Index<usize> for Vec<T> { impl<T> Index<usize> for Vec<T> {
@ -189,12 +158,6 @@ impl<T> Drop for Vec<T> {
} }
} }
impl<T> From<&[T]> for Vec<T> {
fn from(value: &[T]) -> Self {
Self::from_slice(value)
}
}
unsafe impl<T: Send> Send for Vec<T> {} unsafe impl<T: Send> Send for Vec<T> {}
unsafe impl<T: Sync> Sync for Vec<T> {} unsafe impl<T: Sync> Sync for Vec<T> {}