Skip to content

modernize smallintmap module #4733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 1, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ use core::uint;
use core::vec;
use std::map::{Map, HashMap};
use std::map;
use std::smallintmap::{Map, SmallIntMap};
use std::smallintmap;
use std::oldsmallintmap::{Map, SmallIntMap};
use std::oldsmallintmap;
use syntax::ast_util::{path_to_ident};
use syntax::attr;
use syntax::codemap::span;
Expand Down Expand Up @@ -248,7 +248,7 @@ pub type lint_settings = {
};

pub fn mk_lint_settings() -> lint_settings {
{default_settings: smallintmap::mk(),
{default_settings: oldsmallintmap::mk(),
settings_map: HashMap()}
}

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

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

pub fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
let cx = ctxt_({dict: get_lint_dict(),
curr: smallintmap::mk(),
curr: oldsmallintmap::mk(),
is_default: true,
sess: sess});

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ use core::option::{is_none, is_some};
use core::option;
use core::uint;
use std::map::HashMap;
use std::smallintmap;
use std::oldsmallintmap;
use std::{map, time, list};
use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name};
use syntax::ast_util::{def_id_of_def, local_def, path_to_ident};
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use core::to_bytes;
use core::uint;
use core::vec;
use std::map::HashMap;
use std::{map, smallintmap};
use std::{map, oldsmallintmap};
use syntax::ast::*;
use syntax::ast_util::{is_local, local_def};
use syntax::ast_util;
Expand Down Expand Up @@ -785,7 +785,7 @@ type type_cache = HashMap<ast::def_id, ty_param_bounds_and_ty>;

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

pub type node_type_table = @smallintmap::SmallIntMap<t>;
pub type node_type_table = @oldsmallintmap::SmallIntMap<t>;

