Skip to content

Commit 6a58537

Browse files
committed
std: Recreate a collections module
As with the previous commit with `librand`, this commit shuffles around some `collections` code. The new state of the world is similar to that of librand: * The libcollections crate now only depends on libcore and liballoc. * The standard library has a new module, `std::collections`. All functionality of libcollections is reexported through this module. I would like to stress that this change is purely cosmetic. There are very few alterations to these primitives. There are a number of notable points about the new organization: * std::{str, slice, string, vec} all moved to libcollections. There is no reason that these primitives shouldn't be necessarily usable in a freestanding context that has allocation. These are all reexported in their usual places in the standard library. * The `hashmap`, and transitively the `lru_cache`, modules no longer reside in `libcollections`, but rather in libstd. The reason for this is because the `HashMap::new` contructor requires access to the OSRng for initially seeding the hash map. Beyond this requirement, there is no reason that the hashmap could not move to libcollections. I do, however, have a plan to move the hash map to the collections module. The `HashMap::new` function could be altered to require that the `H` hasher parameter ascribe to the `Default` trait, allowing the entire `hashmap` module to live in libcollections. The key idea would be that the default hasher would be different in libstd. Something along the lines of: // src/libstd/collections/mod.rs pub type HashMap<K, V, H = RandomizedSipHasher> = core_collections::HashMap<K, V, H>; This is not possible today because you cannot invoke static methods through type aliases. If we modified the compiler, however, to allow invocation of static methods through type aliases, then this type definition would essentially be switching the default hasher from `SipHasher` in libcollections to a libstd-defined `RandomizedSipHasher` type. This type's `Default` implementation would randomly seed the `SipHasher` instance, and otherwise perform the same as `SipHasher`. This future state doesn't seem incredibly far off, but until that time comes, the hashmap module will live in libstd to not compromise on functionality. * In preparation for the hashmap moving to libcollections, the `hash` module has moved from libstd to libcollections. A previously snapshotted commit enables a distinct `Writer` trait to live in the `hash` module which `Hash` implementations are now parameterized over. Due to using a custom trait, the `SipHasher` implementation has lost its specialized methods for writing integers. These can be re-added backwards-compatibly in the future via default methods if necessary, but the FNV hashing should satisfy much of the need for speedier hashing. A list of breaking changes: * HashMap::{get, get_mut} no longer fails with the key formatted into the error message with `{:?}`, instead, a generic message is printed. With backtraces, it should still be not-too-hard to track down errors. * The HashMap, HashSet, and LruCache types are now available through std::collections instead of the collections crate. * Manual implementations of hash should be parameterized over `hash::Writer` instead of just `Writer`. [breaking-change]
1 parent d70a9b9 commit 6a58537

30 files changed

+398
-372
lines changed

mk/crates.mk

+12-11
Original file line numberDiff line numberDiff line change
@@ -60,36 +60,36 @@ DEPS_core :=
6060
DEPS_rlibc :=
6161
DEPS_alloc := core libc native:jemalloc
6262
DEPS_debug := std
63-
DEPS_std := core rand libc alloc native:rustrt native:backtrace
63+
DEPS_std := core rand libc alloc collections native:rustrt native:backtrace
6464
DEPS_graphviz := std
6565
DEPS_green := std native:context_switch
6666
DEPS_rustuv := std native:uv native:uv_support
6767
DEPS_native := std
68-
DEPS_syntax := std term serialize collections log fmt_macros debug
68+
DEPS_syntax := std term serialize log fmt_macros debug
6969
DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
70-
collections time log graphviz debug
71-
DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \
70+
time log graphviz debug
71+
DEPS_rustdoc := rustc native:hoedown serialize sync getopts \
7272
test time debug
7373
DEPS_flate := std native:miniz
74-
DEPS_arena := std collections
74+
DEPS_arena := std
7575
DEPS_graphviz := std
7676
DEPS_glob := std
77-
DEPS_serialize := std collections log
78-
DEPS_term := std collections log
77+
DEPS_serialize := std log
78+
DEPS_term := std log
7979
DEPS_semver := std
8080
DEPS_uuid := std serialize
8181
DEPS_sync := std alloc
8282
DEPS_getopts := std
83-
DEPS_collections := std debug
83+
DEPS_collections := core alloc
8484
DEPS_fourcc := syntax std
8585
DEPS_hexfloat := syntax std
8686
DEPS_num := std
87-
DEPS_test := std collections getopts serialize term time regex
87+
DEPS_test := std getopts serialize term time regex
8888
DEPS_time := std serialize sync
8989
DEPS_rand := core
90-
DEPS_url := std collections
90+
DEPS_url := std
9191
DEPS_log := std sync
92-
DEPS_regex := std collections
92+
DEPS_regex := std
9393
DEPS_regex_macros = syntax std regex
9494
DEPS_fmt_macros = std
9595

