forked from skim-rs/skim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathorderedvec.rs
110 lines (91 loc) · 2.8 KB
/
orderedvec.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// ordered container
// Normally, user will only care about the first several options. So we only keep several of them
// in order. Other items are kept unordered and are sorted on demand.
const ORDERED_SIZE: usize = 300;
#[derive(Clone)]
pub struct OrderedVec<T: Ord> {
ordered: Vec<T>,
unordered: Vec<T>,
sorted: bool,
}
impl<T> OrderedVec<T> where T: Ord {
pub fn new() -> Self {
OrderedVec {
ordered: Vec::new(),
unordered: Vec::new(),
sorted: false,
}
}
fn ordered_insert(&mut self, item: T) {
self.ordered.push(item);
let mut pos = self.ordered.len() - 1;
while pos > 0 && self.ordered[pos] < self.ordered[pos-1] {
self.ordered.swap(pos, pos-1);
pos -= 1;
}
}
pub fn push(&mut self, item: T) {
if self.ordered.len() < ORDERED_SIZE {
self.ordered_insert(item);
return;
}
let smaller = if item > *self.ordered.last().unwrap() {
item
} else {
self.ordered_insert(item);
self.ordered.pop().unwrap()
};
self.unordered.push(smaller);
self.sorted = false;
}
pub fn get(&mut self, index: usize) -> Option<&T> {
if index < self.ordered.len() {
return self.ordered.get(index);
}
if index >= self.ordered.len() + self.unordered.len() {
return None;
}
if !self.sorted {
self.unordered.sort_by(|a, b| a.cmp(b));
self.sorted = true;
}
self.unordered.get(index - self.ordered.len())
}
pub fn len(&self) -> usize {
self.ordered.len() + self.unordered.len()
}
pub fn clear(&mut self) {
self.ordered.clear();
self.unordered.clear();
self.sorted = true;
}
pub fn iter<'a>(&'a self) -> Box<Iterator<Item=&T> + 'a> {
let ordered = &self.ordered;
let unordered = &self.unordered;
Box::new(ordered.iter().chain(unordered.iter()))
}
pub fn is_empty(&self) -> bool {
return self.len() == 0
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_push_get() {
let mut ordered = OrderedVec::new();
let data = [1,3,-2,-1,0,4,5];
for i in data.iter() {
ordered.push(*i);
}
println!("{}", ordered.get(0).unwrap());
//assert_eq!(*ordered.get(0).unwrap(), -2);
assert_eq!(*(ordered.get(0).unwrap()), -2);
assert_eq!(*(ordered.get(1).unwrap()), -1);
assert_eq!(*(ordered.get(2).unwrap()), 0);
assert_eq!(*(ordered.get(3).unwrap()), 1);
assert_eq!(*(ordered.get(4).unwrap()), 3);
assert_eq!(*(ordered.get(5).unwrap()), 4);
assert_eq!(*(ordered.get(6).unwrap()), 5);
}
}