fn mk_rcache() -> creader_cache {
type val = {cnum: int, pos: uint, len: uint};
Expand Down Expand Up @@ -837,7 +837,7 @@ pub fn mk_ctxt(s: session::Session,
def_map: dm,
region_map: region_map,
region_paramd_items: region_paramd_items,
node_types: @smallintmap::mk(),
node_types: @oldsmallintmap::mk(),
node_type_substs: map::HashMap(),
items: amap,
intrinsic_defs: map::HashMap(),
Expand Down Expand Up @@ -2799,7 +2799,7 @@ pub fn br_hashmap<V:Copy>() -> HashMap<bound_region, V> {

pub fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t {
//io::println(fmt!("%?/%?", id, cx.node_types.size()));
match smallintmap::find(*cx.node_types, id as uint) {
match oldsmallintmap::find(*cx.node_types, id as uint) {
Some(t) => t,
None => cx.sess.bug(
fmt!("node_id_to_type: no type for node `%s`",
Expand Down Expand Up @@ -3175,7 +3175,7 @@ pub fn expr_kind(tcx: ctxt,
}

ast::expr_cast(*) => {
match smallintmap::find(*tcx.node_types, expr.id as uint) {
match oldsmallintmap::find(*tcx.node_types, expr.id as uint) {
Some(t) => {
if ty::type_is_immediate(t) {
RvalueDatumExpr
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ use core::result;
use core::vec;
use std::list::Nil;
use std::map::HashMap;
use std::smallintmap;
use std::oldsmallintmap;
use syntax::ast::{ret_style, purity};
use syntax::ast::{m_const, m_imm, m_mutbl};
use syntax::ast::{unsafe_fn, impure_fn, pure_fn, extern_fn};
Expand Down Expand Up @@ -353,7 +353,7 @@ pub fn fixup_err_to_str(f: fixup_err) -> ~str {

fn new_ValsAndBindings<V:Copy, T:Copy>() -> ValsAndBindings<V, T> {
ValsAndBindings {
vals: smallintmap::mk(),
vals: oldsmallintmap::mk(),
mut bindings: ~[]
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/infer/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use core::prelude::*;
use core::result;
use std::smallintmap::SmallIntMap;
use std::oldsmallintmap::SmallIntMap;

use middle::ty::{Vid, expected_found, IntVarValue};
use middle::ty;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ use std::list::{List, Nil, Cons};
use std::list;
use std::map::HashMap;
use std::map;
use std::smallintmap;
use std::oldsmallintmap;
use syntax::ast::{provided, required, spanned};
use syntax::ast_map::node_id_to_str;
use syntax::ast_util::{local_def, respan, split_trait_methods};
Expand Down Expand Up @@ -212,7 +212,7 @@ pub enum crate_ctxt {
// Functions that write types into the node type table
pub fn write_ty_to_tcx(tcx: ty::ctxt, node_id: ast::node_id, ty: ty::t) {
debug!("write_ty_to_tcx(%d, %s)", node_id, ppaux::ty_to_str(tcx, ty));
smallintmap::insert(*tcx.node_types, node_id as uint, ty);
oldsmallintmap::insert(*tcx.node_types, node_id as uint, ty);
}
pub fn write_substs_to_tcx(tcx: ty::ctxt,
node_id: ast::node_id,
Expand Down
237 changes: 237 additions & 0 deletions src/libstd/oldsmallintmap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
* A simple map based on a vector for small integer keys. Space requirements
* are O(highest integer key).
*/
#[forbid(deprecated_mode)];

use core::container::{Container, Mutable, Map, Set};
use core::dvec::DVec;
use core::ops;
use core::option::{Some, None};
use core::option;
use core::prelude::*;

// FIXME (#2347): Should not be @; there's a bug somewhere in rustc that
// requires this to be.
struct SmallIntMap_<T> {
v: DVec<Option<T>>,
}

pub enum SmallIntMap<T> {
SmallIntMap_(@SmallIntMap_<T>)
}

/// Create a smallintmap
pub fn mk<T: Copy>() -> SmallIntMap<T> {
let v = DVec();
SmallIntMap_(@SmallIntMap_ { v: v } )
}

/**
* Add a value to the map. If the map already contains a value for
* the specified key then the original value is replaced.
*/
#[inline(always)]
pub fn insert<T: Copy>(self: SmallIntMap<T>, key: uint, val: T) {
//io::println(fmt!("%?", key));
self.v.grow_set_elt(key, &None, Some(val));
}

/**
* Get the value for the specified key. If the key does not exist
* in the map then returns none
*/
pub pure fn find<T: Copy>(self: SmallIntMap<T>, key: uint) -> Option<T> {
if key < self.v.len() { return self.v.get_elt(key); }
return None::<T>;
}

/**
* Get the value for the specified key
*
* # Failure
*
* If the key does not exist in the map
*/
pub pure fn get<T: Copy>(self: SmallIntMap<T>, key: uint) -> T {
match find(self, key) {
None => {
error!("smallintmap::get(): key not present");
die!();
}
Some(move v) => return v
}
}

/// Returns true if the map contains a value for the specified key
pub pure fn contains_key<T: Copy>(self: SmallIntMap<T>, key: uint) -> bool {
return !find(self, key).is_none();
}

impl<V> SmallIntMap<V>: Container {
/// Return the number of elements in the map
pure fn len(&self) -> uint {
let mut sz = 0u;
for self.v.each |item| {
match *item {
Some(_) => sz += 1u,
_ => ()
}
}
sz
}

/// Return true if the map contains no elements
pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<V> SmallIntMap<V>: Mutable {
fn clear(&mut self) { self.v.set(~[]) }
}

/// Implements the map::map interface for smallintmap
impl<V: Copy> SmallIntMap<V> {
#[inline(always)]
fn insert(key: uint, value: V) -> bool {
let exists = contains_key(self, key);
insert(self, key, value);
return !exists;
}
fn remove(key: uint) -> bool {
if key >= self.v.len() {
return false;
}
let old = self.v.get_elt(key);
self.v.set_elt(key, None);
old.is_some()
}
pure fn contains_key(key: uint) -> bool {
contains_key(self, key)
}
pure fn contains_key_ref(key: &uint) -> bool {
contains_key(self, *key)
}
pure fn get(key: uint) -> V { get(self, key) }
pure fn find(key: uint) -> Option<V> { find(self, key) }

fn update_with_key(key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool {
match self.find(key) {
None => return self.insert(key, val),
Some(copy orig) => return self.insert(key, ff(key, orig, val)),
}
}

fn update(key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1));
}

pure fn each(it: fn(key: uint, value: V) -> bool) {
self.each_ref(|k, v| it(*k, *v))
}
pure fn each_key(it: fn(key: uint) -> bool) {
self.each_ref(|k, _v| it(*k))
}
pure fn each_value(it: fn(value: V) -> bool) {
self.each_ref(|_k, v| it(*v))
}
pure fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
let mut idx = 0u, l = self.v.len();
while idx < l {
match self.v.get_elt(idx) {
Some(ref elt) => if !it(&idx, elt) { break },
None => ()
}
idx += 1u;
}
}
pure fn each_key_ref(blk: fn(key: &uint) -> bool) {
self.each_ref(|k, _v| blk(k))
}
pure fn each_value_ref(blk: fn(value: &V) -> bool) {
self.each_ref(|_k, v| blk(v))
}
}

impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
pure fn index(&self, key: uint) -> V {
unsafe {
get(*self, key)
}
}
}

#[cfg(test)]
mod tests {
use super::{mk, SmallIntMap};

use core::option::None;

#[test]
fn test_len() {
let mut map = mk();
assert map.len() == 0;
assert map.is_empty();
map.insert(5, 20);
assert map.len() == 1;
assert !map.is_empty();
map.insert(11, 12);
assert map.len() == 2;
assert !map.is_empty();
map.insert(14, 22);
assert map.len() == 3;
assert !map.is_empty();
}

#[test]
fn test_clear() {
let mut map = mk();
map.insert(5, 20);
map.insert(11, 12);
map.insert(14, 22);
map.clear();
assert map.is_empty();
assert map.find(5).is_none();
assert map.find(11).is_none();
assert map.find(14).is_none();
}

#[test]
fn test_insert_with_key() {
let map: SmallIntMap<uint> = mk();

// given a new key, initialize it with this new count, given
// given an existing key, add more to its count
fn addMoreToCount(_k: uint, v0: uint, v1: uint) -> uint {
v0 + v1
}

fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
v0 + v1
}

// count integers
map.update(3, 1, addMoreToCount_simple);
map.update_with_key(9, 1, addMoreToCount);
map.update(3, 7, addMoreToCount_simple);
map.update_with_key(5, 3, addMoreToCount);
map.update_with_key(3, 2, addMoreToCount);

// check the total counts
assert map.find(3).get() == 10;
assert map.find(5).get() == 3;
assert map.find(9).get() == 1;

// sadly, no sevens were counted
assert None == map.find(7);
}
}
Loading