1use std::pin::Pin;
32
33struct Block<T> {
35 vec: Vec<T>,
36}
37
38impl<T> Block<T> {
39 fn new(capacity: usize) -> Self {
40 Self {
41 vec: Vec::with_capacity(capacity),
42 }
43 }
44 fn get(&self, index: usize) -> Option<Pin<&T>> {
45 self.vec
47 .get(index)
48 .map(|p| unsafe { Pin::new_unchecked(p) })
49 }
50 fn get_mut(&mut self, index: usize) -> Option<Pin<&mut T>> {
51 self.vec
53 .get_mut(index)
54 .map(|p| unsafe { Pin::new_unchecked(p) })
55 }
56 fn push(&mut self, item: T) {
57 assert!(self.vec.len() < self.vec.capacity());
58 self.vec.push(item);
59 }
60 fn pop(&mut self) {
61 self.vec.truncate(self.vec.len() - 1);
62 }
63 fn replace(&mut self, index: usize, item: T) {
64 *self.vec.get_mut(index).unwrap() = item;
65 }
66}
67
68pub struct PinnedVec<T> {
70 blocks: Vec<Block<T>>,
71 len: usize,
72}
73
74impl<T> PinnedVec<T> {
75 fn outter_idx(index: usize) -> usize {
76 (usize::BITS - (index + 1).leading_zeros() - 1) as usize
77 }
78 fn split_idx(index: usize) -> (usize, usize) {
79 let m = index + 1;
80 let outter_idx = (usize::BITS - m.leading_zeros() - 1) as usize;
81 let inner_idx: usize = m & (!(1 << outter_idx));
82 (outter_idx, inner_idx)
83 }
84 pub fn new() -> Self {
87 Self {
88 blocks: Vec::new(),
89 len: 0,
90 }
91 }
92 pub fn len(&self) -> usize {
94 self.len
95 }
96 pub fn capacity(&self) -> usize {
100 let outter_idx = Self::outter_idx(self.len);
101 (1 << outter_idx) - 1
102 }
103 pub fn get(&self, index: usize) -> Option<Pin<&T>> {
105 if index >= self.len {
106 None
107 } else {
108 let (outter, inner) = Self::split_idx(index);
109 let block = self.blocks.get(outter).unwrap();
110 let item = block.get(inner).unwrap();
111 Some(item)
112 }
113 }
114 pub fn get_mut(&mut self, index: usize) -> Option<Pin<&mut T>> {
116 if index >= self.len {
117 None
118 } else {
119 let (outter, inner) = Self::split_idx(index);
120 let block = self.blocks.get_mut(outter).unwrap();
121 let item = block.get_mut(inner).unwrap();
122 Some(item)
123 }
124 }
125 pub fn push(&mut self, item: T) {
128 let outter_idx = Self::outter_idx(self.len);
129 if self.blocks.len() <= outter_idx {
130 let new_block = Block::new(1 << outter_idx);
131 self.blocks.push(new_block);
132 }
133 self.blocks[outter_idx].push(item);
134 self.len += 1;
135 }
136 pub fn pop(&mut self) {
141 assert!(self.len > 0);
142 self.len -= 1;
143 let outter_idx = Self::outter_idx(self.len);
144 self.blocks[outter_idx].pop();
145 }
146 pub fn replace(&mut self, index: usize, item: T) {
151 let (outter, inner) = Self::split_idx(index);
152 self.blocks[outter].replace(inner, item);
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use std::fmt::Debug;
159
160 use super::*;
161
162 struct Both<T> {
163 normal: Vec<T>,
164 pinned: PinnedVec<T>,
165 }
166
167 impl<T> Both<T> {
168 fn new() -> Self {
169 Self {
170 normal: Vec::new(),
171 pinned: PinnedVec::new(),
172 }
173 }
174 }
175
176 impl<T: PartialEq + Debug> Both<T> {
177 fn check(&self) {
178 let len = self.normal.len();
179 assert_eq!(len, self.pinned.len());
180 for i in 0..len {
181 assert_eq!(self.normal.get(i), self.pinned.get(i).as_deref());
182 }
183 assert_eq!(self.pinned.get(len), None);
184 }
185 }
186 impl<T: Clone> Both<T> {
187 fn push(&mut self, item: T) {
188 self.normal.push(item.clone());
189 self.pinned.push(item);
190 }
191 fn pop(&mut self) {
192 self.normal.pop();
193 self.pinned.pop();
194 }
195 fn replace(&mut self, index: usize, item: T) {
196 self.normal[index] = item.clone();
197 self.pinned.replace(index, item);
198 }
199 }
200
201 #[test]
202 fn one() {
203 let mut b: Both<i32> = Both::new();
204 for i in 0..200 {
205 for j in 0..i {
206 b.push(j);
207 }
208 b.check();
209 for _ in 0..(i - 2) {
210 b.pop();
211 }
212 b.check();
213 for j in (0..(i / 5)).map(|x| x * 3) {
214 b.replace(j as usize, -j);
215 }
216 b.check();
217 }
218 }
219
220 #[test]
221 fn two() {
222 let mut b: Both<i32> = Both::new();
223 b.push(1);
224 b.push(2);
225 b.push(3);
226 b.push(4);
227 b.check();
228 b.push(5);
229 b.push(6);
230 b.push(7);
231 b.check();
232 b.pop();
233 b.check();
234 b.pop();
235 b.check();
236 b.pop();
237 b.check();
238 b.pop();
239 b.check();
240 b.push(5);
241 b.check()
242 }
243}