|
1 | 1 | use std::mem; |
2 | 2 |
|
3 | | -/// A small map backed by an unsorted vector. |
4 | | -/// |
5 | | -/// Maintains key uniqueness at cost of O(n) lookup/insert/remove. Maintains insertion order |
6 | | -/// (`insert` calls that overwrite an existing value don't change order). |
| 3 | +/// A small map backed by a sorted vector. |
7 | 4 | #[derive(Clone, Default)] |
8 | | -pub struct VecMap<K, V>(Vec<(K, V)>); |
| 5 | +pub struct VecMap<K, V> { |
| 6 | + keys: Vec<K>, |
| 7 | + values: Vec<V>, |
| 8 | +} |
9 | 9 |
|
10 | | -impl<K: Eq, V> VecMap<K, V> { |
| 10 | +impl<K: Ord, V> VecMap<K, V> { |
11 | 11 | pub fn new() -> Self { |
12 | | - VecMap(Vec::new()) |
| 12 | + VecMap { |
| 13 | + keys: Vec::new(), |
| 14 | + values: Vec::new(), |
| 15 | + } |
13 | 16 | } |
14 | 17 |
|
15 | 18 | pub fn is_empty(&self) -> bool { |
16 | | - self.0.is_empty() |
| 19 | + self.keys.is_empty() |
17 | 20 | } |
18 | 21 |
|
19 | 22 | pub fn clear(&mut self) { |
20 | | - self.0.clear(); |
21 | | - } |
22 | | - |
23 | | - fn find(&self, key: &K) -> Option<usize> { |
24 | | - for (i, (k, _)) in self.0.iter().enumerate() { |
25 | | - if k == key { |
26 | | - return Some(i); |
27 | | - } |
28 | | - } |
29 | | - None |
| 23 | + self.keys.clear(); |
| 24 | + self.values.clear(); |
30 | 25 | } |
31 | 26 |
|
32 | 27 | pub fn contains(&self, key: &K) -> bool { |
33 | | - self.find(key).is_some() |
| 28 | + self.keys.binary_search(key).is_ok() |
34 | 29 | } |
35 | 30 |
|
36 | 31 | pub fn get(&self, key: &K) -> Option<&V> { |
37 | | - match self.find(key) { |
38 | | - Some(i) => Some(&self.0[i].1), |
39 | | - None => None, |
| 32 | + match self.keys.binary_search(key) { |
| 33 | + Ok(i) => Some(&self.values[i]), |
| 34 | + Err(_) => None, |
40 | 35 | } |
41 | 36 | } |
42 | 37 |
|
43 | 38 | pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { |
44 | | - match self.find(key) { |
45 | | - Some(i) => Some(&mut self.0[i].1), |
46 | | - None => None, |
| 39 | + match self.keys.binary_search(key) { |
| 40 | + Ok(i) => Some(&mut self.values[i]), |
| 41 | + Err(_) => None, |
47 | 42 | } |
48 | 43 | } |
49 | 44 |
|
50 | 45 | pub fn insert(&mut self, key: K, value: V) -> Option<V> { |
51 | | - if let Some(old) = self.get_mut(&key) { |
52 | | - return Some(mem::replace(old, value)); |
| 46 | + match self.keys.binary_search(&key) { |
| 47 | + Ok(i) => { |
| 48 | + let old = mem::replace(&mut self.values[i], value); |
| 49 | + Some(old) |
| 50 | + } |
| 51 | + Err(i) => { |
| 52 | + self.keys.insert(i, key); |
| 53 | + self.values.insert(i, value); |
| 54 | + None |
| 55 | + } |
53 | 56 | } |
54 | | - self.0.push((key, value)); |
55 | | - None |
56 | 57 | } |
57 | 58 |
|
58 | 59 | pub fn remove(&mut self, key: &K) -> Option<V> { |
59 | | - match self.find(key) { |
60 | | - Some(i) => Some(self.0.remove(i).1), |
61 | | - None => None, |
| 60 | + match self.keys.binary_search(key) { |
| 61 | + Ok(i) => { |
| 62 | + self.keys.remove(i); |
| 63 | + Some(self.values.remove(i)) |
| 64 | + } |
| 65 | + Err(_) => None, |
62 | 66 | } |
63 | 67 | } |
64 | 68 |
|
65 | 69 | pub fn values(&self) -> impl Iterator<Item = &V> { |
66 | | - self.0.iter().map(|kv| &kv.1) |
| 70 | + self.values.iter() |
67 | 71 | } |
68 | 72 | } |
0 commit comments