mapped_vec/
lib.rs

1//! This crate is meant to provide an interface for vectors that not only store data, but also its order. This type of vector is called a mapped vector.
2//! A mapped vector is suitable for the fast processing of large types, because in the case of large types, it's faster to move around a few numbers specifying 
3//! the order of the data than to move around the actual data. The reverse and rotate functions of a mapped vector are O(1), because the reverse function simply
4//! changes the function to filter indices with, and the rotate function only has to edit a number offset for each index and possibly swap a few functions.
5//! Inserts and removes are also generally faster with this, even for small types. A mapped vector also supports turning into a regular vector, although this can
6//! be expensive, so it's recommended to use the get_mapped method to get a vector of references to elements in order instead. This works on no_std with alloc.
7//!
8//! Example Usage with Random Numbers and Timed Functions:
9//!
10//! # use mapped_vec::MappedVec;
11//! # use rand::prelude::*;
12//! #
13//! # fn main() {
14//! #     let mut rng = rand::thread_rng();
15//! #     let mut rgen = (0..100_000).map(|_| rng.gen::<f64>()).collect::<Vec<f64>>();
16//! #     
17//! #     let mut mapped = MappedVec::new();
18//! #     mapped.extend_from_slice(&rgen);
19//! #     
20//! #     let ind = rng.gen::<u16>() as usize;
21//! #     
22//! #     let timed = std::time::Instant::now();
23//! #     mapped.remove(ind);
24//! #     println!("Remove of mapped vector: {:?}", timed.elapsed());
25//! #     
26//! #     let timed = std::time::Instant::now();
27//! #     rgen.remove(ind);
28//! #     println!("Remove of regular vector: {:?}", timed.elapsed());
29//! # 
30//! #     let timed = std::time::Instant::now();
31//! #     mapped.insert(ind, 0.0);
32//! #     println!("Insert of mapped vector: {:?}", timed.elapsed());
33//! #     
34//! #     let timed = std::time::Instant::now();
35//! #     rgen.insert(ind, 0.0);
36//! #     println!("Insert of regular vector: {:?}", timed.elapsed());
37//! # 
38//! #     let timed = std::time::Instant::now();
39//! #     mapped.reverse();
40//! #     println!("Time to reverse mapped vector: {:?}", timed.elapsed());
41//! # 
42//! #     let timed = std::time::Instant::now();
43//! #     rgen.reverse();
44//! #     println!("Time to reverse regular vector: {:?}", timed.elapsed());
45//! # 
46//! #     let timed = std::time::Instant::now();
47//! #     let rvec = mapped.to_vec();
48//! #     println!("Time to convert mapped vector to real vector: {:?}", timed.elapsed());
49//! # 
50//! #     assert_eq!(rvec, rgen);
51//! # }
52#![no_std]
53#![forbid(unsafe_code)]
54extern crate alloc;
55use alloc::vec::Vec;
56use core::ops::{Index, IndexMut};
57mod ring;
58use ring::Ring;
59
60/// See the crate-level documentation for the description of this structure, which is all of the public API in this crate, as well as the method documentation for more info.
61pub struct MappedVec<T> {
62    vector: Vec<T>,
63    indices: Ring<usize>,
64}
65
66impl<T> MappedVec<T> {
67    /// This creates a new mapped vector.
68    pub fn new() -> MappedVec<T> {
69        MappedVec {
70            vector: Vec::new(),
71            indices: Ring::new(),
72        }
73    }
74
75    /// This appends a mapped vector to this one.
76    pub fn append(&mut self, v: &mut MappedVec<T>) {
77        for x in 0..v.indices.len() {
78            v.indices[x] += self.vector.len();
79        }
80        self.indices.append(&mut v.indices);
81        self.vector.append(&mut v.vector);
82        *v = MappedVec::new();
83    }
84    
85    /// This gets the length of a mapped vector.
86    pub fn len(&self) -> usize {
87        self.indices.len()
88    }
89    
90    /// This adds an element to a mapped vector.
91    pub fn push(&mut self, value: T) {
92        self.indices.push(self.vector.len());
93        self.vector.push(value);
94    }
95    
96    /// This quickly swaps elements of the vector.
97    pub fn swap(&mut self, x: usize, y: usize) {
98        self.indices.swap(x, y);
99    }
100    
101    /// This quickly pops off an element of the vector.
102    pub fn pop(&mut self) {
103        self.indices.pop();
104    }
105    
106    /// This quickly removes an element of the vector.
107    pub fn remove(&mut self, index: usize) {
108        self.indices.remove(index);
109    }
110    
111    /// This quickly inserts an element into an index of the vector.
112    pub fn insert(&mut self, index: usize, value: T) {
113        self.vector.push(value);
114        self.indices.insert(index, self.vector.len() - 1);
115    }
116
117    /// This quickly reverses the vector.
118    pub fn reverse(&mut self) {
119        self.indices.reverse();
120    }
121
122    /// This quickly rotates the vector's elements.
123    pub fn rotate(&mut self, offs: isize) {
124        self.indices.rotate(offs);
125    }
126
127    /// This clears the vector.
128    pub fn clear(&mut self) {
129        *self = MappedVec::new();
130    }
131    
132    /// This resizes a vector to a specific size. If the size exceeds the length of the vector, then the remaining elements are filled in by a specified closure.
133    pub fn resize_with<F: Fn() -> T>(&mut self, nl: usize, f: F) {
134        if nl <= self.len() {
135            for _ in nl..self.len() {
136                self.indices.pop();
137            }
138        } else {
139            let diff = nl - self.len();
140            for _ in 0..diff {
141                self.push(f());
142            }
143        }
144    }
145
146    /// This removes an element without caring about ordering.
147    pub fn swap_remove(&mut self, index: usize) {
148        self.swap(index, self.len() - 1);
149        self.indices.pop();
150    }
151
152    /// This checks if the vector is empty.
153    pub fn is_empty(&self) -> bool {
154        self.len() == 0
155    }
156
157    /// This changes the layout of the vector and resets the indices while maintaining the same indexing behavior.
158    pub fn update_vector(&mut self) {
159        for (n, x) in self.indices.iter_mut().enumerate() {
160            self.vector.swap(*x, n);
161            *x = n;
162        }
163    }
164
165    /// This extends the vector by an iterator.
166    pub fn extend<I: Iterator<Item = T> + Clone>(&mut self, iterator: I) {
167        self.indices.extend(0 + self.vector.len()..iterator.clone().count() + self.vector.len());
168        self.vector.extend(iterator);
169    }
170    
171    /// This gets an ordered vector of references to the elements of this vector.
172    pub fn get_mapped(&self) -> Vec<&T> {
173        let mut output = Vec::new();
174        for x in 0..self.len() {
175            output.push(self.index(x));
176        }
177        output
178    }
179}
180
181impl<T> Index<usize> for MappedVec<T> {
182    type Output = T;
183    fn index(&self, index: usize) -> &T {
184        self.vector.index(self.indices[index])
185    }
186}
187
188impl<T> IndexMut<usize> for MappedVec<T> {
189    fn index_mut(&mut self, index: usize) -> &mut T {
190        self.vector.index_mut(self.indices[index])
191    }
192}
193
194impl<T: Clone> MappedVec<T> {
195    /// This extends the vector.
196    pub fn extend_from_slice(&mut self, input: &[T]) {
197        self.indices.extend(self.len()..self.len() + input.len());
198        self.vector.extend(input.iter().cloned());
199    }
200
201    /// This is an expensive operation that turns this mapped vector into a regular one. It is recommended to use get_mapped whenever possible over this.
202    pub fn to_vec(&self) -> Vec<T> {
203        let mut output = Vec::new();
204        for x in 0..self.len() {
205            output.push(self.index(x).clone());
206        }
207        output
208    }
209    
210    /// This resizes the vector. If the size is large than the current size, then the remaining elements are turned into a specified value.
211    pub fn resize(&mut self, nl: usize, v: T) {
212        if nl <= self.len() {
213            for _ in nl..self.len() {
214                self.indices.pop();
215            }
216        } else {
217            let diff = nl - self.len();
218            for _ in 0..diff {
219                self.push(v.clone());
220            }
221        }
222    }
223}