smallintmap.rs 16.0 KB
Newer Older
1
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 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).
 */

16
#![allow(missing_doc)]
17

18 19
use core::prelude::*;

20
use core::default::Default;
21
use core::fmt;
22 23 24
use core::iter::{Enumerate, FilterMap};
use core::mem::replace;

25
use {Collection, Mutable, Map, MutableMap, MutableSeq};
26 27
use {vec, slice};
use vec::Vec;
28

29
#[allow(missing_doc)]
D
Daniel Micay 已提交
30
pub struct SmallIntMap<T> {
31
    v: Vec<Option<T>>,
32 33
}

34
impl<V> Collection for SmallIntMap<V> {
35
    /// Return the number of elements in the map
D
Daniel Micay 已提交
36
    fn len(&self) -> uint {
A
Aaron Turon 已提交
37
        self.v.iter().filter(|elt| elt.is_some()).count()
38 39 40 41 42
    }

    /// Return true if there are no elements in the map
    fn is_empty(&self) -> bool {
        self.v.iter().all(|elt| elt.is_none())
43 44 45
    }
}

46
impl<V> Mutable for SmallIntMap<V> {
D
Daniel Micay 已提交
47 48
    /// Clear the map, removing all key-value pairs.
    fn clear(&mut self) { self.v.clear() }
49 50
}

51
impl<V> Map<uint, V> for SmallIntMap<V> {
D
Daniel Micay 已提交
52
    /// Return a reference to the value corresponding to the key
53 54
    fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
        if *key < self.v.len() {
55
            match *self.v.get(*key) {
56 57 58 59 60 61 62
              Some(ref value) => Some(value),
              None => None
            }
        } else {
            None
        }
    }
63
}
64

65
impl<V> MutableMap<uint, V> for SmallIntMap<V> {
D
Daniel Micay 已提交
66
    /// Return a mutable reference to the value corresponding to the key
67 68
    fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> {
        if *key < self.v.len() {
69
            match *self.v.get_mut(*key) {
70 71 72 73 74 75 76 77
              Some(ref mut value) => Some(value),
              None => None
            }
        } else {
            None
        }
    }

D
Daniel Micay 已提交
78 79 80 81 82 83 84
    /// 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 {
85
            self.v.grow_fn(key - len + 1, |_| None);
D
Daniel Micay 已提交
86
        }
87
        *self.v.get_mut(key) = Some(value);
D
Daniel Micay 已提交
88
        !exists
89 90
    }

D
Daniel Micay 已提交
91 92 93
    /// 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 {
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
        self.pop(key).is_some()
    }

    /// Insert a key-value pair from the map. If the key already had a value
    /// present in the map, that value is returned. Otherwise None is returned.
    fn swap(&mut self, key: uint, value: V) -> Option<V> {
        match self.find_mut(&key) {
            Some(loc) => { return Some(replace(loc, value)); }
            None => ()
        }
        self.insert(key, value);
        return None;
    }

    /// Removes a key from the map, returning the value at the key if the key
    /// was previously in the map.
    fn pop(&mut self, key: &uint) -> Option<V> {
D
Daniel Micay 已提交
111
        if *key >= self.v.len() {
112
            return None;
113
        }
114
        self.v.get_mut(*key).take()
115
    }
D
Daniel Micay 已提交
116 117
}

118 119 120 121 122
impl<V> Default for SmallIntMap<V> {
    #[inline]
    fn default() -> SmallIntMap<V> { SmallIntMap::new() }
}

123
impl<V> SmallIntMap<V> {
D
Daniel Micay 已提交
124
    /// Create an empty SmallIntMap
125
    pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
D
Daniel Micay 已提交
126

127 128
    /// Create an empty SmallIntMap with capacity `capacity`
    pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
129
        SmallIntMap { v: Vec::with_capacity(capacity) }
130 131
    }

132
    pub fn get<'a>(&'a self, key: &uint) -> &'a V {
133
        self.find(key).expect("key not present")
134
    }
135 136 137

    /// An iterator visiting all key-value pairs in ascending order by the keys.
    /// Iterator element type is (uint, &'r V)
P
Palmer Cox 已提交
138 139
    pub fn iter<'r>(&'r self) -> Entries<'r, V> {
        Entries {
140 141 142
            front: 0,
            back: self.v.len(),
            iter: self.v.iter()
143 144 145 146 147 148
        }
    }

    /// An iterator visiting all key-value pairs in ascending order by the keys,
    /// with mutable references to the values
    /// Iterator element type is (uint, &'r mut V)
