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