]> git.lizzy.rs Git - rust.git/blob - src/libstd/collections/mod.rs
Auto merge of #22517 - brson:relnotes, r=Gankro
[rust.git] / src / libstd / collections / mod.rs
1 // Copyright 2013-2014 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 //! Collection types.
12 //!
13 //! Rust's standard collection library provides efficient implementations of the most common
14 //! general purpose programming data structures. By using the standard implementations,
15 //! it should be possible for two libraries to communicate without significant data conversion.
16 //!
17 //! To get this out of the way: you should probably just use `Vec` or `HashMap`. These two
18 //! collections cover most use cases for generic data storage and processing. They are
19 //! exceptionally good at doing what they do. All the other collections in the standard
20 //! library have specific use cases where they are the optimal choice, but these cases are
21 //! borderline *niche* in comparison. Even when `Vec` and `HashMap` are technically suboptimal,
22 //! they're probably a good enough choice to get started.
23 //!
24 //! Rust's collections can be grouped into four major categories:
25 //!
26 //! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV`
27 //! * Maps: `HashMap`, `BTreeMap`, `VecMap`
28 //! * Sets: `HashSet`, `BTreeSet`, `BitVSet`
29 //! * Misc: `BinaryHeap`
30 //!
31 //! # When Should You Use Which Collection?
32 //!
33 //! These are fairly high-level and quick break-downs of when each collection should be
34 //! considered. Detailed discussions of strengths and weaknesses of individual collections
35 //! can be found on their own documentation pages.
36 //!
37 //! ### Use a `Vec` when:
38 //! * You want to collect items up to be processed or sent elsewhere later, and don't care about
39 //! any properties of the actual values being stored.
40 //! * You want a sequence of elements in a particular order, and will only be appending to
41 //! (or near) the end.
42 //! * You want a stack.
43 //! * You want a resizable array.
44 //! * You want a heap-allocated array.
45 //!
46 //! ### Use a `RingBuf` when:
47 //! * You want a `Vec` that supports efficient insertion at both ends of the sequence.
48 //! * You want a queue.
49 //! * You want a double-ended queue (deque).
50 //!
51 //! ### Use a `DList` when:
52 //! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization.
53 //! * You want to efficiently split and append lists.
54 //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list.
55 //!
56 //! ### Use a `HashMap` when:
57 //! * You want to associate arbitrary keys with an arbitrary value.
58 //! * You want a cache.
59 //! * You want a map, with no extra functionality.
60 //!
61 //! ### Use a `BTreeMap` when:
62 //! * You're interested in what the smallest or largest key-value pair is.
63 //! * You want to find the largest or smallest key that is smaller or larger than something
64 //! * You want to be able to get all of the entries in order on-demand.
65 //! * You want a sorted map.
66 //!
67 //! ### Use a `VecMap` when:
68 //! * You want a `HashMap` but with known to be small `usize` keys.
69 //! * You want a `BTreeMap`, but with known to be small `usize` keys.
70 //!
71 //! ### Use the `Set` variant of any of these `Map`s when:
72 //! * You just want to remember which keys you've seen.
73 //! * There is no meaningful value to associate with your keys.
74 //! * You just want a set.
75 //!
76 //! ### Use a `BitV` when:
77 //! * You want to store an unbounded number of booleans in a small space.
78 //! * You want a bitvector.
79 //!
80 //! ### Use a `BitVSet` when:
81 //! * You want a `VecSet`.
82 //!
83 //! ### Use a `BinaryHeap` when:
84 //! * You want to store a bunch of elements, but only ever want to process the "biggest"
85 //! or "most important" one at any given time.
86 //! * You want a priority queue.
87 //!
88 //! # Performance
89 //!
90 //! Choosing the right collection for the job requires an understanding of what each collection
91 //! is good at. Here we briefly summarize the performance of different collections for certain
92 //! important operations. For further details, see each type's documentation.
93 //!
94 //! Throughout the documentation, we will follow a few conventions. For all operations,
95 //! the collection's size is denoted by n. If another collection is involved in the operation, it
96 //! contains m elements. Operations which have an *amortized* cost are suffixed with a `*`.
97 //! Operations with an *expected* cost are suffixed with a `~`.
98 //!
99 //! All amortized costs are for the potential need to resize when capacity is exhausted.
100 //! If a resize occurs it will take O(n) time. Our collections never automatically shrink,
101 //! so removal operations aren't amortized. Over a sufficiently large series of
102 //! operations, the average cost per operation will deterministically equal the given cost.
103 //!
104 //! Only HashMap has expected costs, due to the probabilistic nature of hashing. It is
105 //! theoretically possible, though very unlikely, for HashMap to experience worse performance.
106 //!
107 //! ## Sequences
108 //!
109 //! |         | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
110 //! |---------|----------------|-----------------|----------------|--------|----------------|
111 //! | Vec     | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
112 //! | RingBuf | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
113 //! | DList   | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
114 //! | Bitv    | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
115 //!
116 //! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf
117 //! is generally going to be faster than DList. Bitv is not a general purpose collection, and
118 //! therefore cannot reasonably be compared.
119 //!
120 //! ## Maps
121 //!
122 //! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet,
123 //! refer to VecMap.
124 //!
125 //! |          | get       | insert   | remove   | predecessor |
126 //! |----------|-----------|----------|----------|-------------|
127 //! | HashMap  | O(1)~     | O(1)~*   | O(1)~    | N/A         |
128 //! | BTreeMap | O(log n)  | O(log n) | O(log n) | O(log n)    |
129 //! | VecMap   | O(1)      | O(1)?    | O(1)     | O(n)        |
130 //!
131 //! Note that VecMap is *incredibly* inefficient in terms of space. The O(1) insertion time
132 //! assumes space for the element is already allocated. Otherwise, a large key may require a
133 //! massive reallocation, with no direct relation to the number of elements in the collection.
134 //! VecMap should only be seriously considered for small keys.
135 //!
136 //! Note also that BTreeMap's precise preformance depends on the value of B.
137 //!
138 //! # Correct and Efficient Usage of Collections
139 //!
140 //! Of course, knowing which collection is the right one for the job doesn't instantly
141 //! permit you to use it correctly. Here are some quick tips for efficient and correct
142 //! usage of the standard collections in general. If you're interested in how to use a
143 //! specific collection in particular, consult its documentation for detailed discussion
144 //! and code examples.
145 //!
146 //! ## Capacity Management
147 //!
148 //! Many collections provide several constructors and methods that refer to "capacity".
149 //! These collections are generally built on top of an array. Optimally, this array would be
150 //! exactly the right size to fit only the elements stored in the collection, but for the
151 //! collection to do this would be very inefficient. If the backing array was exactly the
152 //! right size at all times, then every time an element is inserted, the collection would
153 //! have to grow the array to fit it. Due to the way memory is allocated and managed on most
154 //! computers, this would almost surely require allocating an entirely new array and
155 //! copying every single element from the old one into the new one. Hopefully you can
156 //! see that this wouldn't be very efficient to do on every operation.
157 //!
158 //! Most collections therefore use an *amortized* allocation strategy. They generally let
159 //! themselves have a fair amount of unoccupied space so that they only have to grow
160 //! on occasion. When they do grow, they allocate a substantially larger array to move
161 //! the elements into so that it will take a while for another grow to be required. While
162 //! this strategy is great in general, it would be even better if the collection *never*
163 //! had to resize its backing array. Unfortunately, the collection itself doesn't have
164 //! enough information to do this itself. Therefore, it is up to us programmers to give it
165 //! hints.
166 //!
167 //! Any `with_capacity` constructor will instruct the collection to allocate enough space
168 //! for the specified number of elements. Ideally this will be for exactly that many
169 //! elements, but some implementation details may prevent this. `Vec` and `RingBuf` can
170 //! be relied on to allocate exactly the requested amount, though. Use `with_capacity`
171 //! when you know exactly how many elements will be inserted, or at least have a
172 //! reasonable upper-bound on that number.
173 //!
174 //! When anticipating a large influx of elements, the `reserve` family of methods can
175 //! be used to hint to the collection how much room it should make for the coming items.
176 //! As with `with_capacity`, the precise behavior of these methods will be specific to
177 //! the collection of interest.
178 //!
179 //! For optimal performance, collections will generally avoid shrinking themselves.
180 //! If you believe that a collection will not soon contain any more elements, or
181 //! just really need the memory, the `shrink_to_fit` method prompts the collection
182 //! to shrink the backing array to the minimum size capable of holding its elements.
183 //!
184 //! Finally, if ever you're interested in what the actual capacity of the collection is,
185 //! most collections provide a `capacity` method to query this information on demand.
186 //! This can be useful for debugging purposes, or for use with the `reserve` methods.
187 //!
188 //! ## Iterators
189 //!
190 //! Iterators are a powerful and robust mechanism used throughout Rust's standard
191 //! libraries. Iterators provide a sequence of values in a generic, safe, efficient
192 //! and convenient way. The contents of an iterator are usually *lazily* evaluated,
193 //! so that only the values that are actually needed are ever actually produced, and
194 //! no allocation need be done to temporarily store them. Iterators are primarily
195 //! consumed using a `for` loop, although many functions also take iterators where
196 //! a collection or sequence of values is desired.
197 //!
198 //! All of the standard collections provide several iterators for performing bulk
199 //! manipulation of their contents. The three primary iterators almost every collection
200 //! should provide are `iter`, `iter_mut`, and `into_iter`. Some of these are not
201 //! provided on collections where it would be unsound or unreasonable to provide them.
202 //!
203 //! `iter` provides an iterator of immutable references to all the contents of a
204 //! collection in the most "natural" order. For sequence collections like `Vec`, this
205 //! means the items will be yielded in increasing order of index starting at 0. For ordered
206 //! collections like `BTreeMap`, this means that the items will be yielded in sorted order.
207 //! For unordered collections like `HashMap`, the items will be yielded in whatever order
208 //! the internal representation made most convenient. This is great for reading through
209 //! all the contents of the collection.
210 //!
211 //! ```
212 //! let vec = vec![1, 2, 3, 4];
213 //! for x in vec.iter() {
214 //!    println!("vec contained {}", x);
215 //! }
216 //! ```
217 //!
218 //! `iter_mut` provides an iterator of *mutable* references in the same order as `iter`.
219 //! This is great for mutating all the contents of the collection.
220 //!
221 //! ```
222 //! let mut vec = vec![1, 2, 3, 4];
223 //! for x in vec.iter_mut() {
224 //!    *x += 1;
225 //! }
226 //! ```
227 //!
228 //! `into_iter` transforms the actual collection into an iterator over its contents
229 //! by-value. This is great when the collection itself is no longer needed, and the
230 //! values are needed elsewhere. Using `extend` with `into_iter` is the main way that
231 //! contents of one collection are moved into another. Calling `collect` on an iterator
232 //! itself is also a great way to convert one collection into another. Both of these
233 //! methods should internally use the capacity management tools discussed in the
234 //! previous section to do this as efficiently as possible.
235 //!
236 //! ```
237 //! let mut vec1 = vec![1, 2, 3, 4];
238 //! let vec2 = vec![10, 20, 30, 40];
239 //! vec1.extend(vec2.into_iter());
240 //! ```
241 //!
242 //! ```
243 //! use std::collections::RingBuf;
244 //!
245 //! let vec = vec![1, 2, 3, 4];
246 //! let buf: RingBuf<_> = vec.into_iter().collect();
247 //! ```
248 //!
249 //! Iterators also provide a series of *adapter* methods for performing common tasks to
250 //! sequences. Among the adapters are functional favorites like `map`, `fold`, `skip`,
251 //! and `take`. Of particular interest to collections is the `rev` adapter, that
252 //! reverses any iterator that supports this operation. Most collections provide reversible
253 //! iterators as the way to iterate over them in reverse order.
254 //!
255 //! ```
256 //! let vec = vec![1, 2, 3, 4];
257 //! for x in vec.iter().rev() {
258 //!    println!("vec contained {}", x);
259 //! }
260 //! ```
261 //!
262 //! Several other collection methods also return iterators to yield a sequence of results
263 //! but avoid allocating an entire collection to store the result in. This provides maximum
264 //! flexibility as `collect` or `extend` can be called to "pipe" the sequence into any
265 //! collection if desired. Otherwise, the sequence can be looped over with a `for` loop. The
266 //! iterator can also be discarded after partial use, preventing the computation of the unused
267 //! items.
268 //!
269 //! ## Entries
270 //!
271 //! The `entry` API is intended to provide an efficient mechanism for manipulating
272 //! the contents of a map conditionally on the presence of a key or not. The primary
273 //! motivating use case for this is to provide efficient accumulator maps. For instance,
274 //! if one wishes to maintain a count of the number of times each key has been seen,
275 //! they will have to perform some conditional logic on whether this is the first time
276 //! the key has been seen or not. Normally, this would require a `find` followed by an
277 //! `insert`, effectively duplicating the search effort on each insertion.
278 //!
279 //! When a user calls `map.entry(&key)`, the map will search for the key and then yield
280 //! a variant of the `Entry` enum.
281 //!
282 //! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case the
283 //! only valid operation is to `set` the value of the entry. When this is done,
284 //! the vacant entry is consumed and converted into a mutable reference to the
285 //! the value that was inserted. This allows for further manipulation of the value
286 //! beyond the lifetime of the search itself. This is useful if complex logic needs to
287 //! be performed on the value regardless of whether the value was just inserted.
288 //!
289 //! If an `Occupied(entry)` is yielded, then the key *was* found. In this case, the user
290 //! has several options: they can `get`, `set`, or `take` the value of the occupied
291 //! entry. Additionally, they can convert the occupied entry into a mutable reference
292 //! to its value, providing symmetry to the vacant `set` case.
293 //!
294 //! ### Examples
295 //!
296 //! Here are the two primary ways in which `entry` is used. First, a simple example
297 //! where the logic performed on the values is trivial.
298 //!
299 //! #### Counting the number of times each character in a string occurs
300 //!
301 //! ```
302 //! use std::collections::btree_map::{BTreeMap, Entry};
303 //!
304 //! let mut count = BTreeMap::new();
305 //! let message = "she sells sea shells by the sea shore";
306 //!
307 //! for c in message.chars() {
308 //!     match count.entry(c) {
309 //!         Entry::Vacant(entry) => { entry.insert(1); },
310 //!         Entry::Occupied(mut entry) => *entry.get_mut() += 1,
311 //!     }
312 //! }
313 //!
314 //! assert_eq!(count.get(&'s'), Some(&8));
315 //!
316 //! println!("Number of occurrences of each character");
317 //! for (char, count) in count.iter() {
318 //!     println!("{}: {}", char, count);
319 //! }
320 //! ```
321 //!
322 //! When the logic to be performed on the value is more complex, we may simply use
323 //! the `entry` API to ensure that the value is initialized, and perform the logic
324 //! afterwards.
325 //!
326 //! #### Tracking the inebriation of customers at a bar
327 //!
328 //! ```
329 //! use std::collections::btree_map::{BTreeMap, Entry};
330 //!
331 //! // A client of the bar. They have an id and a blood alcohol level.
332 //! struct Person { id: u32, blood_alcohol: f32 };
333 //!
334 //! // All the orders made to the bar, by client id.
335 //! let orders = vec![1,2,1,2,3,4,1,2,2,3,4,1,1,1];
336 //!
337 //! // Our clients.
338 //! let mut blood_alcohol = BTreeMap::new();
339 //!
340 //! for id in orders.into_iter() {
341 //!     // If this is the first time we've seen this customer, initialize them
342 //!     // with no blood alcohol. Otherwise, just retrieve them.
343 //!     let person = match blood_alcohol.entry(id) {
344 //!         Entry::Vacant(entry) => entry.insert(Person{id: id, blood_alcohol: 0.0}),
345 //!         Entry::Occupied(entry) => entry.into_mut(),
346 //!     };
347 //!
348 //!     // Reduce their blood alcohol level. It takes time to order and drink a beer!
349 //!     person.blood_alcohol *= 0.9;
350 //!
351 //!     // Check if they're sober enough to have another beer.
352 //!     if person.blood_alcohol > 0.3 {
353 //!         // Too drunk... for now.
354 //!         println!("Sorry {}, I have to cut you off", person.id);
355 //!     } else {
356 //!         // Have another!
357 //!         person.blood_alcohol += 0.1;
358 //!     }
359 //! }
360 //! ```
361
362 #![stable(feature = "rust1", since = "1.0.0")]
363
364 pub use core_collections::Bound;
365 pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
366 pub use core_collections::{DList, RingBuf, VecMap};
367
368 pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set};
369 pub use core_collections::{dlist, ring_buf, vec_map};
370
371 pub use self::hash_map::HashMap;
372 pub use self::hash_set::HashSet;
373
374 mod hash;
375
376 #[stable(feature = "rust1", since = "1.0.0")]
377 pub mod hash_map {
378     //! A hashmap
379     pub use super::hash::map::*;
380 }
381
382 #[stable(feature = "rust1", since = "1.0.0")]
383 pub mod hash_set {
384     //! A hashset
385     pub use super::hash::set::*;
386 }
387
388 /// Experimental support for providing custom hash algorithms to a HashMap and
389 /// HashSet.
390 #[unstable(feature = "std_misc", reason = "module was recently added")]
391 pub mod hash_state {
392     pub use super::hash::state::*;
393 }