Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
adb9d0e8
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
adb9d0e8
编写于
1月 31, 2013
作者:
T
Tim Chevalier
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4733 from thestinger/smallintmap
modernize smallintmap module
上级
aee79294
74b317dd
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
381 addition
and
153 deletion
+381
-153
src/librustc/middle/lint.rs
src/librustc/middle/lint.rs
+6
-5
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/base.rs
+1
-1
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+5
-5
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/mod.rs
+2
-2
src/librustc/middle/typeck/infer/unify.rs
src/librustc/middle/typeck/infer/unify.rs
+1
-1
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/mod.rs
+2
-2
src/libstd/oldsmallintmap.rs
src/libstd/oldsmallintmap.rs
+237
-0
src/libstd/smallintmap.rs
src/libstd/smallintmap.rs
+120
-130
src/libstd/std.rc
src/libstd/std.rc
+1
-0
src/test/bench/std-smallintmap.rs
src/test/bench/std-smallintmap.rs
+6
-7
未找到文件。
src/librustc/middle/lint.rs
浏览文件 @
adb9d0e8
...
...
@@ -34,8 +34,8 @@
use
core
::
vec
;
use
std
::
map
::{
Map
,
HashMap
};
use
std
::
map
;
use
std
::
smallintmap
::{
Map
,
SmallIntMap
};
use
std
::
smallintmap
;
use
std
::
old
smallintmap
::{
Map
,
SmallIntMap
};
use
std
::
old
smallintmap
;
use
syntax
::
ast_util
::{
path_to_ident
};
use
syntax
::
attr
;
use
syntax
::
codemap
::
span
;
...
...
@@ -248,7 +248,7 @@ pub fn get_lint_dict() -> lint_dict {
};
pub
fn
mk_lint_settings
()
->
lint_settings
{
{
default_settings
:
smallintmap
::
mk
(),
{
default_settings
:
old
smallintmap
::
mk
(),
settings_map
:
HashMap
()}
}
...
...
@@ -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
,
...
...
@@ -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
:
old
smallintmap
::
mk
(),
is_default
:
true
,
sess
:
sess
});
...
...
src/librustc/middle/trans/base.rs
浏览文件 @
adb9d0e8
...
...
@@ -76,7 +76,7 @@
use
core
::
option
;
use
core
::
uint
;
use
std
::
map
::
HashMap
;
use
std
::
smallintmap
;
use
std
::
old
smallintmap
;
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
};
...
...
src/librustc/middle/ty.rs
浏览文件 @
adb9d0e8
...
...
@@ -42,7 +42,7 @@
use
core
::
uint
;
use
core
::
vec
;
use
std
::
map
::
HashMap
;
use
std
::{
map
,
smallintmap
};
use
std
::{
map
,
old
smallintmap
};
use
syntax
::
ast
::
*
;
use
syntax
::
ast_util
::{
is_local
,
local_def
};
use
syntax
::
ast_util
;
...
...
@@ -785,7 +785,7 @@ pub fn param_bounds_to_kind(bounds: param_bounds) -> Kind {
type
constness_cache
=
HashMap
<
ast
::
def_id
,
const_eval
::
constness
>
;
pub
type
node_type_table
=
@
smallintmap
::
SmallIntMap
<
t
>
;
pub
type
node_type_table
=
@
old
smallintmap
::
SmallIntMap
<
t
>
;
fn
mk_rcache
()
->
creader_cache
{
type
val
=
{
cnum
:
int
,
pos
:
uint
,
len
:
uint
};
...
...
@@ -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
:
@
old
smallintmap
::
mk
(),
node_type_substs
:
map
::
HashMap
(),
items
:
amap
,
intrinsic_defs
:
map
::
HashMap
(),
...
...
@@ -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
old
smallintmap
::
find
(
*
cx
.node_types
,
id
as
uint
)
{
Some
(
t
)
=>
t
,
None
=>
cx
.sess
.bug
(
fmt!
(
"node_id_to_type: no type for node `%s`"
,
...
...
@@ -3175,7 +3175,7 @@ pub fn expr_kind(tcx: ctxt,
}
ast
::
expr_cast
(
*
)
=>
{
match
smallintmap
::
find
(
*
tcx
.node_types
,
expr
.id
as
uint
)
{
match
old
smallintmap
::
find
(
*
tcx
.node_types
,
expr
.id
as
uint
)
{
Some
(
t
)
=>
{
if
ty
::
type_is_immediate
(
t
)
{
RvalueDatumExpr
...
...
src/librustc/middle/typeck/infer/mod.rs
浏览文件 @
adb9d0e8
...
...
@@ -281,7 +281,7 @@ fn bar() {
use
core
::
vec
;
use
std
::
list
::
Nil
;
use
std
::
map
::
HashMap
;
use
std
::
smallintmap
;
use
std
::
old
smallintmap
;
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
};
...
...
@@ -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
:
old
smallintmap
::
mk
(),
mut
bindings
:
~
[]
}
}
...
...
src/librustc/middle/typeck/infer/unify.rs
浏览文件 @
adb9d0e8
...
...
@@ -10,7 +10,7 @@
use
core
::
prelude
::
*
;
use
core
::
result
;
use
std
::
smallintmap
::
SmallIntMap
;
use
std
::
old
smallintmap
::
SmallIntMap
;
use
middle
::
ty
::{
Vid
,
expected_found
,
IntVarValue
};
use
middle
::
ty
;
...
...
src/librustc/middle/typeck/mod.rs
浏览文件 @
adb9d0e8
...
...
@@ -69,7 +69,7 @@
use
std
::
list
;
use
std
::
map
::
HashMap
;
use
std
::
map
;
use
std
::
smallintmap
;
use
std
::
old
smallintmap
;
use
syntax
::
ast
::{
provided
,
required
,
spanned
};
use
syntax
::
ast_map
::
node_id_to_str
;
use
syntax
::
ast_util
::{
local_def
,
respan
,
split_trait_methods
};
...
...
@@ -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
);
old
smallintmap
::
insert
(
*
tcx
.node_types
,
node_id
as
uint
,
ty
);
}
pub
fn
write_substs_to_tcx
(
tcx
:
ty
::
ctxt
,
node_id
:
ast
::
node_id
,
...
...
src/libstd/oldsmallintmap.rs
0 → 100644
浏览文件 @
adb9d0e8
// 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
);
}
}
src/libstd/smallintmap.rs
浏览文件 @
adb9d0e8
...
...
@@ -14,171 +14,161 @@
*/
#[forbid(deprecated_mode)]
;
use
map
;
use
map
::
StdMap
;
use
core
::
dvec
::
DVec
;
use
core
::
ops
;
use
core
::
container
::{
Container
,
Mutable
,
Map
,
Set
};
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
>
)
pub
struct
SmallIntMap
<
T
>
{
priv
v
:
~
[
Option
<
T
>
],
}
/// Create a smallintmap
pub
fn
mk
<
T
:
Copy
>
()
->
SmallIntMap
<
T
>
{
let
v
=
DVec
();
SmallIntMap_
(
@
SmallIntMap_
{
v
:
v
}
)
}
impl
<
V
>
SmallIntMap
<
V
>
:
Container
{
/// Return the number of elements in the map
pure
fn
len
(
&
self
)
->
uint
{
let
mut
sz
=
0
;
for
self
.v.each
|
item
|
{
if
item
.is_some
()
{
sz
+=
1
;
}
}
sz
}
/**
* 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
));
/// Return true if the map contains no elements
pure
fn
is_empty
(
&
self
)
->
bool
{
self
.len
()
==
0
}
}
/**
* 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
>
;
impl
<
V
>
SmallIntMap
<
V
>
:
Mutable
{
/// Clear the map, removing all key-value pairs.
fn
clear
(
&
mut
self
)
{
self
.v
.clear
()
}
}
/**
* 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
impl
<
V
>
SmallIntMap
<
V
>
:
Map
<
uint
,
V
>
{
/// Return true if the map contains a value for the specified key
pure
fn
contains_key
(
&
self
,
key
:
&
uint
)
->
bool
{
self
.find
(
key
)
.is_some
()
}
}
/// 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
();
}
/// Implements the map::map interface for smallintmap
impl
<
V
:
Copy
>
SmallIntMap
<
V
>
:
map
::
StdMap
<
uint
,
V
>
{
pure
fn
size
()
->
uint
{
let
mut
sz
=
0u
;
for
self
.v.each
|
item
|
{
match
*
item
{
Some
(
_
)
=>
sz
+=
1u
,
_
=>
()
/// Visit all key-value pairs
pure
fn
each
(
&
self
,
it
:
fn
(
key
:
&
uint
,
value
:
&
V
)
->
bool
)
{
for
uint
::
range
(
0
,
self
.v
.len
())
|
i
|
{
match
self
.v
[
i
]
{
Some
(
ref
elt
)
=>
if
!
it
(
&
i
,
elt
)
{
break
},
None
=>
()
}
}
sz
}
#[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
()
}
fn
clear
()
{
self
.v
.set
(
~
[]);
}
pure
fn
contains_key
(
key
:
uint
)
->
bool
{
contains_key
(
self
,
key
)
/// Visit all keys
pure
fn
each_key
(
&
self
,
blk
:
fn
(
key
:
&
uint
)
->
bool
)
{
self
.each
(|
k
,
_
|
blk
(
k
))
}
pure
fn
contains_key_ref
(
key
:
&
uint
)
->
bool
{
contains_key
(
self
,
*
key
)
/// Visit all values
pure
fn
each_value
(
&
self
,
blk
:
fn
(
value
:
&
V
)
->
bool
)
{
self
.each
(|
_
,
v
|
blk
(
v
))
}
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
)),
/// Return the value corresponding to the key in the map
pure
fn
find
(
&
self
,
key
:
&
uint
)
->
Option
<&
self
/
V
>
{
if
*
key
<
self
.v
.len
()
{
match
self
.v
[
*
key
]
{
Some
(
ref
value
)
=>
Some
(
value
),
None
=>
None
}
}
else
{
None
}
}
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
));
/// 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.
fn
insert
(
&
mut
self
,
key
:
uint
,
value
:
V
)
->
bool
{
let
exists
=
self
.contains_key
(
&
key
);
let
len
=
self
.v
.len
();
if
len
<=
key
{
vec
::
grow_fn
(
&
mut
self
.v
,
key
-
len
+
1
,
|
_
|
None
);
}
self
.v
[
key
]
=
Some
(
value
);
!
exists
}
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
;
/// Remove a key-value pair from the map. Return true if the key
/// was present in the map, otherwise false.
fn
remove
(
&
mut
self
,
key
:
&
uint
)
->
bool
{
if
*
key
>=
self
.v
.len
()
{
return
false
;
}
let
removed
=
self
.v
[
*
key
]
.is_some
();
self
.v
[
*
key
]
=
None
;
removed
}
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
))
}
pub
impl
<
V
>
SmallIntMap
<
V
>
{
/// Create an empty SmallIntMap
static
pure
fn
new
()
->
SmallIntMap
<
V
>
{
SmallIntMap
{
v
:
~
[]}
}
pure
fn
get
(
&
self
,
key
:
&
uint
)
->
&
self
/
V
{
self
.find
(
key
)
.expect
(
"key not present"
)
}
}
impl
<
V
:
Copy
>
SmallIntMap
<
V
>
:
ops
::
Index
<
uint
,
V
>
{
pure
fn
index
(
&
self
,
key
:
uint
)
->
V
{
unsafe
{
get
(
*
self
,
key
)
pub
impl
<
V
:
Copy
>
SmallIntMap
<
V
>
{
// FIXME: #4733, remove after the next snapshot
#[cfg(stage2)]
fn
update_with_key
(
&
mut
self
,
key
:
uint
,
val
:
V
,
ff
:
fn
(
uint
,
V
,
V
)
->
V
)
->
bool
{
match
self
.find
(
&
key
)
{
None
=>
self
.insert
(
key
,
val
),
Some
(
orig
)
=>
self
.insert
(
key
,
ff
(
key
,
copy
*
orig
,
val
)),
}
}
}
/// Cast the given smallintmap to a map::map
pub
fn
as_map
<
V
:
Copy
>
(
s
:
SmallIntMap
<
V
>
)
->
map
::
StdMap
<
uint
,
V
>
{
s
as
map
::
StdMap
::
<
uint
,
V
>
// FIXME: #4733, remove after the next snapshot
#[cfg(stage2)]
fn
update
(
&
mut
self
,
key
:
uint
,
newval
:
V
,
ff
:
fn
(
V
,
V
)
->
V
)
->
bool
{
self
.update_with_key
(
key
,
newval
,
|
_
k
,
v
,
v1
|
ff
(
v
,
v1
))
}
}
#[cfg(test)]
mod
tests
{
use
s
mallintmap
::{
mk
,
SmallIntMap
}
;
use
s
uper
::
SmallIntMap
;
use
core
::
option
::
None
;
use
core
::
option
;
#[test]
fn
test_len
()
{
let
mut
map
=
SmallIntMap
::
new
();
assert
map
.len
()
==
0
;
assert
map
.is_empty
();
assert
map
.insert
(
5
,
20
);
assert
map
.len
()
==
1
;
assert
!
map
.is_empty
();
assert
map
.insert
(
11
,
12
);
assert
map
.len
()
==
2
;
assert
!
map
.is_empty
();
assert
map
.insert
(
14
,
22
);
assert
map
.len
()
==
3
;
assert
!
map
.is_empty
();
}
#[test]
fn
test_clear
()
{
let
mut
map
=
SmallIntMap
::
new
();
assert
map
.insert
(
5
,
20
);
assert
map
.insert
(
11
,
12
);
assert
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
m
ap
:
SmallIntMap
<
uint
>
=
mk
();
let
m
ut
map
=
SmallIntMap
::
new
();
// given a new key, initialize it with this new count, given
// given an existing key, add more to its count
...
...
@@ -198,11 +188,11 @@ fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
map
.update_with_key
(
3
,
2
,
addMoreToCount
);
// check the total counts
assert
10
==
option
::
get
(
map
.find
(
3
))
;
assert
3
==
option
::
get
(
map
.find
(
5
))
;
assert
1
==
option
::
get
(
map
.find
(
9
))
;
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
);
assert
map
.find
(
&
7
)
.is_none
(
);
}
}
src/libstd/std.rc
浏览文件 @
adb9d0e8
...
...
@@ -83,6 +83,7 @@ pub mod map;
pub mod priority_queue;
pub mod rope;
pub mod smallintmap;
pub mod oldsmallintmap;
pub mod sort;
pub mod treemap;
...
...
src/test/bench/std-smallintmap.rs
浏览文件 @
adb9d0e8
...
...
@@ -11,19 +11,18 @@
// Microbenchmark for the smallintmap library
extern
mod
std
;
use
std
::
smallintmap
;
use
std
::
smallintmap
::
SmallIntMap
;
use
io
::
WriterUtil
;
fn
append_sequential
(
min
:
uint
,
max
:
uint
,
map
:
SmallIntMap
<
uint
>
)
{
fn
append_sequential
(
min
:
uint
,
max
:
uint
,
map
:
&
mut
SmallIntMap
<
uint
>
)
{
for
uint
::
range
(
min
,
max
)
|
i
|
{
map
.insert
(
i
,
i
+
22u
);
}
}
fn
check_sequential
(
min
:
uint
,
max
:
uint
,
map
:
SmallIntMap
<
uint
>
)
{
fn
check_sequential
(
min
:
uint
,
max
:
uint
,
map
:
&
SmallIntMap
<
uint
>
)
{
for
uint
::
range
(
min
,
max
)
|
i
|
{
assert
map
.get
(
i
)
==
i
+
22u
;
assert
*
map
.get
(
&
i
)
==
i
+
22u
;
}
}
...
...
@@ -43,11 +42,11 @@ fn main() {
let
mut
appendf
=
0.0
;
for
uint
::
range
(
0u
,
rep
)
|
_
r
|
{
let
m
ap
=
smallintmap
::
mk
();
let
m
ut
map
=
SmallIntMap
::
new
();
let
start
=
std
::
time
::
precise_time_s
();
append_sequential
(
0u
,
max
,
map
);
append_sequential
(
0u
,
max
,
&
mut
map
);
let
mid
=
std
::
time
::
precise_time_s
();
check_sequential
(
0u
,
max
,
map
);
check_sequential
(
0u
,
max
,
&
map
);
let
end
=
std
::
time
::
precise_time_s
();
checkf
+=
(
end
-
mid
)
as
float
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录