@@ -105,6 +105,7 @@ ONLY_RLIB_libc := 1
105105
ONLY_RLIB_rlibc := 1
106106
ONLY_RLIB_alloc := 1
107107
ONLY_RLIB_rand := 1
108+
ONLY_RLIB_collections := 1
108109

109110
################################################################################
110111
# You should not need to edit below this line

src/libcollections/bitv.rs

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

1111
#![allow(missing_doc)]
1212

13+
use core::prelude::*;
1314

14-
use std::cmp;
15-
use std::fmt;
16-
use std::iter::RandomAccessIterator;
17-
use std::iter::{Enumerate, Repeat, Map, Zip};
18-
use std::ops;
19-
use std::slice;
20-
use std::uint;
15+
use core::cmp;
16+
use core::fmt;
17+
use core::iter::{Enumerate, Repeat, Map, Zip};
18+
use core::ops;
19+
use core::slice;
20+
use core::uint;
21+
22+
use string::String;
23+
use vec::Vec;
2124

2225
#[deriving(Clone)]
2326
struct SmallBitv {

src/libcollections/btree.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@
1818
///a length (the height of the tree), and lower and upper bounds on the
1919
///number of elements that a given node can contain.
2020
21-
use std::fmt;
22-
use std::fmt::Show;
21+
use core::prelude::*;
22+
23+
use alloc::owned::Box;
24+
use core::fmt;
25+
use core::fmt::Show;
26+
27+
use vec::Vec;
2328

2429
#[allow(missing_doc)]
2530
pub struct BTree<K, V> {

src/libcollections/deque.rs

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

1111
//! Container traits for collections
1212
13-
use std::container::Mutable;
13+
use core::prelude::*;
1414

1515
/// A double-ended sequence that allows querying, insertion and deletion at both ends.
1616
pub trait Deque<T> : Mutable {

src/libcollections/dlist.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
// Backlinks over DList::prev are raw pointers that form a full chain in
2222
// the reverse direction.
2323

24-
use std::iter;
25-
use std::mem;
26-
use std::ptr;
24+
use core::prelude::*;
25+
26+
use alloc::owned::Box;
27+
use core::iter;
28+
use core::mem;
29+
use core::ptr;
2730

2831
use deque::Deque;
2932

src/libcollections/enum_set.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
//! This module defines a container which uses an efficient bit mask
1414
//! representation to hold C-like enum variants.
1515
16-
use std::num::Bitwise;
16+
use core::prelude::*;
17+
18+
use core::num::Bitwise;
1719

1820
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
1921
/// A specialized Set implementation to use enum types.

src/libstd/hash/mod.rs src/libcollections/hash/mod.rs

+17-26
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,17 @@
6363

6464
#![allow(unused_must_use)]
6565

66-
use container::Container;
67-
use intrinsics::TypeId;
68-
use iter::Iterator;
69-
use option::{Option, Some, None};
70-
use owned::Box;
71-
use rc::Rc;
72-
use result::{Result, Ok, Err};
73-
use slice::{Vector, ImmutableVector};
74-
use str::{Str, StrSlice};
66+
use core::prelude::*;
67+
68+
use alloc::owned::Box;
69+
use alloc::rc::Rc;
70+
use core::intrinsics::TypeId;
71+
7572
use vec::Vec;
7673

7774
/// Reexport the `sip::hash` function as our default hasher.
7875
pub use hash = self::sip::hash;
7976

80-
pub use Writer = io::Writer;
81-
8277
pub mod sip;
8378

8479
/// A trait that represents a hashable type. The `S` type parameter is an
@@ -96,33 +91,29 @@ pub trait Hasher<S> {
9691
fn hash<T: Hash<S>>(&self, value: &T) -> u64;
9792
}
9893

94+
pub trait Writer {
95+
fn write(&mut self, bytes: &[u8]);
96+
}
97+
9998
//////////////////////////////////////////////////////////////////////////////
10099

101100
macro_rules! impl_hash(
102-
( $( $ty:ty => $method:ident;)* ) => (
101+
( $($ty:ident)* ) => (
103102
$(
104103
impl<S: Writer> Hash<S> for $ty {
105104
#[inline]
106105
fn hash(&self, state: &mut S) {
107-
state.$method(*self);
106+
let a: [u8, ..::core::$ty::BYTES] = unsafe {
107+
::core::mem::transmute(*self)
108+
};
109+
state.write(a.as_slice())
108110
}
109111
}
110112
)*
111113
)
112114
)
113115

114-
impl_hash!(
115-
u8 => write_u8;
116-
u16 => write_le_u16;
117-
u32 => write_le_u32;
118-
u64 => write_le_u64;
119-
uint => write_le_uint;
120-
i8 => write_i8;
121-
i16 => write_le_i16;
122-
i32 => write_le_i32;
123-
i64 => write_le_i64;
124-
int => write_le_int;
125-
)
116+
impl_hash!( u8 u16 u32 u64 uint i8 i16 i32 i64 int )
126117

127118
impl<S: Writer> Hash<S> for bool {
128119
#[inline]
@@ -142,7 +133,7 @@ impl<'a, S: Writer> Hash<S> for &'a str {
142133
#[inline]
143134
fn hash(&self, state: &mut S) {
144135
state.write(self.as_bytes());
145-
state.write_u8(0xFF);
136+
0xffu8.hash(state)
146137
}
147138
}
148139

src/libstd/hash/sip.rs src/libcollections/hash/sip.rs

+7-96
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,11 @@
2424
* discouraged.
2525
*/
2626

27-
use clone::Clone;
28-
use container::Container;
29-
use default::Default;
30-
use int;
31-
use io::{IoResult, Writer};
32-
use iter::Iterator;
33-
use result::Ok;
34-
use slice::ImmutableVector;
35-
use uint;
36-
37-
use super::{Hash, Hasher};
27+
use core::prelude::*;
28+
29+
use core::default::Default;
30+
31+
use super::{Hash, Hasher, Writer};
3832

3933
/// `SipState` computes a SipHash 2-4 hash over a stream of bytes.
4034
pub struct SipState {
@@ -151,41 +145,11 @@ impl SipState {
151145

152146
v0 ^ v1 ^ v2 ^ v3
153147
}
154-
155-
#[inline]
156-
fn write_le(&mut self, n: u64, size: uint) {
157-
self.tail |= n << 8*self.ntail;
158-
self.ntail += size;
159-
160-
if self.ntail >= 8 {
161-
let m = self.tail;
162-
163-
self.v3 ^= m;
164-
compress!(self.v0, self.v1, self.v2, self.v3);
165-
compress!(self.v0, self.v1, self.v2, self.v3);
166-
self.v0 ^= m;
167-
168-
self.ntail -= 8;
169-
if self.ntail == 0 {
170-
self.tail = 0;
171-
} else {
172-
self.tail = n >> 64 - 8*self.ntail;
173-
}
174-
}
175-
}
176148
}
177149

178-
macro_rules! make_write_le(
179-
($this:expr, $n:expr, $size:expr) => ({
180-
$this.write_le($n as u64, $size);
181-
$this.length += $size;
182-
Ok(())
183-
})
184-
)
185-
186150
impl Writer for SipState {
187151
#[inline]
188-
fn write(&mut self, msg: &[u8]) -> IoResult<()> {
152+
fn write(&mut self, msg: &[u8]) {
189153
let length = msg.len();
190154
self.length += length;
191155

@@ -196,7 +160,7 @@ impl Writer for SipState {
196160
if length < needed {
197161
self.tail |= u8to64_le!(msg, 0, length) << 8*self.ntail;
198162
self.ntail += length;
199-
return Ok(());
163+
return
200164
}
201165

202166
let m = self.tail | u8to64_le!(msg, 0, needed) << 8*self.ntail;
@@ -228,60 +192,7 @@ impl Writer for SipState {
228192

229193
self.tail = u8to64_le!(msg, i, left);
230194
self.ntail = left;
231-
232-
Ok(())
233-
}
234-
235-
#[inline]
236-
fn write_u8(&mut self, n: u8) -> IoResult<()> {
237-
make_write_le!(self, n, 1)
238-
}
239-
240-
#[inline]
241-
fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
242-
make_write_le!(self, n, 2)
243195
}
244-
245-
#[inline]
246-
fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
247-
make_write_le!(self, n, 4)
248-
}
249-
250-
#[inline]
251-
fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
252-
make_write_le!(self, n, 8)
253-
}
254-
255-
#[inline]
256-
fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
257-
make_write_le!(self, n, uint::BYTES)
258-
}
259-
260-
#[inline]
261-
fn write_i8(&mut self, n: i8) -> IoResult<()> {
262-
make_write_le!(self, n, 1)
263-
}
264-
265-
#[inline]
266-
fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
267-
make_write_le!(self, n, 2)
268-
}
269-
270-
#[inline]
271-
fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
272-
make_write_le!(self, n, 4)
273-
}
274-
275-
#[inline]
276-
fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
277-
make_write_le!(self, n, 8)
278-
}
279-
280-
#[inline]
281-
fn write_le_int(&mut self, n: int) -> IoResult<()> {
282-
make_write_le!(self, n, int::BYTES)
283-
}
284-
285196
}
286197

287198
impl Clone for SipState {

0 commit comments

Comments
 (0)