-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
append_id
will remove the node when the new node is the last child
#39
Comments
Thank you for reporting this and I agree with your assessment. This might also be the root cause of #35 (prepending an ID that already is the first child). Let me try to come up with a regression test and then implement your fix... |
I found a way to implement sorting. However, since sorting wasn't implemented before, I'm not sure if it can be merged. use std::cmp::Ordering;
impl<'a, T: 'a> NodeMut<'a, T> {
pub fn sort(&mut self)
where
T: Ord,
{
if self.has_children() {
let (unsorted, sorted) = self.sort_handler(|nodes| {
nodes.sort_by(|(_, a), (_, b)| a.cmp(b));
});
self.swap(unsorted, sorted);
}
}
pub fn sort_by<F>(&mut self, mut compare: F)
where
F: FnMut(&T, &T) -> Ordering,
{
if self.has_children() {
let (unsorted, sorted) = self.sort_handler(|nodes| {
nodes.sort_by(|(_, a), (_, b)| compare(a, b));
});
self.swap(unsorted, sorted);
}
}
pub fn sort_by_key<K, F>(&mut self, mut f: F)
where
F: FnMut(&T) -> K,
K: Ord,
{
if self.has_children() {
let (unsorted, sorted) = self.sort_handler(|nodes| {
nodes.sort_by_key(|(_, value)| f(value));
});
self.swap(unsorted, sorted);
}
}
fn sort_handler<F>(&mut self, mut f: F) -> (Vec<NodeId>, Vec<NodeId>)
where
F: FnMut(&mut Vec<(NodeId, &T)>),
{
let children = unsafe { self.tree.get_unchecked(self.id()).children() };
let (unsorted, mut nodes): (Vec<_>, Vec<_>) =
children.map(|n| (n.id(), (n.id(), n.value()))).unzip();
f(&mut nodes);
let sorted = nodes.into_iter().map(|(id, _)| id).collect::<Vec<_>>();
(unsorted, sorted)
}
fn swap(&mut self, unsorted: Vec<NodeId>, sorted: Vec<NodeId>) {
let mut swap = |sorted_id: NodeId, unsorted_id: NodeId| {
let mut node = unsafe { self.tree.get_unchecked_mut(unsorted_id) };
node.insert_id_before(sorted_id);
};
let mut cache = None;
let mut unsorted = unsorted.into_iter();
for id in sorted {
match cache {
Some(cache_id) if cache_id != id => swap(id, cache_id),
Some(_) => cache = None,
None => match unsorted.next() {
Some(unsorted_id) if unsorted_id != id => {
swap(id, unsorted_id);
cache = Some(unsorted_id);
}
_ => (),
},
}
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When I tried to sort in the tree, I used the code below which caused a panic in detach function:
I found that every time I append, the last node disappears. After reviewing the code, it seems that when a node detaches, the previous node's
next_sibling
is set toNone
, but the parent's children still hold the original value. When only one node remains, it enters the conditionfirst_child_id == self.id
.The simplest way to fix this is, as I commented in the match, to directly return the Node
if last_child_id == new_child_id
. The same logic applies toprepend_id
.BTW, Is it possible to implement a
sort
orsort_by_key
method? By operating directly withinNodeMut
, it would eliminate the need for operations like clone to_vec that I'm currently using.The text was updated successfully, but these errors were encountered: