smallintmap.rs 15.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
use std::iter::{Enumerate, FilterMap};
19
use std::mem::replace;
20
use std::{vec, slice};
21

22
#[allow(missing_doc)]
D
Daniel Micay 已提交
23
pub struct SmallIntMap<T> {
24
    v: Vec<Option<T>>,
25 26
}

27
impl<V> Container for SmallIntMap<V> {
28
    /// Return the number of elements in the map
D
Daniel Micay 已提交
29
    fn len(&self) -> uint {
30 31 32 33 34 35
        self.v.iter().count(|elt| elt.is_some())
    }

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

39
impl<V> Mutable for SmallIntMap<V> {
D
Daniel Micay 已提交
40 41
    /// Clear the map, removing all key-value pairs.
    fn clear(&mut self) { self.v.clear() }
42 43
}

44
impl<V> Map<uint, V> for SmallIntMap<V> {
D
Daniel Micay 已提交
45
    /// Return a reference to the value corresponding to the key
46 47
    fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
        if *key < self.v.len() {
48
            match *self.v.get(*key) {
49 50 51 52 53 54 55
              Some(ref value) => Some(value),
              None => None
            }
        } else {
            None
        }
    }
56
}
57

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

D
Daniel Micay 已提交
71 72 73 74 75 76 77
    /// 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 {
78
            self.v.grow_fn(key - len + 1, |_| None);
D
Daniel Micay 已提交
79
        }
80
        *self.v.get_mut(key) = Some(value);
D
Daniel Micay 已提交
81
        !exists
82 83
    }

D
Daniel Micay 已提交
84 85 86
    /// 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 {
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
        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 已提交
104
        if *key >= self.v.len() {
105
            return None;
106
        }
107
        self.v.get_mut(*key).take()
108
    }
D
Daniel Micay 已提交
109 110
}

111
impl<V> SmallIntMap<V> {
D
Daniel Micay 已提交
112
    /// Create an empty SmallIntMap
113
    pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
D
Daniel Micay 已提交
114

115 116
    /// Create an empty SmallIntMap with capacity `capacity`
    pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
117
        SmallIntMap { v: Vec::with_capacity(capacity) }
118 119
    }

120
    pub fn get<'a>(&'a self, key: &uint) -> &'a V {
121 122
        self.find(key).expect("key not present")
    }
123 124 125

    /// An iterator visiting all key-value pairs in ascending order by the keys.
    /// Iterator element type is (uint, &'r V)
P
Palmer Cox 已提交
126 127
    pub fn iter<'r>(&'r self) -> Entries<'r, V> {
        Entries {
128 129 130
            front: 0,
            back: self.v.len(),
            iter: self.v.iter()
131 132 133 134 135 136
        }
    }

    /// 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 已提交
137 138
    pub fn mut_iter<'r>(&'r mut self) -> MutEntries<'r, V> {
        MutEntries {
139 140 141
            front: 0,
            back: self.v.len(),
            iter: self.v.mut_iter()
142 143 144
        }
    }

145
    /// Empties the hash map, moving all values into the specified closure
146
    pub fn move_iter(&mut self)
147
        -> FilterMap<(uint, Option<V>), (uint, V),
148
                Enumerate<vec::MoveItems<Option<V>>>>
149
    {
150
        let values = replace(&mut self.v, vec!());
151
        values.move_iter().enumerate().filter_map(|(i, v)| {
152
            v.map(|v| (i, v))
153 154
        })
    }
155 156
}

157
impl<V:Clone> SmallIntMap<V> {
158 159 160 161 162
    pub fn update_with_key(&mut self,
                           key: uint,
                           val: V,
                           ff: |uint, V, V| -> V)
                           -> bool {
163 164
        let new_val = match self.find(&key) {
            None => val,
165
            Some(orig) => ff(key, (*orig).clone(), val)
166 167
        };
        self.insert(key, new_val)
168
    }
D
Daniel Micay 已提交
169

170
    pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool {
D
Daniel Micay 已提交
171 172
        self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
    }
173 174
}

175 176

macro_rules! iterator {
177
    (impl $name:ident -> $elem:ty, $getter:ident) => {
E
Erik Price 已提交
178
        impl<'a, T> Iterator<$elem> for $name<'a, T> {
179
            #[inline]
180 181 182 183 184 185 186 187 188 189 190
            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 ()));
                            }
                        }
                        _ => ()
191
                    }
192
                    self.front += 1;
193 194 195
                }
                None
            }
196 197 198 199 200

            #[inline]
            fn size_hint(&self) -> (uint, Option<uint>) {
                (0, Some(self.back - self.front))
            }
201 202 203 204
        }
    }
}

205 206
macro_rules! double_ended_iterator {
    (impl $name:ident -> $elem:ty, $getter:ident) => {
E
Erik Price 已提交
207
        impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
208
            #[inline]
209 210 211 212 213 214 215 216 217 218
            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 ()));
                            }
                        }
                        _ => ()
219
                    }
220
                    self.back -= 1;
221 222 223 224 225 226 227
                }
                None
            }
        }
    }
}

P
Palmer Cox 已提交
228
pub struct Entries<'a, T> {
229 230 231
    front: uint,
    back: uint,
    iter: slice::Items<'a, Option<T>>
232 233
}

P
Palmer Cox 已提交
234 235
iterator!(impl Entries -> (uint, &'a T), get_ref)
double_ended_iterator!(impl Entries -> (uint, &'a T), get_ref)
236

P
Palmer Cox 已提交
237
pub struct MutEntries<'a, T> {
238 239 240
    front: uint,
    back: uint,
    iter: slice::MutItems<'a, Option<T>>
241 242
}

P
Palmer Cox 已提交
243 244
iterator!(impl MutEntries -> (uint, &'a mut T), get_mut_ref)
double_ended_iterator!(impl MutEntries -> (uint, &'a mut T), get_mut_ref)
245

246
#[cfg(test)]
247
mod test_map {
248

D
Daniel Micay 已提交
249
    use super::SmallIntMap;
D
Daniel Micay 已提交
250 251 252 253

    #[test]
    fn test_find_mut() {
        let mut m = SmallIntMap::new();
P
Patrick Walton 已提交
254 255 256
        assert!(m.insert(1, 12));
        assert!(m.insert(2, 8));
        assert!(m.insert(5, 14));
D
Daniel Micay 已提交
257 258
        let new = 100;
        match m.find_mut(&5) {
259
            None => fail!(), Some(x) => *x = new
D
Daniel Micay 已提交
260 261 262
        }
        assert_eq!(m.find(&5), Some(&new));
    }
263 264 265

    #[test]
    fn test_len() {
D
Daniel Micay 已提交
266
        let mut map = SmallIntMap::new();
267
        assert_eq!(map.len(), 0);
P
Patrick Walton 已提交
268 269
        assert!(map.is_empty());
        assert!(map.insert(5, 20));
270
        assert_eq!(map.len(), 1);
P
Patrick Walton 已提交
271 272
        assert!(!map.is_empty());
        assert!(map.insert(11, 12));
273
        assert_eq!(map.len(), 2);
P
Patrick Walton 已提交
274 275
        assert!(!map.is_empty());
        assert!(map.insert(14, 22));
276
        assert_eq!(map.len(), 3);
P
Patrick Walton 已提交
277
        assert!(!map.is_empty());
278 279 280 281
    }

    #[test]
    fn test_clear() {
D
Daniel Micay 已提交
282
        let mut map = SmallIntMap::new();
P
Patrick Walton 已提交
283 284 285
        assert!(map.insert(5, 20));
        assert!(map.insert(11, 12));
        assert!(map.insert(14, 22));
286
        map.clear();
P
Patrick Walton 已提交
287 288 289 290
        assert!(map.is_empty());
        assert!(map.find(&5).is_none());
        assert!(map.find(&11).is_none());
        assert!(map.find(&14).is_none());
291 292 293 294
    }

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

297
        // given a new key, initialize it with this new count,
298
        // given an existing key, add more to its count
299
        fn add_more_to_count(_k: uint, v0: uint, v1: uint) -> uint {
300 301 302
            v0 + v1
        }

303
        fn add_more_to_count_simple(v0: uint, v1: uint) -> uint {
304 305 306 307
            v0 + v1
        }

        // count integers
308 309 310 311 312
        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);
313 314

        // check the total counts
315 316 317
        assert_eq!(map.find(&3).unwrap(), &10);
        assert_eq!(map.find(&5).unwrap(), &3);
        assert_eq!(map.find(&9).unwrap(), &1);
318 319

        // sadly, no sevens were counted
P
Patrick Walton 已提交
320
        assert!(map.find(&7).is_none());
321
    }
322 323 324 325

    #[test]
    fn test_swap() {
        let mut m = SmallIntMap::new();
326 327 328
        assert_eq!(m.swap(1, 2), None);
        assert_eq!(m.swap(1, 3), Some(2));
        assert_eq!(m.swap(1, 4), Some(3));
329 330 331 332 333 334
    }

    #[test]
    fn test_pop() {
        let mut m = SmallIntMap::new();
        m.insert(1, 2);
335 336
        assert_eq!(m.pop(&1), Some(2));
        assert_eq!(m.pop(&1), None);
337
    }
338 339 340

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

343 344 345 346 347
        assert!(m.insert(0, 1));
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
348

349 350
        let mut it = m.iter();
        assert_eq!(it.size_hint(), (0, Some(11)));
351
        assert_eq!(it.next().unwrap(), (0, &1));
352
        assert_eq!(it.size_hint(), (0, Some(10)));
353
        assert_eq!(it.next().unwrap(), (1, &2));
354 355 356 357 358 359 360
        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)));
361 362 363
        assert!(it.next().is_none());
    }

364 365 366 367 368 369 370 371 372 373 374
    #[test]
    fn test_iterator_size_hints() {
        let mut m = SmallIntMap::new();

        assert!(m.insert(0, 1));
        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)));
375
        assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
376
        assert_eq!(m.mut_iter().size_hint(), (0, Some(11)));
377
        assert_eq!(m.mut_iter().rev().size_hint(), (0, Some(11)));
378 379
    }

380 381
    #[test]
    fn test_mut_iterator() {
382
        let mut m = SmallIntMap::new();
383

384 385 386 387 388
        assert!(m.insert(0, 1));
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
389

D
Daniel Micay 已提交
390
        for (k, v) in m.mut_iter() {
391
            *v += k as int;
392 393
        }

394 395 396 397 398 399 400
        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());
401 402 403 404
    }

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

407 408 409 410 411
        assert!(m.insert(0, 1));
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
412

413
        let mut it = m.iter().rev();
414 415 416 417 418 419
        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());
420 421 422 423
    }

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

426 427 428 429 430
        assert!(m.insert(0, 1));
        assert!(m.insert(1, 2));
        assert!(m.insert(3, 5));
        assert!(m.insert(6, 10));
        assert!(m.insert(10, 11));
431

432
        for (k, v) in m.mut_iter().rev() {
433
            *v += k as int;
434 435
        }

436 437 438 439 440 441 442
        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());
443
    }
444 445

    #[test]
446
    fn test_move_iter() {
447
        let mut m = SmallIntMap::new();
448
        m.insert(1, box 2);
449
        let mut called = false;
450
        for (k, v) in m.move_iter() {
451 452 453
            assert!(!called);
            called = true;
            assert_eq!(k, 1);
454
            assert_eq!(v, box 2);
455 456
        }
        assert!(called);
457
        m.insert(2, box 1);
458
    }
459
}
J
Jihyun Yu 已提交
460

G
Graydon Hoare 已提交
461 462
#[cfg(test)]
mod bench {
L
Liigo Zhuang 已提交
463
    extern crate test;
464
    use self::test::Bencher;
465 466
    use super::SmallIntMap;
    use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
G
Graydon Hoare 已提交
467 468 469

    // Find seq
    #[bench]
470
    pub fn insert_rand_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
471
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
472
        insert_rand_n(100, &mut m, b);
G
Graydon Hoare 已提交
473 474 475
    }

    #[bench]
476
    pub fn insert_rand_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
477
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
478
        insert_rand_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
479 480 481 482
    }

    // Insert seq
    #[bench]
483
    pub fn insert_seq_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
484
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
485
        insert_seq_n(100, &mut m, b);
G
Graydon Hoare 已提交
486 487 488
    }

    #[bench]
489
    pub fn insert_seq_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
490
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
491
        insert_seq_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
492 493 494 495
    }

    // Find rand
    #[bench]
496
    pub fn find_rand_100(b: &mut Bencher) {
G
Graydon Hoare 已提交
497
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
498
        find_rand_n(100, &mut m, b);
G
Graydon Hoare 已提交
499 500 501
    }

    #[bench]
502
    pub fn find_rand_10_000(b: &mut Bencher) {
G
Graydon Hoare 已提交
503
        let mut m : SmallIntMap<uint> = SmallIntMap::new();
504
        find_rand_n(10_000, &mut m, b);
G
Graydon Hoare 已提交
505 506 507 508
    }

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

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