P
Palmer Cox 已提交
149 150
    pub fn mut_iter<'r>(&'r mut self) -> MutEntries<'r, V> {
        MutEntries {
151 152 153
            front: 0,
            back: self.v.len(),
            iter: self.v.mut_iter()
154 155 156
        }
    }

157
    /// Empties the hash map, moving all values into the specified closure
158
    pub fn move_iter(&mut self)
159
        -> FilterMap<(uint, Option<V>), (uint, V),
160
                Enumerate<vec::MoveItems<Option<V>>>>
161
    {
162
        let values = replace(&mut self.v, vec!());
163
        values.move_iter().enumerate().filter_map(|(i, v)| {
164
            v.map(|v| (i, v))
165 166
        })
    }
167 168
}

169
impl<V:Clone> SmallIntMap<V> {
170 171 172 173 174
    pub fn update_with_key(&mut self,
                           key: uint,
                           val: V,
                           ff: |uint, V, V| -> V)
                           -> bool {
175 176
        let new_val = match self.find(&key) {
            None => val,
177
            Some(orig) => ff(key, (*orig).clone(), val)
178 179
        };
        self.insert(key, new_val)
180
    }
D
Daniel Micay 已提交
181

182
    pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool {
D
Daniel Micay 已提交
183 184
        self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
    }
185 186
}

187
impl<V: fmt::Show> fmt::Show for SmallIntMap<V> {
188 189 190 191 192 193 194 195 196 197
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "{{"));

        for (i, (k, v)) in self.iter().enumerate() {
            if i != 0 { try!(write!(f, ", ")); }
            try!(write!(f, "{}: {}", k, *v));
        }

        write!(f, "}}")
    }
198
}
199 200

macro_rules! iterator {
201
    (impl $name:ident -> $elem:ty, $getter:ident) => {
E
Erik Price 已提交
202
        impl<'a, T> Iterator<$elem> for $name<'a, T> {
203
            #[inline]
204 205 206 207 208 209 210 211 212 213 214
            fn next(&mut self) -> Option<$elem> {
                while self.front < self.back {
                    match self.iter.next() {
                        Some(elem) => {
                            if elem.is_some() {
                                let index = self.front;
                                self.front += 1;
                                return Some((index, elem. $getter ()));
                            }
                        }
                        _ => ()
215
                    }
216
                    self.front += 1;
217 218 219
                }
                None
            }
220 221 222 223 224

            #[inline]
            fn size_hint(&self) -> (uint, Option<uint>) {
                (0, Some(self.back - self.front))
            }
225 226 227 228
        }
    }
}

229 230
macro_rules! double_ended_iterator {
    (impl $name:ident -> $elem:ty, $getter:ident) => {
E
Erik Price 已提交
231
        impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
232
            #[inline]
233 234 235 236 237 238 239 240 241 242
            fn next_back(&mut self) -> Option<$elem> {
                while self.front < self.back {
                    match self.iter.next_back() {
                        Some(elem) => {
                            if elem.is_some() {
                                self.back -= 1;
                                return Some((self.back, elem. $getter ()));
                            }
                        }
                        _ => ()
243
                    }
244
                    self.back -= 1;
245 246 247 248 249 250 251
                }
                None
            }
        }
    }
}

P
Palmer Cox 已提交
252
pub struct Entries<'a, T> {
253 254 255
    front: uint,
    back: uint,
    iter: slice::Items<'a, Option<T>>
256 257
}

