Skip to content

Commit 348d770

Browse files
committed
copy oldsmallintmap.rs to smallintmap.rs
1 parent 70855f5 commit 348d770

File tree

1 file changed

+237
-0
lines changed

1 file changed

+237
-0
lines changed

src/libstd/smallintmap.rs

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/*!
12+
* A simple map based on a vector for small integer keys. Space requirements
13+
* are O(highest integer key).
14+
*/
15+
#[forbid(deprecated_mode)];
16+
17+
use core::container::{Container, Mutable, Map, Set};
18+
use core::dvec::DVec;
19+
use core::ops;
20+
use core::option::{Some, None};
21+
use core::option;
22+
use core::prelude::*;
23+
24+
// FIXME (#2347): Should not be @; there's a bug somewhere in rustc that
25+
// requires this to be.
26+
struct SmallIntMap_<T> {
27+
v: DVec<Option<T>>,
28+
}
29+
30+
pub enum SmallIntMap<T> {
31+
SmallIntMap_(@SmallIntMap_<T>)
32+
}
33+
34+
/// Create a smallintmap
35+
pub fn mk<T: Copy>() -> SmallIntMap<T> {
36+
let v = DVec();
37+
SmallIntMap_(@SmallIntMap_ { v: v } )
38+
}
39+
40+
/**
41+
* Add a value to the map. If the map already contains a value for
42+
* the specified key then the original value is replaced.
43+
*/
44+
#[inline(always)]
45+
pub fn insert<T: Copy>(self: SmallIntMap<T>, key: uint, val: T) {
46+
//io::println(fmt!("%?", key));
47+
self.v.grow_set_elt(key, &None, Some(val));
48+
}
49+
50+
/**
51+
* Get the value for the specified key. If the key does not exist
52+
* in the map then returns none
53+
*/
54+
pub pure fn find<T: Copy>(self: SmallIntMap<T>, key: uint) -> Option<T> {
55+
if key < self.v.len() { return self.v.get_elt(key); }
56+
return None::<T>;
57+
}
58+
59+
/**
60+
* Get the value for the specified key
61+
*
62+
* # Failure
63+
*
64+
* If the key does not exist in the map
65+
*/
66+
pub pure fn get<T: Copy>(self: SmallIntMap<T>, key: uint) -> T {
67+
match find(self, key) {
68+
None => {
69+
error!("smallintmap::get(): key not present");
70+
fail;
71+
}
72+
Some(move v) => return v
73+
}
74+
}
75+
76+
/// Returns true if the map contains a value for the specified key
77+
pub pure fn contains_key<T: Copy>(self: SmallIntMap<T>, key: uint) -> bool {
78+
return !find(self, key).is_none();
79+
}
80+
81+
impl<V> SmallIntMap<V>: Container {
82+
/// Return the number of elements in the map
83+
pure fn len(&self) -> uint {
84+
let mut sz = 0u;
85+
for self.v.each |item| {
86+
match *item {
87+
Some(_) => sz += 1u,
88+
_ => ()
89+
}
90+
}
91+
sz
92+
}
93+
94+
/// Return true if the map contains no elements
95+
pure fn is_empty(&self) -> bool { self.len() == 0 }
96+
}
97+
98+
impl<V> SmallIntMap<V>: Mutable {
99+
fn clear(&mut self) { self.v.set(~[]) }
100+
}
101+
102+
/// Implements the map::map interface for smallintmap
103+
impl<V: Copy> SmallIntMap<V> {
104+
#[inline(always)]
105+
fn insert(key: uint, value: V) -> bool {
106+
let exists = contains_key(self, key);
107+
insert(self, key, value);
108+
return !exists;
109+
}
110+
fn remove(key: uint) -> bool {
111+
if key >= self.v.len() {
112+
return false;
113+
}
114+
let old = self.v.get_elt(key);
115+
self.v.set_elt(key, None);
116+
old.is_some()
117+
}
118+
pure fn contains_key(key: uint) -> bool {
119+
contains_key(self, key)
120+
}
121+
pure fn contains_key_ref(key: &uint) -> bool {
122+
contains_key(self, *key)
123+
}
124+
pure fn get(key: uint) -> V { get(self, key) }
125+
pure fn find(key: uint) -> Option<V> { find(self, key) }
126+
127+
fn update_with_key(key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool {
128+
match self.find(key) {
129+
None => return self.insert(key, val),
130+
Some(copy orig) => return self.insert(key, ff(key, orig, val)),
131+
}
132+
}
133+
134+
fn update(key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
135+
return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1));
136+
}
137+
138+
pure fn each(it: fn(key: uint, value: V) -> bool) {
139+
self.each_ref(|k, v| it(*k, *v))
140+
}
141+
pure fn each_key(it: fn(key: uint) -> bool) {
142+
self.each_ref(|k, _v| it(*k))
143+
}
144+
pure fn each_value(it: fn(value: V) -> bool) {
145+
self.each_ref(|_k, v| it(*v))
146+
}
147+
pure fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
148+
let mut idx = 0u, l = self.v.len();
149+
while idx < l {
150+
match self.v.get_elt(idx) {
151+
Some(ref elt) => if !it(&idx, elt) { break },
152+
None => ()
153+
}
154+
idx += 1u;
155+
}
156+
}
157+
pure fn each_key_ref(blk: fn(key: &uint) -> bool) {
158+
self.each_ref(|k, _v| blk(k))
159+
}
160+
pure fn each_value_ref(blk: fn(value: &V) -> bool) {
161+
self.each_ref(|_k, v| blk(v))
162+
}
163+
}
164+
165+
impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
166+
pure fn index(&self, key: uint) -> V {
167+
unsafe {
168+
get(*self, key)
169+
}
170+
}
171+
}
172+
173+
#[cfg(test)]
174+
mod tests {
175+
use super::{mk, SmallIntMap};
176+
177+
use core::option::None;
178+
179+
#[test]
180+
fn test_len() {
181+
let mut map = mk();
182+
assert map.len() == 0;
183+
assert map.is_empty();
184+
map.insert(5, 20);
185+
assert map.len() == 1;
186+
assert !map.is_empty();
187+
map.insert(11, 12);
188+
assert map.len() == 2;
189+
assert !map.is_empty();
190+
map.insert(14, 22);
191+
assert map.len() == 3;
192+
assert !map.is_empty();
193+
}
194+
195+
#[test]
196+
fn test_clear() {
197+
let mut map = mk();
198+
map.insert(5, 20);
199+
map.insert(11, 12);
200+
map.insert(14, 22);
201+
map.clear();
202+
assert map.is_empty();
203+
assert map.find(5).is_none();
204+
assert map.find(11).is_none();
205+
assert map.find(14).is_none();
206+
}
207+
208+
#[test]
209+
fn test_insert_with_key() {
210+
let map: SmallIntMap<uint> = mk();
211+
212+
// given a new key, initialize it with this new count, given
213+
// given an existing key, add more to its count
214+
fn addMoreToCount(_k: uint, v0: uint, v1: uint) -> uint {
215+
v0 + v1
216+
}
217+
218+
fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
219+
v0 + v1
220+
}
221+
222+
// count integers
223+
map.update(3, 1, addMoreToCount_simple);
224+
map.update_with_key(9, 1, addMoreToCount);
225+
map.update(3, 7, addMoreToCount_simple);
226+
map.update_with_key(5, 3, addMoreToCount);
227+
map.update_with_key(3, 2, addMoreToCount);
228+
229+
// check the total counts
230+
assert map.find(3).get() == 10;
231+
assert map.find(5).get() == 3;
232+
assert map.find(9).get() == 1;
233+
234+
// sadly, no sevens were counted
235+
assert None == map.find(7);
236+
}
237+
}

0 commit comments

Comments
 (0)