Make get() and set() on MutNullableHeap use the correct types.

get() must always return a rooted value, because we have no way of
ensuring the value won't be invalidated. set() takes an &T because it's
convenient; there isn't any need to expose JS<T>.
This commit is contained in:
Eli Friedman 2015-10-14 17:48:28 -07:00
parent 7a08b29201
commit 57584e74c6
11 changed files with 68 additions and 67 deletions

View file

@ -127,14 +127,14 @@ impl ChildrenList {
let last_index = self.last_index.get();
if index == last_index {
// Item is last visited child, no need to update last visited.
return Some(self.last_visited.get().unwrap().root());
return Some(self.last_visited.get().unwrap());
}
let last_visited = if index - 1u32 == last_index {
// Item is last visited's next sibling.
self.last_visited.get().unwrap().root().GetNextSibling().unwrap()
self.last_visited.get().unwrap().GetNextSibling().unwrap()
} else if last_index > 0 && index == last_index - 1u32 {
// Item is last visited's previous sibling.
self.last_visited.get().unwrap().root().GetPreviousSibling().unwrap()
self.last_visited.get().unwrap().GetPreviousSibling().unwrap()
} else if index > last_index {
if index == len - 1u32 {
// Item is parent's last child, not worth updating last visited.
@ -142,7 +142,7 @@ impl ChildrenList {
}
if index <= last_index + (len - last_index) / 2u32 {
// Item is closer to the last visited child and follows it.
self.last_visited.get().unwrap().root()
self.last_visited.get().unwrap()
.inclusively_following_siblings()
.nth((index - last_index) as usize).unwrap()
} else {
@ -154,7 +154,7 @@ impl ChildrenList {
}
} else if index >= last_index / 2u32 {
// Item is closer to the last visited child and precedes it.
self.last_visited.get().unwrap().root()
self.last_visited.get().unwrap()
.inclusively_preceding_siblings()
.nth((last_index - index) as usize).unwrap()
} else {
@ -165,7 +165,7 @@ impl ChildrenList {
.nth(index as usize)
.unwrap()
};
self.last_visited.set(Some(JS::from_rooted(&last_visited)));
self.last_visited.set(Some(last_visited.r()));
self.last_index.set(index);
Some(last_visited)
}
@ -178,7 +178,7 @@ impl ChildrenList {
}
let index = list.last_index.get();
if index < len {
list.last_visited.set(Some(JS::from_ref(added[index as usize])));
list.last_visited.set(Some(added[index as usize]));
} else if index / 2u32 >= len {
// If last index is twice as large as the number of added nodes,
// updating only it means that less nodes will be traversed if
@ -187,7 +187,7 @@ impl ChildrenList {
} else {
// If last index is not twice as large but still larger,
// it's better to update it to the number of added nodes.
list.last_visited.set(Some(JS::from_ref(next)));
list.last_visited.set(Some(next));
list.last_index.set(len);
}
}
@ -198,7 +198,7 @@ impl ChildrenList {
added: &[&Node],
next: Option<&Node>) {
let index = list.last_index.get();
if removed == &*list.last_visited.get().unwrap().root() {
if removed == &*list.last_visited.get().unwrap() {
let visited = match (prev, added, next) {
(None, _, None) => {
// Such cases where parent had only one child should
@ -213,7 +213,7 @@ impl ChildrenList {
prev
},
};
list.last_visited.set(Some(JS::from_ref(visited)));
list.last_visited.set(Some(visited));
} else if added.len() != 1 {
// The replaced child isn't the last visited one, and there are
// 0 or more than 1 nodes to replace it. Special care must be
@ -250,13 +250,13 @@ impl ChildrenList {
self.last_visited.set(None);
self.last_index.set(0u32);
} else if index < len as u32 {
self.last_visited.set(Some(JS::from_ref(added[index as usize])));
self.last_visited.set(Some(added[index as usize]));
} else {
// Setting last visited to parent's last child serves no purpose,
// so the middle is arbitrarily chosen here in case the caller
// wants random access.
let middle = len / 2;
self.last_visited.set(Some(JS::from_ref(added[middle])));
self.last_visited.set(Some(added[middle]));
self.last_index.set(middle as u32);
}
},
@ -264,8 +264,7 @@ impl ChildrenList {
}
fn reset(&self) {
self.last_visited.set(
self.node.root().GetFirstChild().map(|node| JS::from_rooted(&node)));
self.last_visited.set(self.node.root().GetFirstChild().as_ref().map(Root::r));
self.last_index.set(0u32);
}
}