P
Palmer Cox 已提交
258 259
iterator!(impl Entries -> (uint, &'a T), get_ref)
double_ended_iterator!(impl Entries -> (uint, &'a T), get_ref)
260

P
Palmer Cox 已提交
261
pub struct MutEntries<'a, T> {
262 263 264
    front: uint,
    back: uint,
    iter: slice::MutItems<'a, Option<T>>
265 266
}

P
Palmer Cox 已提交
267 268
iterator!(impl MutEntries -> (uint, &'a mut T), get_mut_ref)
double_ended_iterator!(impl MutEntries -> (uint, &'a mut T), get_mut_ref)
269

270
#[cfg(test)]
271
mod test_map {
272
    use std::prelude::*;
273

274
    use {Map, MutableMap, Mutable};
D
Daniel Micay 已提交
275
    use super::SmallIntMap;
D
Daniel Micay 已提交
276 277 278 279

    #[test]
    fn test_find_mut() {
        let mut m = SmallIntMap::new();
280
        assert!(m.insert(1, 12i));
P
Patrick Walton 已提交
281 282
        assert!(m.insert(2, 8));
        assert!(m.insert(5, 14));
D
Daniel Micay 已提交
283 284
        let new = 100;
        match m.find_mut(&5) {
285
            None => fail!(), Some(x) => *x = new
D
Daniel Micay 已提交
286 287 288
        }
        assert_eq!(m.find(&5), Some(&new));
    }
289 290 291

    #[test]
    fn test_len() {
D
Daniel Micay 已提交
292
        let mut map = SmallIntMap::new();
293
        assert_eq!(map.len(), 0);
P
Patrick Walton 已提交
294
        assert!(map.is_empty());
295
        assert!(map.insert(5, 20i));
296
        assert_eq!(map.len(), 1);
P
Patrick Walton 已提交
297 298
        assert!(!map.is_empty());
        assert!(map.insert(11, 12));
299
        assert_eq!(map.len(), 2);
P
Patrick Walton 已提交
300 301
        assert!(!map.is_empty());
        assert!(map.insert(14, 22));
302
        assert_eq!(map.len(), 3);
P
Patrick Walton 已提交
303
        assert!(!map.is_empty());
304 305 306 307
    }

    #[test]
    fn test_clear() {
D
Daniel Micay 已提交
308
        let mut map = SmallIntMap::new();
309
        assert!(map.insert(5, 20i));
P
Patrick Walton 已提交
310 311
        assert!(map.insert(11, 12));
        assert!(map.insert(14, 22));
312
        map.clear();
P
Patrick Walton 已提交
313 314 315 316
        assert!(map.is_empty());
        assert!(map.find(&5).is_none());
        assert!(map.find(&11).is_none());
        assert!(map.find(&14).is_none());
317 318 319 320
    }

    #[test]
    fn test_insert_with_key() {
D
Daniel Micay 已提交
321
        let mut map = SmallIntMap::new();
322

323
        // given a new key, initialize it with this new count,
324
        // given an existing key, add more to its count
325
        fn add_more_to_count(_k: uint, v0: uint, v1: uint) -> uint {
326 327 328
            v0 + v1
        }

329
        fn add_more_to_count_simple(v0: uint, v1: uint) -> uint {
330 331 332 333
            v0 + v1
        }

        // count integers
334 335 336 337 338
        map.update(3, 1, add_more_to_count_simple);
        map.update_with_key(9, 1, add_more_to_count);
        map.update(3, 7, add_more_to_count_simple);
        map.update_with_key(5, 3, add_more_to_count);
        map.update_with_key(3, 2, add_more_to_count);
339 340

        // check the total counts
341 342 343
        assert_eq!(map.find(&3).unwrap(), &10);
        assert_eq!(map.find(&5).unwrap(), &3);
        assert_eq!(map.find(&9).unwrap(), &1);
344 345

        // sadly, no sevens were counted
P
Patrick Walton 已提交
346
        assert!(map.find(&7).is_none());
347
    }
348 349 350 351

    #[test]
    fn test_swap() {
        let mut m = SmallIntMap::new();
352 353 354
        assert_eq!(m.swap(1, 2i), None);
        assert_eq!(m.swap(1, 3i), Some(2));
        assert_eq!(m.swap(1, 4i), Some(3));
355 356 357 358 359
    }

    #[test]
    fn test_pop() {
        let mut m = SmallIntMap::new();
360
        m.insert(1, 2i);
361 362
        assert_eq!(m.pop(&1), Some(2));
        assert_eq!(m.pop(&1), None);
363
    }
364 365 366

    #[test]
    fn test_iterator() {
367
        let mut m = SmallIntMap::new();
368

369
        assert!(m.insert(0, 1i));
370 371 372 373
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
374

375 376
        let mut it = m.iter();
        assert_eq!(it.size_hint(), (0, Some(11)));
377
        assert_eq!(it.next().unwrap(), (0, &1));
378
        assert_eq!(it.size_hint(), (0, Some(10)));
379
        assert_eq!(it.next().unwrap(), (1, &2));
380 381 382 383 384 385 386
        assert_eq!(it.size_hint(), (0, Some(9)));
        assert_eq!(it.next().unwrap(), (3, &5));
        assert_eq!(it.size_hint(), (0, Some(7)));
        assert_eq!(it.next().unwrap(), (6, &10));
        assert_eq!(it.size_hint(), (0, Some(4)));
        assert_eq!(it.next().unwrap(), (10, &11));
        assert_eq!(it.size_hint(), (0, Some(0)));
387 388 389
        assert!(it.next().is_none());
    }

390 391 392 393
    #[test]
    fn test_iterator_size_hints() {
        let mut m = SmallIntMap::new();

394
        assert!(m.insert(0, 1i));
395 396 397 398 399 400
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));

        assert_eq!(m.iter().size_hint(), (0, Some(11)));
401
        assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
402
        assert_eq!(m.mut_iter().size_hint(), (0, Some(11)));
403
        assert_eq!(m.mut_iter().rev().size_hint(), (0, Some(11)));
404 405
    }

406 407
    #[test]
    fn test_mut_iterator() {
408
        let mut m = SmallIntMap::new();
409

410
        assert!(m.insert(0, 1i));
411 412 413 414
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
415

D
Daniel Micay 已提交
416
        for (k, v) in m.mut_iter() {
417
            *v += k as int;
418 419
        }

420 421 422 423 424 425 426
        let mut it = m.iter();
        assert_eq!(it.next().unwrap(), (0, &1));
        assert_eq!(it.next().unwrap(), (1, &3));
        assert_eq!(it.next().unwrap(), (3, &8));
        assert_eq!(it.next().unwrap(), (6, &16));
        assert_eq!(it.next().unwrap(), (10, &21));
        assert!(it.next().is_none());
427 428 429 430
    }

    #[test]
    fn test_rev_iterator() {
431
        let mut m = SmallIntMap::new();
432

433
        assert!(m.insert(0, 1i));
434 435 436 437
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
438

439
        let mut it = m.iter().rev();
440 441 442 443 444 445
        assert_eq!(it.next().unwrap(), (10, &11));
        assert_eq!(it.next().unwrap(), (6, &10));
        assert_eq!(it.next().unwrap(), (3, &5));
        assert_eq!(it.next().unwrap(), (1, &2));
        assert_eq!(it.next().unwrap(), (0, &1));
        assert!(it.next().is_none());
446 447 448 449
    }

    #[test]
    fn test_mut_rev_iterator() {
450
        let mut m = SmallIntMap::new();
451

452
        assert!(m.insert(0, 1i));
453 454 455 456
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
457

458
        for (k, v) in m.mut_iter().rev() {
459
            *v += k as int;
460 461
        }

462 463 464 465 466 467 468
        let mut it = m.iter();
        assert_eq!(it.next().unwrap(), (0, &1));
        assert_eq!(it.next().unwrap(), (1, &3));
        assert_eq!(it.next().unwrap(), (3, &8));
        assert_eq!(it.next().unwrap(), (6, &16));
        assert_eq!(it.next().unwrap(), (10, &21));
        assert!(it.next().is_none());
469
    }
470 471

    #[test]
472
    fn test_move_iter() {
473
        let mut m = SmallIntMap::new();
474
        m.insert(1, box 2i);
475
        let mut called = false;
476
        for (k, v) in m.move_iter() {
477 478 479
            assert!(!called);
            called = true;
            assert_eq!(k, 1);
480
            assert_eq!(v, box 2i);
481 482
        }
        assert!(called);
483
        m.insert(2, box 1i);
484
    }
485 486 487 488 489 490

    #[test]
    fn test_show() {
        let mut map = SmallIntMap::new();
        let empty = SmallIntMap::<int>::new();

491 492
        map.insert(1, 2i);
        map.insert(3, 4i);
493

494
        let map_str = map.to_string();
495 496 497 498
        let map_str = map_str.as_slice();
        assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
        assert_eq!(format!("{}", empty), "{}".to_string());
    }
499
}
J
Jihyun Yu 已提交
500

G
Graydon Hoare 已提交
501 502
#[cfg(test)]
mod bench {
L
Liigo Zhuang 已提交
503
    extern crate test;
504
    use self::test::Bencher;
505 506
    use super::SmallIntMap;
    use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
G
Graydon Hoare 已提交
507 508 509

    // Find seq
    #[bench]
510
    pub fn insert_rand_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
511
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
512
        insert_rand_n(100, &mut m, b);
G
Graydon Hoare 已提交
513 514 515
    }

    #[bench]
516
    pub fn insert_rand_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
517
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
518
        insert_rand_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
519 520 521 522
    }

    // Insert seq
    #[bench]
523
    pub fn insert_seq_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
524
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
525
        insert_seq_n(100, &mut m, b);
G
Graydon Hoare 已提交
526 527 528
    }

    #[bench]
529
    pub fn insert_seq_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
530
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
531
        insert_seq_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
532 533 534 535
    }

    // Find rand
    #[bench]
536
    pub fn find_rand_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
537
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
538
        find_rand_n(100, &mut m, b);
G
Graydon Hoare 已提交
539 540 541
    }

    #[bench]
542
    pub fn find_rand_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
543
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
544
        find_rand_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
545 546 547 548
    }

    // Find seq
    #[bench]
549
    pub fn find_seq_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
550
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
551
        find_seq_n(100, &mut m, b);
G
Graydon Hoare 已提交
552 553 554
    }

    #[bench]
555
    pub fn find_seq_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
556
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
557
        find_seq_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
558 559
    }
}