Merge pull request #4594 from thestinger/map
more work on the map trait and TreeMap/LinearMap
This commit is contained in:
@@ -24,7 +24,7 @@ use core::float;
|
||||
use core::io::{WriterUtil, ReaderUtil};
|
||||
use core::io;
|
||||
use core::prelude::*;
|
||||
use core::send_map::linear;
|
||||
use core::hashmap::linear::LinearMap;
|
||||
use core::str;
|
||||
use core::to_str;
|
||||
use core::vec;
|
||||
@@ -40,7 +40,7 @@ pub enum Json {
|
||||
}
|
||||
|
||||
pub type List = ~[Json];
|
||||
pub type Object = linear::LinearMap<~str, Json>;
|
||||
pub type Object = LinearMap<~str, Json>;
|
||||
|
||||
pub struct Error {
|
||||
line: uint,
|
||||
@@ -673,7 +673,7 @@ priv impl Parser {
|
||||
self.bump();
|
||||
self.parse_whitespace();
|
||||
|
||||
let mut values = ~linear::LinearMap();
|
||||
let mut values = ~LinearMap::new();
|
||||
|
||||
if self.ch == '}' {
|
||||
self.bump();
|
||||
@@ -913,7 +913,7 @@ pub impl Decoder: serialize::Decoder {
|
||||
// FIXME(#3148) This hint should not be necessary.
|
||||
let obj: &self/~Object = obj;
|
||||
|
||||
match obj.find_ref(&name.to_owned()) {
|
||||
match obj.find(&name.to_owned()) {
|
||||
None => fail fmt!("no such field: %s", name),
|
||||
Some(json) => {
|
||||
self.stack.push(json);
|
||||
@@ -971,7 +971,7 @@ impl Json : Eq {
|
||||
if d0.len() == d1.len() {
|
||||
let mut equal = true;
|
||||
for d0.each |k, v0| {
|
||||
match d1.find_ref(k) {
|
||||
match d1.find(k) {
|
||||
Some(v1) if v0 == v1 => { },
|
||||
_ => { equal = false; break }
|
||||
}
|
||||
@@ -1177,9 +1177,9 @@ impl <A: ToJson> ~[A]: ToJson {
|
||||
fn to_json() -> Json { List(self.map(|elt| elt.to_json())) }
|
||||
}
|
||||
|
||||
impl <A: ToJson Copy> linear::LinearMap<~str, A>: ToJson {
|
||||
impl <A: ToJson Copy> LinearMap<~str, A>: ToJson {
|
||||
fn to_json() -> Json {
|
||||
let mut d = linear::LinearMap();
|
||||
let mut d = LinearMap::new();
|
||||
for self.each() |key, value| {
|
||||
d.insert(copy *key, value.to_json());
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ impl <A: ToJson Copy> linear::LinearMap<~str, A>: ToJson {
|
||||
/*
|
||||
impl <A: ToJson Copy> @std::map::HashMap<~str, A>: ToJson {
|
||||
fn to_json() -> Json {
|
||||
let mut d = linear::LinearMap();
|
||||
let mut d = LinearMap::new();
|
||||
for self.each_ref |key, value| {
|
||||
d.insert(copy *key, value.to_json());
|
||||
}
|
||||
@@ -1225,10 +1225,10 @@ mod tests {
|
||||
use json::*;
|
||||
|
||||
use core::result;
|
||||
use core::send_map::linear;
|
||||
use core::hashmap::linear::LinearMap;
|
||||
|
||||
fn mk_object(items: &[(~str, Json)]) -> Json {
|
||||
let mut d = ~linear::LinearMap();
|
||||
let mut d = ~LinearMap::new();
|
||||
|
||||
for items.each |item| {
|
||||
match *item {
|
||||
|
||||
@@ -19,7 +19,6 @@ use core::ops;
|
||||
use core::to_str::ToStr;
|
||||
use core::mutable::Mut;
|
||||
use core::prelude::*;
|
||||
use core::send_map::linear::LinearMap;
|
||||
use core::to_bytes::IterBytes;
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
@@ -500,121 +499,6 @@ pub fn hash_from_vec<K: Eq IterBytes Hash Const Copy, V: Copy>(
|
||||
map
|
||||
}
|
||||
|
||||
// FIXME #4431: Transitional
|
||||
impl<K: Eq IterBytes Hash Copy, V: Copy> @Mut<LinearMap<K, V>>:
|
||||
Map<K, V> {
|
||||
pure fn size() -> uint {
|
||||
unsafe {
|
||||
do self.borrow_const |p| {
|
||||
p.len()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn insert(key: K, value: V) -> bool {
|
||||
do self.borrow_mut |p| {
|
||||
p.insert(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
pure fn contains_key(key: K) -> bool {
|
||||
do self.borrow_const |p| {
|
||||
p.contains_key(&key)
|
||||
}
|
||||
}
|
||||
|
||||
pure fn contains_key_ref(key: &K) -> bool {
|
||||
do self.borrow_const |p| {
|
||||
p.contains_key(key)
|
||||
}
|
||||
}
|
||||
|
||||
pure fn get(key: K) -> V {
|
||||
do self.borrow_const |p| {
|
||||
p.get(&key)
|
||||
}
|
||||
}
|
||||
|
||||
pure fn find(key: K) -> Option<V> {
|
||||
unsafe {
|
||||
do self.borrow_const |p| {
|
||||
p.find(&key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_with_key(key: K, newval: V, ff: fn(K, V, V) -> V) -> bool {
|
||||
match self.find(key) {
|
||||
None => return self.insert(key, newval),
|
||||
Some(copy orig) => return self.insert(key, ff(key, orig, newval))
|
||||
}
|
||||
}
|
||||
|
||||
fn update(key: K, newval: V, ff: fn(V, V) -> V) -> bool {
|
||||
return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1));
|
||||
}
|
||||
|
||||
fn remove(key: K) -> bool {
|
||||
do self.borrow_mut |p| {
|
||||
p.remove(&key)
|
||||
}
|
||||
}
|
||||
|
||||
fn clear() {
|
||||
do self.borrow_mut |p| {
|
||||
p.clear()
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each(op: fn(key: K, value: V) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each(|k, v| op(*k, *v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each_key(op: fn(key: K) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each_key(|k| op(*k))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each_value(op: fn(value: V) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each_value(|v| op(*v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each_ref(op: fn(key: &K, value: &V) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each(op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each_key_ref(op: fn(key: &K) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each_key(op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each_value_ref(op: fn(value: &V) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each_value(op)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use map;
|
||||
|
||||
@@ -11,17 +11,13 @@
|
||||
//! Types/fns concerning URLs (see RFC 3986)
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use map;
|
||||
use map::HashMap;
|
||||
|
||||
use core::cmp::Eq;
|
||||
use core::dvec::DVec;
|
||||
use core::from_str::FromStr;
|
||||
use core::io::{Reader, ReaderUtil};
|
||||
use core::io;
|
||||
use core::prelude::*;
|
||||
use core::send_map::linear::LinearMap;
|
||||
use core::send_map;
|
||||
use core::hashmap::linear::LinearMap;
|
||||
use core::str;
|
||||
use core::to_bytes::IterBytes;
|
||||
use core::to_bytes;
|
||||
@@ -244,11 +240,9 @@ pub fn encode_form_urlencoded(m: &LinearMap<~str, ~[~str]>) -> ~str {
|
||||
* Decode a string encoded with the 'application/x-www-form-urlencoded' media
|
||||
* type into a hashmap.
|
||||
*/
|
||||
pub fn decode_form_urlencoded(
|
||||
s: &[u8]
|
||||
) -> send_map::linear::LinearMap<~str, ~[~str]> {
|
||||
pub fn decode_form_urlencoded(s: &[u8]) -> LinearMap<~str, ~[~str]> {
|
||||
do io::with_bytes_reader(s) |rdr| {
|
||||
let mut m = LinearMap();
|
||||
let mut m = LinearMap::new();
|
||||
let mut key = ~"";
|
||||
let mut value = ~"";
|
||||
let mut parsing_key = true;
|
||||
@@ -1061,18 +1055,18 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_encode_form_urlencoded() {
|
||||
let mut m = LinearMap();
|
||||
let mut m = LinearMap::new();
|
||||
assert encode_form_urlencoded(&m) == ~"";
|
||||
|
||||
m.insert(~"", ~[]);
|
||||
m.insert(~"foo", ~[]);
|
||||
assert encode_form_urlencoded(&m) == ~"";
|
||||
|
||||
let mut m = LinearMap();
|
||||
let mut m = LinearMap::new();
|
||||
m.insert(~"foo", ~[~"bar", ~"123"]);
|
||||
assert encode_form_urlencoded(&m) == ~"foo=bar&foo=123";
|
||||
|
||||
let mut m = LinearMap();
|
||||
let mut m = LinearMap::new();
|
||||
m.insert(~"foo bar", ~[~"abc", ~"12 = 34"]);
|
||||
assert encode_form_urlencoded(&m) == ~"foo+bar=abc&foo+bar=12+%3D+34";
|
||||
}
|
||||
|
||||
@@ -100,6 +100,26 @@ impl <K: Ord, V> TreeMap<K, V>: Map<K, V> {
|
||||
/// Visit all values in order
|
||||
pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|_, v| f(v)) }
|
||||
|
||||
/// Return the value corresponding to the key in the map
|
||||
pure fn find(&self, key: &K) -> Option<&self/V> {
|
||||
let mut current: &self/Option<~TreeNode<K, V>> = &self.root;
|
||||
loop {
|
||||
match *current {
|
||||
Some(ref r) => {
|
||||
let r: &self/~TreeNode<K, V> = r; // FIXME: #3148
|
||||
if *key < r.key {
|
||||
current = &r.left;
|
||||
} else if r.key < *key {
|
||||
current = &r.right;
|
||||
} else {
|
||||
return Some(&r.value);
|
||||
}
|
||||
}
|
||||
None => return None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a key-value pair into the map. An existing value for a
|
||||
/// key is replaced by the new value. Return true if the key did
|
||||
/// not already exist in the map.
|
||||
@@ -122,7 +142,6 @@ impl <K: Ord, V> TreeMap<K, V> {
|
||||
/// Create an empty TreeMap
|
||||
static pure fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
|
||||
|
||||
|
||||
/// Visit all key-value pairs in reverse order
|
||||
pure fn each_reverse(&self, f: fn(&K, &V) -> bool) {
|
||||
each_reverse(&self.root, f);
|
||||
@@ -138,26 +157,6 @@ impl <K: Ord, V> TreeMap<K, V> {
|
||||
self.each_reverse(|_, v| f(v))
|
||||
}
|
||||
|
||||
/// Return the value corresponding to the key in the map
|
||||
pure fn find(&self, key: &K) -> Option<&self/V> {
|
||||
let mut current: &self/Option<~TreeNode<K, V>> = &self.root;
|
||||
loop {
|
||||
match *current {
|
||||
Some(ref r) => {
|
||||
let r: &self/~TreeNode<K, V> = r; // FIXME: #3148
|
||||
if *key < r.key {
|
||||
current = &r.left;
|
||||
} else if r.key < *key {
|
||||
current = &r.right;
|
||||
} else {
|
||||
return Some(&r.value);
|
||||
}
|
||||
}
|
||||
None => return None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a lazy iterator over the key-value pairs in the map.
|
||||
/// Requires that it be frozen (immutable).
|
||||
pure fn iter(&self) -> TreeMapIterator/&self<K, V> {
|
||||
@@ -209,10 +208,10 @@ impl <T: Eq Ord> TreeSet<T>: Eq {
|
||||
}
|
||||
|
||||
impl <T: Ord> TreeSet<T>: Container {
|
||||
/// Return the number of elements in the map
|
||||
/// Return the number of elements in the set
|
||||
pure fn len(&self) -> uint { self.map.len() }
|
||||
|
||||
/// Return true if the map contains no elements
|
||||
/// Return true if the set contains no elements
|
||||
pure fn is_empty(&self) -> bool { self.map.is_empty() }
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ use core::pipes::{recv, oneshot, PortOne, send_one};
|
||||
use core::prelude::*;
|
||||
use core::result;
|
||||
use core::run;
|
||||
use core::send_map::linear::LinearMap;
|
||||
use core::hashmap::linear::LinearMap;
|
||||
use core::task;
|
||||
use core::to_bytes;
|
||||
use core::mutable::Mut;
|
||||
@@ -152,7 +152,7 @@ pub impl<S: Encoder> WorkMap: Encodable<S> {
|
||||
pub impl<D: Decoder> WorkMap: Decodable<D> {
|
||||
static fn decode(&self, d: &D) -> WorkMap {
|
||||
let v : ~[(WorkKey,~str)] = Decodable::decode(d);
|
||||
let mut w = LinearMap();
|
||||
let mut w = LinearMap::new();
|
||||
for v.each |&(k,v)| {
|
||||
w.insert(copy k, copy v);
|
||||
}
|
||||
@@ -173,7 +173,7 @@ impl Database {
|
||||
declared_inputs: &WorkMap) ->
|
||||
Option<(WorkMap, WorkMap, ~str)> {
|
||||
let k = json_encode(&(fn_name, declared_inputs));
|
||||
match self.db_cache.find(&k) {
|
||||
match self.db_cache.find_copy(&k) {
|
||||
None => None,
|
||||
Some(v) => Some(json_decode(v))
|
||||
}
|
||||
@@ -297,7 +297,7 @@ impl @Mut<Prep> : TPrep {
|
||||
name: &str, val: &str) -> bool {
|
||||
do self.borrow_imm |p| {
|
||||
let k = kind.to_owned();
|
||||
let f = (p.ctxt.freshness.get(&k))(name, val);
|
||||
let f = (*p.ctxt.freshness.get(&k))(name, val);
|
||||
do p.ctxt.logger.borrow_imm |lg| {
|
||||
if f {
|
||||
lg.info(fmt!("%s %s:%s is fresh",
|
||||
@@ -348,8 +348,8 @@ impl @Mut<Prep> : TPrep {
|
||||
let blk = blk.unwrap();
|
||||
let chan = ~mut Some(move chan);
|
||||
do task::spawn |move blk, move chan| {
|
||||
let exe = Exec { discovered_inputs: LinearMap(),
|
||||
discovered_outputs: LinearMap() };
|
||||
let exe = Exec{discovered_inputs: LinearMap::new(),
|
||||
discovered_outputs: LinearMap::new()};
|
||||
let chan = option::swap_unwrap(&mut *chan);
|
||||
let v = blk(&exe);
|
||||
send_one(move chan, (move exe, move v));
|
||||
@@ -411,10 +411,10 @@ fn test() {
|
||||
use io::WriterUtil;
|
||||
|
||||
let db = @Mut(Database { db_filename: Path("db.json"),
|
||||
db_cache: LinearMap(),
|
||||
db_cache: LinearMap::new(),
|
||||
db_dirty: false });
|
||||
let lg = @Mut(Logger { a: () });
|
||||
let cfg = @LinearMap();
|
||||
let cfg = @LinearMap::new();
|
||||
let cx = @Context::new(db, lg, cfg);
|
||||
let w:Work<~str> = do cx.prep("test1") |prep| {
|
||||
let pth = Path("foo.c");
|
||||
|
||||
Reference in New Issue
Block a user