From b47e1e9eda303e42896821cbc8d9bbc127890abb Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 17:55:55 -0500 Subject: [PATCH] modernize std::deque * use a proper exported data type with private fields * implement core::container::Container * use the current constructor convention * use explicit self * get rid of DVec and the mutable fields Closes #2343 --- src/libstd/deque.rs | 247 +++++++++++++++----------------- src/test/bench/graph500-bfs.rs | 11 +- src/test/run-pass/issue-2383.rs | 5 +- 3 files changed, 119 insertions(+), 144 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 6d01a4418435..86b904be3cbe 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,145 +8,122 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A deque. Untested as of yet. Likely buggy -#[forbid(non_camel_case_types)]; - +use core::container::{Container, Mutable}; use core::cmp::Eq; -use core::dvec::DVec; -use core::dvec; use core::prelude::*; use core::uint; use core::vec; -pub trait Deque { - fn size() -> uint; - fn add_front(v: T); - fn add_back(v: T); - fn pop_front() -> T; - fn pop_back() -> T; - fn peek_front() -> T; - fn peek_back() -> T; - fn get(int) -> T; +const initial_capacity: uint = 32u; // 2^5 + +pub struct Deque { + priv nelts: uint, + priv lo: uint, + priv hi: uint, + priv elts: ~[Option] } -// FIXME (#2343) eventually, a proper datatype plus an exported impl would -// be preferrable. -pub fn create() -> Deque { - type Cell = Option; +impl Container for Deque { + pure fn len(&self) -> uint { self.nelts } + pure fn is_empty(&self) -> bool { self.len() == 0 } +} - let initial_capacity: uint = 32u; // 2^5 - /** - * Grow is only called on full elts, so nelts is also len(elts), unlike - * elsewhere. - */ - fn grow(nelts: uint, lo: uint, elts: ~[Cell]) - -> ~[Cell] { - let mut elts = elts; - assert (nelts == vec::len(elts)); - let mut rv = ~[]; - - let mut i = 0u; - let nalloc = uint::next_power_of_two(nelts + 1u); - while i < nalloc { - if i < nelts { - rv.push(elts[(lo + i) % nelts]); - } else { rv.push(None); } - i += 1u; - } - - rv - } - fn get(elts: &DVec>, i: uint) -> T { - match (*elts).get_elt(i) { Some(t) => t, _ => fail!() } +impl Deque { + static pure fn new() -> Deque { + Deque{nelts: 0, lo: 0, hi: 0, + elts: vec::from_fn(initial_capacity, |_| None)} } - struct Repr { - mut nelts: uint, - mut lo: uint, - mut hi: uint, - elts: DVec>, + fn add_front(&mut self, t: T) { + let oldlo: uint = self.lo; + if self.lo == 0u { + self.lo = self.elts.len() - 1u; + } else { self.lo -= 1u; } + if self.lo == self.hi { + self.elts = grow(self.nelts, oldlo, self.elts); + self.lo = self.elts.len() - 1u; + self.hi = self.nelts; + } + self.elts[self.lo] = Some(t); + self.nelts += 1u; } - impl Deque for Repr { - fn size() -> uint { return self.nelts; } - fn add_front(t: T) { - let oldlo: uint = self.lo; - if self.lo == 0u { - self.lo = self.elts.len() - 1u; - } else { self.lo -= 1u; } - if self.lo == self.hi { - self.elts.swap(|v| grow(self.nelts, oldlo, v)); - self.lo = self.elts.len() - 1u; - self.hi = self.nelts; - } - self.elts.set_elt(self.lo, Some(t)); - self.nelts += 1u; - } - fn add_back(t: T) { - if self.lo == self.hi && self.nelts != 0u { - self.elts.swap(|v| grow(self.nelts, self.lo, v)); - self.lo = 0u; - self.hi = self.nelts; - } - self.elts.set_elt(self.hi, Some(t)); - self.hi = (self.hi + 1u) % self.elts.len(); - self.nelts += 1u; - } - /** - * We actually release (turn to none()) the T we're popping so - * that we don't keep anyone's refcount up unexpectedly. - */ - fn pop_front() -> T { - let t: T = get(&self.elts, self.lo); - self.elts.set_elt(self.lo, None); - self.lo = (self.lo + 1u) % self.elts.len(); - self.nelts -= 1u; - return t; - } - fn pop_back() -> T { - if self.hi == 0u { - self.hi = self.elts.len() - 1u; - } else { self.hi -= 1u; } - let t: T = get(&self.elts, self.hi); - self.elts.set_elt(self.hi, None); - self.nelts -= 1u; - return t; - } - fn peek_front() -> T { return get(&self.elts, self.lo); } - fn peek_back() -> T { return get(&self.elts, self.hi - 1u); } - fn get(i: int) -> T { - let idx = (self.lo + (i as uint)) % self.elts.len(); - return get(&self.elts, idx); + fn add_back(&mut self, t: T) { + if self.lo == self.hi && self.nelts != 0u { + self.elts = grow(self.nelts, self.lo, self.elts); + self.lo = 0u; + self.hi = self.nelts; } + self.elts[self.hi] = Some(t); + self.hi = (self.hi + 1u) % self.elts.len(); + self.nelts += 1u; } - let repr: Repr = Repr { - nelts: 0u, - lo: 0u, - hi: 0u, - elts: dvec::from_vec(vec::from_elem(initial_capacity, None)), - }; + fn pop_front(&mut self) -> T { + let t: T = get(self.elts, self.lo); + self.elts[self.lo] = None; + self.lo = (self.lo + 1u) % self.elts.len(); + self.nelts -= 1u; + return t; + } - repr as Deque:: + fn pop_back(&mut self) -> T { + if self.hi == 0u { + self.hi = self.elts.len() - 1u; + } else { self.hi -= 1u; } + let t: T = get(self.elts, self.hi); + self.elts[self.hi] = None; + self.nelts -= 1u; + return t; + } + + fn peek_front(&self) -> T { return get(self.elts, self.lo); } + + fn peek_back(&self) -> T { return get(self.elts, self.hi - 1u); } + + fn get(&self, i: int) -> T { + let idx = (self.lo + (i as uint)) % self.elts.len(); + return get(self.elts, idx); + } +} + +/// Grow is only called on full elts, so nelts is also len(elts), unlike +/// elsewhere. +fn grow(nelts: uint, lo: uint, elts: &[Option]) -> ~[Option] { + assert nelts == elts.len(); + let mut rv = ~[]; + + let mut i = 0u; + let nalloc = uint::next_power_of_two(nelts + 1u); + while i < nalloc { + if i < nelts { + rv.push(elts[(lo + i) % nelts]); + } else { rv.push(None); } + i += 1u; + } + + rv +} + +fn get(elts: &[Option], i: uint) -> T { + match elts[i] { Some(t) => t, _ => fail!() } } #[cfg(test)] mod tests { use core::prelude::*; - - use deque::*; - use deque; + use super::*; #[test] fn test_simple() { - let d: deque::Deque = deque::create::(); - assert (d.size() == 0u); + let mut d = Deque::new(); + assert (d.len() == 0u); d.add_front(17); d.add_front(42); d.add_back(137); - assert (d.size() == 3u); + assert (d.len() == 3u); d.add_back(137); - assert (d.size() == 4u); + assert (d.len() == 4u); log(debug, d.peek_front()); assert (d.peek_front() == 42); log(debug, d.peek_back()); @@ -163,15 +140,15 @@ mod tests { i = d.pop_back(); log(debug, i); assert (i == 17); - assert (d.size() == 0u); + assert (d.len() == 0u); d.add_back(3); - assert (d.size() == 1u); + assert (d.len() == 1u); d.add_front(2); - assert (d.size() == 2u); + assert (d.len() == 2u); d.add_back(4); - assert (d.size() == 3u); + assert (d.len() == 3u); d.add_front(1); - assert (d.size() == 4u); + assert (d.len() == 4u); log(debug, d.get(0)); log(debug, d.get(1)); log(debug, d.get(2)); @@ -189,29 +166,29 @@ mod tests { let c: @int = @64; let d: @int = @175; - let deq: deque::Deque<@int> = deque::create::<@int>(); - assert (deq.size() == 0u); + let mut deq = Deque::new(); + assert (deq.len() == 0u); deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_back(d); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert (deq.peek_front() == b); assert (deq.peek_back() == d); assert (deq.pop_front() == b); assert (deq.pop_back() == d); assert (deq.pop_back() == c); assert (deq.pop_back() == a); - assert (deq.size() == 0u); + assert (deq.len() == 0u); deq.add_back(c); - assert (deq.size() == 1u); + assert (deq.len() == 1u); deq.add_front(b); - assert (deq.size() == 2u); + assert (deq.len() == 2u); deq.add_back(d); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_front(a); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert (deq.get(0) == a); assert (deq.get(1) == b); assert (deq.get(2) == c); @@ -219,29 +196,29 @@ mod tests { } fn test_parameterized(a: T, b: T, c: T, d: T) { - let deq: deque::Deque = deque::create::(); - assert (deq.size() == 0u); + let mut deq = Deque::new(); + assert (deq.len() == 0u); deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_back(d); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert deq.peek_front() == b; assert deq.peek_back() == d; assert deq.pop_front() == b; assert deq.pop_back() == d; assert deq.pop_back() == c; assert deq.pop_back() == a; - assert (deq.size() == 0u); + assert (deq.len() == 0u); deq.add_back(c); - assert (deq.size() == 1u); + assert (deq.len() == 1u); deq.add_front(b); - assert (deq.size() == 2u); + assert (deq.len() == 2u); deq.add_back(d); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_front(a); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert deq.get(0) == a; assert deq.get(1) == b; assert deq.get(2) == c; diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 5910ade013e8..f1d5749e8402 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -23,7 +23,6 @@ use std::time; use std::oldmap; use std::oldmap::Map; use std::oldmap::HashMap; -use std::deque; use std::deque::Deque; use std::par; use core::io::WriterUtil; @@ -124,18 +123,18 @@ fn bfs(graph: graph, key: node_id) -> bfs_result { let mut marks : ~[node_id] = vec::from_elem(vec::len(graph), -1i64); - let Q = deque::create(); + let mut q = Deque::new(); - Q.add_back(key); + q.add_back(key); marks[key] = key; - while Q.size() > 0 { - let t = Q.pop_front(); + while !q.is_empty() { + let t = q.pop_front(); do graph[t].each() |k| { if marks[*k] == -1i64 { marks[*k] = t; - Q.add_back(*k); + q.add_back(*k); } true }; diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index e45d9d605552..a7afa1d6f349 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -11,10 +11,9 @@ // except according to those terms. extern mod std; -use std::deque; use std::deque::Deque; pub fn main() { - let Q = deque::create(); - Q.add_back(10); + let mut q = Deque::new(); + q.add_back(10); }