Better node splitting for large text insertions.

This commit is contained in:
Nathan Vegdahl 2014-12-13 19:16:28 -08:00
parent f85dd9c1db
commit 8b62f01222
2 changed files with 15 additions and 8 deletions

View File

@ -156,13 +156,14 @@ impl TextNode {
}
}
/// Splits a leaf node into two roughly equal-sized children
pub fn split(&mut self) {
/// Recursively splits a leaf node into roughly equal-sized children,
/// being no larger than 'max_size'.
pub fn split(&mut self, max_size: uint) {
if let TextNodeData::Branch(_, _) = self.data {
panic!("TextNode::split(): attempt to split a non-leaf node.");
}
if self.byte_count > 1 {
if self.byte_count > max_size {
// Split data into two new text blocks
let mut tn1 = box TextNode::new();
let mut tn2 = box TextNode::new();
@ -172,6 +173,9 @@ impl TextNode {
tn2 = box TextNode::new_from_str(tb.as_str().slice(pos, tb.len()));
}
tn1.split(max_size);
tn2.split(max_size);
// Swap the old and new data
let mut new_data = TextNodeData::Branch(tn1, tn2);
mem::swap(&mut self.data, &mut new_data);
@ -218,7 +222,7 @@ impl TextNode {
}
if self.byte_count > MAX_LEAF_SIZE {
self.split();
self.split(MAX_LEAF_SIZE);
}
},

View File

@ -32,14 +32,17 @@ fn main() {
let mut tb = TextBuffer::new();
for _ in range(0i, 1000) {
for _ in range(0i, 100) {
tb.insert_text(args.arg_file.as_slice(), 0);
if tb.len() > 1024 {
tb.remove_text(27, 27+3);
}
}
tb.remove_text(3, 6);
tb.remove_text(8, 9);
tb.remove_text(40, 43);
if tb.len() > 300 {
tb.remove_text(67, 285);
}
println!("{}", tb);
}