vec_with_positions/
lib.rs

1//! UNTESTED code.
2//!
3//! TODO: docs
4
5use std::iter::{once, Once};
6
7#[derive(Clone, Copy, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
8pub struct Position(usize); // TODO: pub?
9
10// FIXME: Set positions to usize::max.
11
12/// A `Vec` inside together with positions that move together with the elements if the `Vec`
13/// has deletions or insertions.
14///
15/// Implemented partially.
16///
17/// TODO: `Position` enum type to differentiate positions and indexes.
18pub trait VecWithPositions<'a, T>
19{
20    type Positions: Iterator<Item = &'a usize> + 'a;
21    type PositionsMut: Iterator<Item = &'a mut usize> + 'a;
22
23    fn vec(&self) -> &Vec<T>;
24    fn vec_mut(&mut self) -> &mut Vec<T>;
25    fn positions(&'a self) -> Self::Positions;
26    fn positions_mut(&'a mut self) -> Self::PositionsMut;
27    fn push(&mut self, value: T) {
28        self.vec_mut().push(value)
29    }
30    fn append(&mut self, other: &mut Vec<T>) {
31        self.vec_mut().append(other)
32    }
33    fn remove(&'a mut self, index: usize) -> T { // FIXME
34        let result = self.vec_mut().remove(index);
35        for pos in self.positions_mut() {
36            if *pos > index {
37                *pos -= 1;
38            }
39        }
40        result
41    }
42    fn clear(&mut self) {
43        self.vec_mut().clear();
44    }
45
46    fn get(&self, index: usize) -> Option<&T> {
47        self.vec().get(index)
48    }
49    fn get_mut(&mut self, index: usize) -> Option<&mut T> {
50        self.vec_mut().get_mut(index)
51    }
52    fn set(&mut self, index: usize, value: T) {
53        self.vec_mut()[index] = value;
54    }
55
56    fn is_empty(&self) -> bool {
57        self.vec().is_empty()
58    }
59    fn len(&self) -> usize {
60        self.vec().len()
61    }
62
63    fn iter(&'a self) -> std::slice::Iter<'a, T> {
64        self.vec().iter()
65    }
66    fn iter_mut(&'a mut self) -> std::slice::IterMut<'a, T> {
67        self.vec_mut().iter_mut()
68    }
69}
70
71pub struct VecWithOnePosition<T> {
72    vec: Vec<T>,
73    position: usize,
74}
75
76impl<T> VecWithOnePosition<T> {
77    pub fn new() -> Self {
78        Self {
79            vec: Vec::new(),
80            position: usize::MAX, // a nonsense value
81        }
82    }
83    pub fn get_position(&self) -> usize {
84        self.position
85    }
86    pub fn set_position(&mut self, index: usize) {
87        self.position = index;
88    }
89}
90
91impl<'a, T> VecWithPositions<'a, T> for VecWithOnePosition<T> {
92    type Positions = Once<&'a usize>;
93    type PositionsMut = Once<&'a mut usize>;
94    fn vec(&self) -> &Vec<T> {
95        &self.vec
96    }
97    fn vec_mut(&mut self) -> &mut Vec<T> {
98        &mut self.vec
99    }
100    fn positions(&'a self) -> Self::Positions {
101        once(&self.position)
102    }
103    fn positions_mut(&'a mut self) -> Self::PositionsMut {
104        once(&mut self.position)
105    }
106}
107
108pub struct VecWithPositionsVector<T> {
109    vec: Vec<T>,
110    positions: Vec<usize>,
111}
112
113impl<T> VecWithPositionsVector<T> {
114    pub fn new() -> Self {
115        Self {
116            vec: Vec::new(),
117            positions: Vec::new(),
118        }
119    }
120
121    pub fn get_position(&self, pos: Position) -> usize {
122        self.positions[pos.0]
123    }
124    pub fn set_position(&mut self, pos: Position, index: usize) {
125        self.positions[pos.0] = index;
126    }
127
128    fn get_by_position(&self, pos: Position) -> Option<&T> {
129        self.get(self.positions[pos.0])
130    }
131    fn get_mut_by_position(&mut self, pos: Position) -> Option<&mut T> {
132        self.get_mut(self.positions[pos.0])
133    }
134    fn set_by_position(&mut self, pos: Position, value: T) {
135        self.set(self.positions[pos.0], value);
136    }
137}
138
139impl<'a, T> VecWithPositions<'a, T> for VecWithPositionsVector<T> {
140    type Positions = std::slice::Iter<'a, usize>;
141    type PositionsMut = std::slice::IterMut<'a, usize>;
142    fn vec(&self) -> &Vec<T> {
143        &self.vec
144    }
145    fn vec_mut(&mut self) -> &mut Vec<T> {
146        &mut self.vec
147    }
148    fn positions(&'a self) -> Self::Positions {
149        self.positions.iter()
150    }
151    fn positions_mut(&'a mut self) -> Self::PositionsMut {
152        self.positions.iter_mut()
153    }
154}
155
156/// Example: Several threads use a pool of network nodes to download from.
157/// From the pool we "view" a range of currently used nodes, one by thread.
158/// If a note is invalidated, it is removed from the list and the lacking thread
159/// is moved to the end of the list receiving a new node.
160/// Nodes later than it in the range decrease their positions.
161/// Despite of the name, positions can be the same, if shortage of the pool.
162pub struct VecWithPositionsAllDifferent<T> {
163    vec_with_positions: VecWithPositionsVector<T>,
164    range_start: Position,
165    range_end: Position, // wraps around circularly
166}
167
168impl<T> VecWithPositionsAllDifferent<T> {
169    pub fn push(&mut self, value: T) {
170        self.vec_with_positions.push(value);
171    }
172    pub fn append(&mut self, other: &mut Vec<T>) {
173        self.vec_with_positions.append(other);
174    }
175    pub fn remove(&mut self, index: usize) -> T {
176        self.range_end.0 = if self.range_end.0 != 0 {
177            self.range_end.0 - 1
178        } else {
179            self.len()
180        };
181        self.vec_with_positions.remove(index)
182    }
183    pub fn clear(&mut self) {
184        self.range_start = Position(0);
185        self.range_end = Position(0);
186        self.vec_with_positions.clear();
187    }
188    pub fn len(&self) -> usize {
189        self.vec_with_positions.len()
190    }
191    pub fn is_empty(&self) -> bool {
192        self.vec_with_positions.is_empty()
193    }
194    pub fn new_position(&mut self) -> Position {
195        self.range_end.0 += 1;
196        if self.range_end.0 == self.len() {
197            self.range_end.0 = 0;
198        }
199        self.range_end
200    }
201    pub fn get(&self, index: usize) -> Option<&T> {
202        self.vec_with_positions.get(index)
203    }
204    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
205        self.vec_with_positions.get_mut(index)
206    }
207    pub fn set(&mut self, index: usize, value: T) {
208        self.vec_with_positions.set(index, value)
209    }
210    pub fn get_by_position(&self, pos: Position) -> Option<&T> {
211        self.vec_with_positions.get_by_position(pos)
212    }
213    pub fn get_mut_by_position(&mut self, pos: Position) -> Option<&mut T> {
214        self.vec_with_positions.get_mut_by_position(pos)
215    }
216    pub fn set_by_position(&mut self, pos: Position, value: T) {
217        self.vec_with_positions.set_by_position(pos, value)
218    }
219}
220
221#[cfg(test)]
222mod tests {
223    use crate::{Position, VecWithOnePosition, VecWithPositions};
224
225    #[test]
226    fn before() {
227        let mut v = VecWithOnePosition::new();
228        let mut input = (0..10).collect::<Vec<i32>>();
229        v.append(&mut input);
230        v.set_position(Position(3));
231        v.remove(5);
232        assert_eq!(v.iter().map(|n| *n).collect::<Vec<i32>>(), vec![0, 1, 2, 3, 4, 6, 7, 8, 9]);
233        assert_eq!(v.get_position().0, 3);
234    }
235
236    #[test]
237    fn middle() {
238        let mut v = VecWithOnePosition::new();
239        let mut input = (0..10).collect::<Vec<i32>>();
240        v.append(&mut input);
241        v.set_position(Position(5));
242        v.remove(5);
243        assert_eq!(v.iter().map(|n| *n).collect::<Vec<i32>>(), vec![0, 1, 2, 3, 4, 6, 7, 8, 9]);
244        assert_eq!(v.get_position().0, 5);
245    }
246
247    #[test]
248    fn after() {
249        let mut v = VecWithOnePosition::new();
250        let mut input = (0..10).collect::<Vec<i32>>();
251        v.append(&mut input);
252        v.set_position(Position(7));
253        v.remove(5);
254        assert_eq!(v.iter().map(|n| *n).collect::<Vec<i32>>(), vec![0, 1, 2, 3, 4, 6, 7, 8, 9]);
255        assert_eq!(v.get_position().0, 6);
256    }
257}