Skip to content

Commit adb9d0e

Browse files
committed
Merge pull request #4733 from thestinger/smallintmap
modernize smallintmap module
2 parents aee7929 + 74b317d commit adb9d0e

File tree

10 files changed

+381
-153
lines changed

10 files changed

+381
-153
lines changed

src/librustc/middle/lint.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ use core::uint;
3434
use core::vec;
3535
use std::map::{Map, HashMap};
3636
use std::map;
37-
use std::smallintmap::{Map, SmallIntMap};
38-
use std::smallintmap;
37+
use std::oldsmallintmap::{Map, SmallIntMap};
38+
use std::oldsmallintmap;
3939
use syntax::ast_util::{path_to_ident};
4040
use syntax::attr;
4141
use syntax::codemap::span;
@@ -248,7 +248,7 @@ pub type lint_settings = {
248248
};
249249

250250
pub fn mk_lint_settings() -> lint_settings {
251-
{default_settings: smallintmap::mk(),
251+
{default_settings: oldsmallintmap::mk(),
252252
settings_map: HashMap()}
253253
}
254254

@@ -273,7 +273,8 @@ pub fn get_lint_settings_level(settings: lint_settings,
273273
// This is kind of unfortunate. It should be somewhere else, or we should use
274274
// a persistent data structure...
275275
fn clone_lint_modes(modes: lint_modes) -> lint_modes {
276-
smallintmap::SmallIntMap_(@smallintmap::SmallIntMap_ { v: copy modes.v })
276+
oldsmallintmap::SmallIntMap_(@oldsmallintmap::SmallIntMap_
277+
{v: copy modes.v})
277278
}
278279

279280
type ctxt_ = {dict: lint_dict,
@@ -393,7 +394,7 @@ fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt<ctxt>) {
393394

394395
pub fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
395396
let cx = ctxt_({dict: get_lint_dict(),
396-
curr: smallintmap::mk(),
397+
curr: oldsmallintmap::mk(),
397398
is_default: true,
398399
sess: sess});
399400

src/librustc/middle/trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use core::option::{is_none, is_some};
7676
use core::option;
7777
use core::uint;
7878
use std::map::HashMap;
79-
use std::smallintmap;
79+
use std::oldsmallintmap;
8080
use std::{map, time, list};
8181
use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name};
8282
use syntax::ast_util::{def_id_of_def, local_def, path_to_ident};

src/librustc/middle/ty.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use core::to_bytes;
4242
use core::uint;
4343
use core::vec;
4444
use std::map::HashMap;
45-
use std::{map, smallintmap};
45+
use std::{map, oldsmallintmap};
4646
use syntax::ast::*;
4747
use syntax::ast_util::{is_local, local_def};
4848
use syntax::ast_util;
@@ -785,7 +785,7 @@ type type_cache = HashMap<ast::def_id, ty_param_bounds_and_ty>;
785785

786786
type constness_cache = HashMap<ast::def_id, const_eval::constness>;
787787

788-
pub type node_type_table = @smallintmap::SmallIntMap<t>;
788+
pub type node_type_table = @oldsmallintmap::SmallIntMap<t>;
789789

790790
fn mk_rcache() -> creader_cache {
791791
type val = {cnum: int, pos: uint, len: uint};
@@ -837,7 +837,7 @@ pub fn mk_ctxt(s: session::Session,
837837
def_map: dm,
838838
region_map: region_map,
839839
region_paramd_items: region_paramd_items,
840-
node_types: @smallintmap::mk(),
840+
node_types: @oldsmallintmap::mk(),
841841
node_type_substs: map::HashMap(),
842842
items: amap,
843843
intrinsic_defs: map::HashMap(),
@@ -2799,7 +2799,7 @@ pub fn br_hashmap<V:Copy>() -> HashMap<bound_region, V> {
27992799
28002800
pub fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t {
28012801
//io::println(fmt!("%?/%?", id, cx.node_types.size()));
2802-
match smallintmap::find(*cx.node_types, id as uint) {
2802+
match oldsmallintmap::find(*cx.node_types, id as uint) {
28032803
Some(t) => t,
28042804
None => cx.sess.bug(
28052805
fmt!("node_id_to_type: no type for node `%s`",
@@ -3175,7 +3175,7 @@ pub fn expr_kind(tcx: ctxt,
31753175
}
31763176
31773177
ast::expr_cast(*) => {
3178-
match smallintmap::find(*tcx.node_types, expr.id as uint) {
3178+
match oldsmallintmap::find(*tcx.node_types, expr.id as uint) {
31793179
Some(t) => {
31803180
if ty::type_is_immediate(t) {
31813181
RvalueDatumExpr

src/librustc/middle/typeck/infer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ use core::result;
281281
use core::vec;
282282
use std::list::Nil;
283283
use std::map::HashMap;
284-
use std::smallintmap;
284+
use std::oldsmallintmap;
285285
use syntax::ast::{ret_style, purity};
286286
use syntax::ast::{m_const, m_imm, m_mutbl};
287287
use syntax::ast::{unsafe_fn, impure_fn, pure_fn, extern_fn};
@@ -353,7 +353,7 @@ pub fn fixup_err_to_str(f: fixup_err) -> ~str {
353353

354354
fn new_ValsAndBindings<V:Copy, T:Copy>() -> ValsAndBindings<V, T> {
355355
ValsAndBindings {
356-
vals: smallintmap::mk(),
356+
vals: oldsmallintmap::mk(),
357357
mut bindings: ~[]
358358
}
359359
}

src/librustc/middle/typeck/infer/unify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use core::prelude::*;
1212
use core::result;
13-
use std::smallintmap::SmallIntMap;
13+
use std::oldsmallintmap::SmallIntMap;
1414

1515
use middle::ty::{Vid, expected_found, IntVarValue};
1616
use middle::ty;

src/librustc/middle/typeck/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use std::list::{List, Nil, Cons};
6969
use std::list;
7070
use std::map::HashMap;
7171
use std::map;
72-
use std::smallintmap;
72+
use std::oldsmallintmap;
7373
use syntax::ast::{provided, required, spanned};
7474
use syntax::ast_map::node_id_to_str;
7575
use syntax::ast_util::{local_def, respan, split_trait_methods};
@@ -212,7 +212,7 @@ pub enum crate_ctxt {
212212
// Functions that write types into the node type table
213213
pub fn write_ty_to_tcx(tcx: ty::ctxt, node_id: ast::node_id, ty: ty::t) {
214214
debug!("write_ty_to_tcx(%d, %s)", node_id, ppaux::ty_to_str(tcx, ty));
215-
smallintmap::insert(*tcx.node_types, node_id as uint, ty);
215+
oldsmallintmap::insert(*tcx.node_types, node_id as uint, ty);
216216
}
217217
pub fn write_substs_to_tcx(tcx: ty::ctxt,
218218
node_id: ast::node_id,

src/libstd/oldsmallintmap.rs

+237
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+
die!();
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)