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}