auto merge of #4815 : thestinger/rust/treemap, r=pcwalton
5283a8b reworks the TreeMap lazy iterator to use `&mut` again, which closes #4763. It gets the performance of the set methods back in the same ballpark that it was pre-INHTWAMA which is nice. These can be turned back into methods eventually. e5b6334 removes the transitional smallintmap attributes which closes #4737.
This commit is contained in:
commit
951ad11d68
@ -49,9 +49,8 @@ pub mod linear {
|
|||||||
buckets: ~[Option<Bucket<K, V>>],
|
buckets: ~[Option<Bucket<K, V>>],
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#3148) -- we could rewrite FoundEntry
|
// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
|
||||||
// to have type Option<&Bucket<K, V>> which would be nifty
|
// which would be nifty
|
||||||
// However, that won't work until #3148 is fixed
|
|
||||||
enum SearchResult {
|
enum SearchResult {
|
||||||
FoundEntry(uint), FoundHole(uint), TableFull
|
FoundEntry(uint), FoundHole(uint), TableFull
|
||||||
}
|
}
|
||||||
@ -296,8 +295,6 @@ pub mod linear {
|
|||||||
FoundEntry(idx) => {
|
FoundEntry(idx) => {
|
||||||
match self.buckets[idx] {
|
match self.buckets[idx] {
|
||||||
Some(ref bkt) => {
|
Some(ref bkt) => {
|
||||||
// FIXME(#3148)---should be inferred
|
|
||||||
let bkt: &self/Bucket<K, V> = bkt;
|
|
||||||
Some(&bkt.value)
|
Some(&bkt.value)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -856,9 +856,6 @@ pub impl Decoder: serialize::Decoder {
|
|||||||
debug!("read_vec_elt(idx=%u)", idx);
|
debug!("read_vec_elt(idx=%u)", idx);
|
||||||
match *self.peek() {
|
match *self.peek() {
|
||||||
List(ref list) => {
|
List(ref list) => {
|
||||||
// FIXME(#3148)---should be inferred
|
|
||||||
let list: &self/~[Json] = list;
|
|
||||||
|
|
||||||
self.stack.push(&list[idx]);
|
self.stack.push(&list[idx]);
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
@ -885,9 +882,6 @@ pub impl Decoder: serialize::Decoder {
|
|||||||
let top = self.peek();
|
let top = self.peek();
|
||||||
match *top {
|
match *top {
|
||||||
Object(ref obj) => {
|
Object(ref obj) => {
|
||||||
// FIXME(#3148) This hint should not be necessary.
|
|
||||||
let obj: &self/~Object = obj;
|
|
||||||
|
|
||||||
match obj.find(&name.to_owned()) {
|
match obj.find(&name.to_owned()) {
|
||||||
None => die!(fmt!("no such field: %s", name)),
|
None => die!(fmt!("no such field: %s", name)),
|
||||||
Some(json) => {
|
Some(json) => {
|
||||||
@ -917,8 +911,6 @@ pub impl Decoder: serialize::Decoder {
|
|||||||
debug!("read_tup_elt(idx=%u)", idx);
|
debug!("read_tup_elt(idx=%u)", idx);
|
||||||
match *self.peek() {
|
match *self.peek() {
|
||||||
List(ref list) => {
|
List(ref list) => {
|
||||||
// FIXME(#3148)---should be inferred
|
|
||||||
let list: &self/~[Json] = list;
|
|
||||||
self.stack.push(&list[idx]);
|
self.stack.push(&list[idx]);
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
@ -116,8 +116,6 @@ pub impl<V> SmallIntMap<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub impl<V: Copy> SmallIntMap<V> {
|
pub impl<V: Copy> SmallIntMap<V> {
|
||||||
// FIXME: #4733, remove after the next snapshot
|
|
||||||
#[cfg(stage2)]
|
|
||||||
fn update_with_key(&mut self, key: uint, val: V,
|
fn update_with_key(&mut self, key: uint, val: V,
|
||||||
ff: fn(uint, V, V) -> V) -> bool {
|
ff: fn(uint, V, V) -> V) -> bool {
|
||||||
match self.find(&key) {
|
match self.find(&key) {
|
||||||
@ -126,8 +124,6 @@ pub impl<V: Copy> SmallIntMap<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: #4733, remove after the next snapshot
|
|
||||||
#[cfg(stage2)]
|
|
||||||
fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
|
fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
|
||||||
self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
|
self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: Eq {
|
|||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
for self.len().times {
|
for self.len().times {
|
||||||
unsafe { // unsafe as a purity workaround
|
unsafe { // unsafe as a purity workaround
|
||||||
x = x.next();
|
map_next(&mut x);
|
||||||
y = y.next();
|
map_next(&mut y);
|
||||||
// FIXME: #4492 (ICE), x.get() == y.get()
|
// FIXME: #4492 (ICE), x.get() == y.get()
|
||||||
let (x1, x2) = x.get().unwrap();
|
let (x1, x2) = x.get().unwrap();
|
||||||
let (y1, y2) = y.get().unwrap();
|
let (y1, y2) = y.get().unwrap();
|
||||||
@ -74,8 +74,8 @@ pure fn lt<K: Ord, V>(a: &TreeMap<K, V>, b: &TreeMap<K, V>) -> bool {
|
|||||||
let (a_len, b_len) = (a.len(), b.len());
|
let (a_len, b_len) = (a.len(), b.len());
|
||||||
for uint::min(a_len, b_len).times {
|
for uint::min(a_len, b_len).times {
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
map_next(&mut x);
|
||||||
y = y.next();
|
map_next(&mut y);
|
||||||
let (key_a,_) = x.get().unwrap();
|
let (key_a,_) = x.get().unwrap();
|
||||||
let (key_b,_) = y.get().unwrap();
|
let (key_b,_) = y.get().unwrap();
|
||||||
if *key_a < *key_b { return true; }
|
if *key_a < *key_b { return true; }
|
||||||
@ -142,7 +142,6 @@ impl <K: Ord, V> TreeMap<K, V>: Map<K, V> {
|
|||||||
loop {
|
loop {
|
||||||
match *current {
|
match *current {
|
||||||
Some(ref r) => {
|
Some(ref r) => {
|
||||||
let r: &self/~TreeNode<K, V> = r; // FIXME: #3148
|
|
||||||
if *key < r.key {
|
if *key < r.key {
|
||||||
current = &r.left;
|
current = &r.left;
|
||||||
} else if r.key < *key {
|
} else if r.key < *key {
|
||||||
@ -211,32 +210,30 @@ impl <K: Ord, V> TreeMapIterator<K, V> {
|
|||||||
// Returns the current node, or None if this iterator is at the end.
|
// Returns the current node, or None if this iterator is at the end.
|
||||||
fn get(&const self) -> Option<(&self/K, &self/V)> {
|
fn get(&const self) -> Option<(&self/K, &self/V)> {
|
||||||
match self.current {
|
match self.current {
|
||||||
Some(res) => Some((&res.key, &res.value)),
|
Some(res) => Some((&res.key, &res.value)),
|
||||||
None => None
|
None => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Advance the iterator to the next node (in order). If this iterator
|
/// Advance the iterator to the next node (in order). If this iterator
|
||||||
/// is finished, does nothing.
|
/// is finished, does nothing.
|
||||||
fn next(self) -> TreeMapIterator/&self<K, V> {
|
pub fn map_next<K: Ord, V>(iter: &mut TreeMapIterator/&a<K, V>) {
|
||||||
let mut this = self;
|
while !iter.stack.is_empty() || iter.node.is_some() {
|
||||||
while !this.stack.is_empty() || this.node.is_some() {
|
match *iter.node {
|
||||||
match *this.node {
|
Some(ref x) => {
|
||||||
Some(ref x) => {
|
iter.stack.push(x);
|
||||||
this.stack.push(x);
|
iter.node = &x.left;
|
||||||
this.node = &x.left;
|
}
|
||||||
}
|
None => {
|
||||||
None => {
|
let res = iter.stack.pop();
|
||||||
let res = this.stack.pop();
|
iter.node = &res.right;
|
||||||
this.node = &res.right;
|
iter.current = Some(res);
|
||||||
this.current = Some(res);
|
return;
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.current = None;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
iter.current = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TreeSet<T> {
|
pub struct TreeSet<T> {
|
||||||
@ -298,18 +295,18 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let mut x = self.iter();
|
let mut x = self.iter();
|
||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
let mut a = x.get();
|
let mut a = x.get();
|
||||||
let mut b = y.get();
|
let mut b = y.get();
|
||||||
while a.is_some() && b.is_some() {
|
while a.is_some() && b.is_some() {
|
||||||
let a1 = a.unwrap();
|
let a1 = a.unwrap();
|
||||||
let b1 = b.unwrap();
|
let b1 = b.unwrap();
|
||||||
if a1 < b1 {
|
if a1 < b1 {
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
} else if b1 < a1 {
|
} else if b1 < a1 {
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get();
|
b = y.get();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -329,8 +326,8 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let mut x = self.iter();
|
let mut x = self.iter();
|
||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
let mut a = x.get();
|
let mut a = x.get();
|
||||||
let mut b = y.get();
|
let mut b = y.get();
|
||||||
while b.is_some() {
|
while b.is_some() {
|
||||||
@ -346,10 +343,10 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !(a1 < b1) {
|
if !(a1 < b1) {
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get();
|
b = y.get();
|
||||||
}
|
}
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,15 +359,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
|
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
let mut a = x.get();
|
let mut a = x.get();
|
||||||
let mut b = y.get();
|
let mut b = y.get();
|
||||||
|
|
||||||
while a.is_some() {
|
while a.is_some() {
|
||||||
if b.is_none() {
|
if b.is_none() {
|
||||||
return do a.while_some() |a1| {
|
return do a.while_some() |a1| {
|
||||||
if f(a1) { x = x.next(); x.get() } else { None }
|
if f(a1) { set_next(&mut x); x.get() } else { None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,11 +376,11 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
|
|
||||||
if a1 < b1 {
|
if a1 < b1 {
|
||||||
if !f(a1) { return }
|
if !f(a1) { return }
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
} else {
|
} else {
|
||||||
if !(b1 < a1) { x = x.next(); a = x.get() }
|
if !(b1 < a1) { set_next(&mut x); a = x.get() }
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get();
|
b = y.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,15 +394,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
|
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
let mut a = x.get();
|
let mut a = x.get();
|
||||||
let mut b = y.get();
|
let mut b = y.get();
|
||||||
|
|
||||||
while a.is_some() {
|
while a.is_some() {
|
||||||
if b.is_none() {
|
if b.is_none() {
|
||||||
return do a.while_some() |a1| {
|
return do a.while_some() |a1| {
|
||||||
if f(a1) { x.next(); x.get() } else { None }
|
if f(a1) { set_next(&mut x); x.get() } else { None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,21 +411,21 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
|
|
||||||
if a1 < b1 {
|
if a1 < b1 {
|
||||||
if !f(a1) { return }
|
if !f(a1) { return }
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
} else {
|
} else {
|
||||||
if b1 < a1 {
|
if b1 < a1 {
|
||||||
if !f(b1) { return }
|
if !f(b1) { return }
|
||||||
} else {
|
} else {
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
}
|
}
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get();
|
b = y.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
do b.while_some |b1| {
|
do b.while_some |b1| {
|
||||||
if f(b1) { y = y.next(); y.get() } else { None }
|
if f(b1) { set_next(&mut y); y.get() } else { None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,8 +436,8 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
|
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
let mut a = x.get();
|
let mut a = x.get();
|
||||||
let mut b = y.get();
|
let mut b = y.get();
|
||||||
|
|
||||||
@ -448,13 +445,13 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let a1 = a.unwrap();
|
let a1 = a.unwrap();
|
||||||
let b1 = b.unwrap();
|
let b1 = b.unwrap();
|
||||||
if a1 < b1 {
|
if a1 < b1 {
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
} else {
|
} else {
|
||||||
if !(b1 < a1) {
|
if !(b1 < a1) {
|
||||||
if !f(a1) { return }
|
if !f(a1) { return }
|
||||||
}
|
}
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get();
|
b = y.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -467,15 +464,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
let mut y = other.iter();
|
let mut y = other.iter();
|
||||||
|
|
||||||
unsafe { // purity workaround
|
unsafe { // purity workaround
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
let mut a = x.get();
|
let mut a = x.get();
|
||||||
let mut b = y.get();
|
let mut b = y.get();
|
||||||
|
|
||||||
while a.is_some() {
|
while a.is_some() {
|
||||||
if b.is_none() {
|
if b.is_none() {
|
||||||
return do a.while_some() |a1| {
|
return do a.while_some() |a1| {
|
||||||
if f(a1) { x = x.next(); x.get() } else { None }
|
if f(a1) { set_next(&mut x); x.get() } else { None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,15 +481,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
|||||||
|
|
||||||
if b1 < a1 {
|
if b1 < a1 {
|
||||||
if !f(b1) { return }
|
if !f(b1) { return }
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get();
|
b = y.get();
|
||||||
} else {
|
} else {
|
||||||
if !f(a1) { return }
|
if !f(a1) { return }
|
||||||
if !(a1 < b1) {
|
if !(a1 < b1) {
|
||||||
y = y.next();
|
set_next(&mut y);
|
||||||
b = y.get()
|
b = y.get()
|
||||||
}
|
}
|
||||||
x = x.next();
|
set_next(&mut x);
|
||||||
a = x.get();
|
a = x.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -525,16 +522,16 @@ impl <T: Ord> TreeSetIterator<T> {
|
|||||||
/// Returns the current node, or None if this iterator is at the end.
|
/// Returns the current node, or None if this iterator is at the end.
|
||||||
fn get(&const self) -> Option<&self/T> {
|
fn get(&const self) -> Option<&self/T> {
|
||||||
match self.iter.get() {
|
match self.iter.get() {
|
||||||
None => None,
|
None => None,
|
||||||
Some((k, _)) => Some(k)
|
Some((k, _)) => Some(k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Advance the iterator to the next node (in order). If this iterator is
|
/// Advance the iterator to the next node (in order). If this iterator is
|
||||||
/// finished, does nothing.
|
/// finished, does nothing.
|
||||||
fn next(self) -> TreeSetIterator/&self<T> {
|
pub fn set_next<T: Ord>(iter: &mut TreeSetIterator/&a<T>) {
|
||||||
TreeSetIterator { iter: self.iter.next() }
|
map_next(&mut iter.iter);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes keep track of their level in the tree, starting at 1 in the
|
// Nodes keep track of their level in the tree, starting at 1 in the
|
||||||
@ -746,8 +743,8 @@ mod test_treemap {
|
|||||||
let v1 = str::to_bytes(~"baz");
|
let v1 = str::to_bytes(~"baz");
|
||||||
let v2 = str::to_bytes(~"foobar");
|
let v2 = str::to_bytes(~"foobar");
|
||||||
|
|
||||||
m.insert(k1, v1);
|
m.insert(copy k1, copy v1);
|
||||||
m.insert(k2, v2);
|
m.insert(copy k2, copy v2);
|
||||||
|
|
||||||
assert m.find(&k2) == Some(&v2);
|
assert m.find(&k2) == Some(&v2);
|
||||||
assert m.find(&k1) == Some(&v1);
|
assert m.find(&k1) == Some(&v1);
|
||||||
@ -966,20 +963,20 @@ mod test_treemap {
|
|||||||
let m = m;
|
let m = m;
|
||||||
let mut iter = m.iter();
|
let mut iter = m.iter();
|
||||||
|
|
||||||
// FIXME: #4492 (ICE): iter.next() == Some((&x1, &y1))
|
// FIXME: #4492 (ICE): iter.get() == Some((&x1, &y1))
|
||||||
|
|
||||||
iter = iter.next();
|
map_next(&mut iter);
|
||||||
assert iter.get().unwrap() == (&x1, &y1);
|
assert iter.get().unwrap() == (&x1, &y1);
|
||||||
iter = iter.next();
|
map_next(&mut iter);
|
||||||
assert iter.get().unwrap() == (&x2, &y2);
|
assert iter.get().unwrap() == (&x2, &y2);
|
||||||
iter = iter.next();
|
map_next(&mut iter);
|
||||||
assert iter.get().unwrap() == (&x3, &y3);
|
assert iter.get().unwrap() == (&x3, &y3);
|
||||||
iter = iter.next();
|
map_next(&mut iter);
|
||||||
assert iter.get().unwrap() == (&x4, &y4);
|
assert iter.get().unwrap() == (&x4, &y4);
|
||||||
iter = iter.next();
|
map_next(&mut iter);
|
||||||
assert iter.get().unwrap() == (&x5, &y5);
|
assert iter.get().unwrap() == (&x5, &y5);
|
||||||
|
|
||||||
iter = iter.next();
|
map_next(&mut iter);
|
||||||
assert iter.get().is_none();
|
assert iter.get().is_none();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user