Skip to content

Commit

Permalink
also refactored drop_left; tag 0.0.7
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed May 30, 2022
1 parent 8bfbcfc commit 73d3b80
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 84 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

[package]
name = "im_ternary_tree"
version = "0.0.6"
version = "0.0.7"
edition = "2021"
authors = ["jiyinyiyong <jiyinyiyong@gmail.com>"]
license = "MIT"
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,11 @@ where
if t.len() == 1 {
TernaryTreeList::Empty
} else {
TernaryTreeList::Tree(t.drop_left())
// TernaryTreeList::Tree(t.drop_left())
match t.split_left_some(1).1 {
Some(v) => TernaryTreeList::Tree(v),
None => unreachable!("got not body"),
}
}
}
}
Expand Down
258 changes: 176 additions & 82 deletions src/tree/finger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,108 +243,202 @@ where
self.push_left_main(Leaf(Arc::new(item)), 2)
}

pub fn drop_left(&self) -> Self {
match self {
Leaf(_) => {
unreachable!("not expected empty node inside tree")
}
Branch2 { size, left, middle, .. } => {
if left.len() == 1 {
(**middle).to_owned()
/// try to split a small bunch of elements under(or equal) a bound size,
/// meanwhile also maintain the left branches relatively shallow
/// if all token, the rest part returns None
/// `bound` is `1, 3, 9, 27, ...`
pub fn split_left_some(&self, bound: usize) -> (Self, Option<Self>) {
if self.len() <= bound {
return (self.to_owned(), None);
}
match &self {
Leaf(_) => (self.to_owned(), None),
Branch2 {
size: root_size,
left,
middle,
} => {
if left.len() <= bound {
let (next_left_branch, rest_part) = middle.split_left_some(bound * 3);
match rest_part {
Some(branch) => (
(**left).to_owned(),
Some(Branch2 {
size: middle.len(),
left: Arc::new(next_left_branch),
middle: Arc::new(branch),
}),
),
None => ((**left).to_owned(), Some((**middle).to_owned())),
}
} else {
let changed_branch = left.drop_left();
match changed_branch {
match &**left {
Leaf(_) => unreachable!("leaf should already fall into prev case"),
Branch2 {
left: b_left,
middle: b_middle,
..
} => Branch3 {
size: size - 1,
left: b_left,
middle: b_middle,
right: middle.to_owned(),
},
size: _child_size,
left: left_child,
middle: middle_child,
} => {
let (small_bunch, rest_node) = left_child.split_left_some(bound);
match rest_node {
Some(branch) => (
small_bunch.to_owned(),
Some(Branch3 {
size: root_size - small_bunch.len(),
left: Arc::new(branch),
middle: middle_child.to_owned(),
right: middle.to_owned(),
}),
),
None => (
(**left_child).to_owned(),
Some(Branch2 {
size: root_size - left_child.len(),
left: middle_child.to_owned(),
middle: middle.to_owned(),
}),
),
}
}
Branch3 {
left: b_left,
middle: b_middle,
right: b_right,
..
size: child_size,
left: left_child,
middle: middle_child,
right: right_child,
} => {
let internal_branch = Branch2 {
size: b_middle.len() + b_right.len(),
left: b_middle,
middle: b_right,
};
Branch3 {
size: size - 1,
left: b_left,
middle: Arc::new(internal_branch),
right: middle.to_owned(),
let (small_bunch, rest_node) = left_child.split_left_some(bound);
match rest_node {
Some(branch) => (
small_bunch.to_owned(),
Some(Branch2 {
size: root_size - small_bunch.len(),
left: Arc::new(Branch3 {
size: child_size - small_bunch.len(),
left: Arc::new(branch),
middle: middle_child.to_owned(),
right: right_child.to_owned(),
}),
middle: middle.to_owned(),
}),
),
None => (
small_bunch.to_owned(),
Some(Branch3 {
size: root_size - small_bunch.len(),
left: middle_child.to_owned(),
middle: right_child.to_owned(),
right: middle.to_owned(),
}),
),
}
}
_ => Branch2 {
size: size - 1,
left: Arc::new(changed_branch),
middle: middle.to_owned(),
},
}
}
}
Branch3 {
size, left, middle, right, ..
size: root_size,
right,
middle,
left,
} => {
if left.len() == 1 {
match &**middle {
if left.len() <= bound {
let (next_left_branch, rest_part) = middle.split_left_some(bound * 3);
match rest_part {
Some(branch) => (
(**left).to_owned(),
Some(Branch3 {
size: root_size - left.len(),
left: Arc::new(next_left_branch),
middle: Arc::new(branch),
right: right.to_owned(),
}),
),
None => (
(**left).to_owned(),
Some(Branch2 {
size: root_size - left.len(),
left: middle.to_owned(),
middle: right.to_owned(),
}),
),
}
} else {
match &**left {
Leaf(_) => unreachable!("leaf should already fall into prev case"),
Branch2 {
left: b_left,
middle: b_middle,
..
} => Branch3 {
size: size - 1,
left: b_left.to_owned(),
middle: b_middle.to_owned(),
right: right.to_owned(),
},
size: child_size,
left: left_child,
middle: middle_child,
} => {
let (small_bunch, rest_node) = left_child.split_left_some(bound);
match rest_node {
Some(branch) => (
small_bunch.to_owned(),
Some(Branch3 {
size: root_size - small_bunch.len(),
left: Arc::new(Branch2 {
size: child_size - small_bunch.len(),
left: Arc::new(branch),
middle: middle_child.to_owned(),
}),
middle: middle.to_owned(),
right: right.to_owned(),
}),
),
None => (
(**left_child).to_owned(),
Some(Branch3 {
size: root_size - left_child.len(),
left: middle_child.to_owned(),
middle: middle.to_owned(),
right: right.to_owned(),
}),
),
}
}
Branch3 {
left: b_left,
middle: b_middle,
right: b_right,
..
size: child_size,
left: left_child,
middle: middle_child,
right: right_child,
} => {
let internal_branch = Branch2 {
size: b_middle.len() + b_right.len(),
left: b_middle.to_owned(),
middle: b_right.to_owned(),
};
Branch3 {
size: size - 1,
left: b_left.to_owned(),
middle: Arc::new(internal_branch),
right: right.to_owned(),
let (small_bunch, rest_node) = left_child.split_left_some(bound);
match rest_node {
Some(branch) => (
small_bunch.to_owned(),
Some(Branch3 {
size: root_size - small_bunch.len(),
left: Arc::new(Branch3 {
size: child_size - small_bunch.len(),
left: Arc::new(branch),
middle: middle_child.to_owned(),
right: right_child.to_owned(),
}),
middle: middle.to_owned(),
right: right.to_owned(),
}),
),
None => (
small_bunch.to_owned(),
Some(Branch3 {
size: root_size - small_bunch.len(),
left: Arc::new(Branch2 {
size: child_size - small_bunch.len(),
left: middle_child.to_owned(),
middle: right_child.to_owned(),
}),
middle: middle.to_owned(),
right: right.to_owned(),
}),
),
}
}
_ => Branch2 {
size: size - 1,
left: middle.to_owned(),
middle: right.to_owned(),
},
}
} else {
let changed_branch = left.drop_left();
Branch3 {
size: size - 1,
left: Arc::new(changed_branch),
middle: middle.to_owned(),
right: right.to_owned(),
}
}
}
}
}
/// try to split a small bunch of elements under(or equal) a bound size,
/// meanwhile also maintain the right branches relatively shallow
/// if all token, the rest part returns None
/// `bound` is `1, 3, 9, 27, ...`

pub fn split_right_some(&self, bound: usize) -> (Option<Self>, Self) {
if self.len() <= bound {
return (None, self.to_owned());
Expand All @@ -361,7 +455,7 @@ where
match rest_part {
Some(branch) => (
Some(Branch2 {
size: root_size - middle.len(),
size: left.len(),
left: Arc::new(branch),
middle: Arc::new(next_right_branch),
}),
Expand Down

0 comments on commit 73d3b80

Please sign in to comment.