Skip to main content

file_vec/
lib.rs

1impl<F:FnOnce()> Drop for FinalizeDrop<F>{
2	fn drop(&mut self){
3		unsafe{self.0.assume_init_read()()}
4	}
5}
6impl<F:FnOnce()> FinalizeDrop<F>{
7	/// create a new drop finalizer from the function
8	pub fn new(inner:F)->Self{Self(MaybeUninit::new(inner))}
9}
10
11#[cfg(test)]
12mod tests{
13	#[test]
14	fn close_drop(){
15		let data=[Arc::new(1),Arc::new(2),Arc::new(3),Arc::new(4),Arc::new(5)];
16		let mut v=FileVec::new();
17
18		for x in data.iter().cloned(){v.push(x)}
19		let path=PathBuf::from(v.path().unwrap());
20
21		assert_eq!(Arc::strong_count(&data[0]),2);
22		assert_eq!(Arc::strong_count(&data[1]),2);
23		assert_eq!(Arc::strong_count(&data[2]),2);
24		assert_eq!(Arc::strong_count(&data[3]),2);
25		assert_eq!(Arc::strong_count(&data[4]),2);
26
27		v.close();
28		v.push(data[0].clone());
29
30		assert_eq!(Arc::strong_count(&data[0]),2);
31		assert_eq!(Arc::strong_count(&data[1]),1);
32		assert_eq!(Arc::strong_count(&data[2]),1);
33		assert_eq!(Arc::strong_count(&data[3]),1);
34		assert_eq!(Arc::strong_count(&data[4]),1);
35		assert_ne!(path,v.path().unwrap());
36
37		mem::drop(v);
38
39		assert_eq!(Arc::strong_count(&data[0]),1);
40	}
41	#[test]
42	fn dedup_by(){
43		let mut v=FileVec::new();
44
45		v.push(5);
46		v.push(4);
47		v.push(3);
48		v.push(3);
49		v.push(2);
50		v.push(1);
51		v.push(0);
52
53		v.dedup_by(|x,y|*x/2==*y/2);
54		assert_eq!([5,3,1],v.as_slice());
55	}
56	#[test]
57	fn drain_keep(){
58		let mut v=FileVec::new();
59
60		v.extend_from_slice(&[10,9,8,7,6,5,4,3,2,1]);
61
62		let mut drain=v.drain(1..9);
63
64		assert_eq!(drain.next(),Some(9));
65		assert_eq!(drain.next(),Some(8));
66		assert_eq!(drain.next_back(),Some(2));
67
68		assert_eq!(drain.as_slice(),[7,6,5,4,3]);
69		drain.keep_rest();
70
71		assert_eq!(drain.next(),None);
72		mem::drop(drain);
73
74		assert_eq!(v.as_slice(),[10,7,6,5,4,3,1]);
75
76		drain=v.drain(..);
77		drain.keep_rest();
78		mem::drop(drain);
79
80		assert_eq!(v.as_slice(),[10,7,6,5,4,3,1]);
81	}
82	#[test]
83	fn drain_remove(){
84		let mut v=FileVec::new();
85
86		v.push(5);
87		v.push(4);
88		v.push(3);
89		v.push(2);
90		v.push(1);
91
92		assert_eq!(v.drain(..3).as_slice(),[5,4,3]);
93		assert_eq!([2,1],v.as_slice());
94
95		v.push(2);
96		v.push(3);
97		v.push(4);
98
99		assert_eq!(v.drain(2..4).as_slice(),[2,3]);
100		assert_eq!([2,1,4],v.as_slice());
101
102		assert_eq!(v.drain(1..2).as_slice(),[1]);
103		assert_eq!([2,4],v.as_slice());
104
105		assert_eq!(v.drain(1..1).as_slice(),[]);
106		assert_eq!([2,4],v.as_slice());
107
108		v.push(6);
109		v.push(8);
110		v.push(10);
111		v.push(11);
112		v.push(12);
113
114		assert_eq!(v.drain(4..).as_slice(),[10,11,12]);
115		assert_eq!([2,4,6,8],v.as_slice());
116
117		assert_eq!(v.drain(..).as_slice(),[2,4,6,8]);
118		assert_eq!([0_i32;0],v.as_slice());
119	}
120	#[test]
121	fn extend_iter(){
122		let mut v=FileVec::new();
123
124		v.extend([5,4,3,2,1].iter().copied());
125		assert_eq!([5,4,3,2,1],v.as_slice());
126
127		v.extend([0,3,9,6].iter().copied());
128		assert_eq!([5,4,3,2,1,0,3,9,6],v.as_slice());
129	}
130	#[test]
131	fn extend_slice(){
132		let mut v=FileVec::new();
133
134		v.extend_from_slice(&[5,4,3,2,1]);
135		assert_eq!([5,4,3,2,1],v.as_slice());
136
137		v.extend_from_slice(&[0,3,9,6]);
138		assert_eq!([5,4,3,2,1,0,3,9,6],v.as_slice());
139	}
140	#[test]
141	fn extend_within(){
142		let mut v=FileVec::new();
143
144		v.extend_from_slice(&[5,4,3,2,1]);
145		assert_eq!([5,4,3,2,1],v.as_slice());
146
147		v.extend_from_within(1..4);
148		assert_eq!([5,4,3,2,1,4,3,2],v.as_slice());
149	}
150	#[test]
151	fn extract_if(){
152		let mut v=FileVec::new();
153		v.extend_from_slice(&[5,4,3,2,1,0,-2,-4,-6,3,3,3]);
154
155		let extracted:Vec<i32>=v.extract_if(2..,|x|*x%2==0).take(3).collect();
156
157		assert_eq!(extracted,[2,0,-2]);
158		assert_eq!(v.as_slice(),[5,4,3,1,-4,-6,3,3,3]);
159
160		let extracted:Vec<i32>=v.extract_if(2..,|x|*x%2>0).rev().take(3).collect();
161
162		assert_eq!(extracted,[3,3,3]);
163		assert_eq!(v.as_slice(),[5,4,3,1,-4,-6]);
164	}
165	#[test]
166	fn insert_remove(){
167		let mut v=FileVec::from([0,1,2,3,4,5,6,7,8,9]);
168
169		v.insert(10,-9);
170		v.insert( 9,-8);
171		v.insert( 3,-2);
172
173		v.insert( 9,-7);
174		v.insert( 8,-6);
175		v.insert( 7,-5);
176		v.insert( 6,-4);
177		v.insert( 5,-3);
178		//v.insert( 3,-2);
179		v.insert( 2,-1);
180		v.insert( 1, 0);
181		v.insert( 0, 1);
182
183		assert_eq!(v.as_slice(),[1,0,0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,9,-9]);
184
185		assert_eq!(v.remove(0),1);
186		assert_eq!(v.remove(1),0);
187		assert_eq!(v.remove(1),1);
188		assert_eq!(v.remove(2),2);
189		assert_eq!(v.remove(9),6);
190
191		assert_eq!(v.remove(3),3);
192		assert_eq!(v.remove(4),4);
193		assert_eq!(v.remove(5),5);
194		//assert_eq!(v.remove(6),6);
195		assert_eq!(v.remove(7),7);
196		assert_eq!(v.remove(8),8);
197		assert_eq!(v.remove(9),9);
198
199		assert_eq!(v.as_slice(),[0,-1,-2,-3,-4,-5,-6,-7,-8,-9]);
200		assert_eq!(v.remove(9),-9);
201		assert_eq!(v.remove(8),-8);
202		assert_eq!(v.remove(7),-7);
203		assert_eq!(v.remove(6),-6);
204	}
205	#[test]
206	fn load_persist(){
207		let mut v=FileVec::new();
208
209		v.push(5);
210		v.push(4);
211		v.push(3);
212		v.push(2);
213		v.push(1);
214		v.set_persistent(true);
215
216		let path=PathBuf::from(v.path().unwrap());
217
218		mem::drop(v);
219		v=unsafe{FileVec::open(path).unwrap()};
220		v.set_persistent(false);
221
222		assert_eq!([5,4,3,2,1],v.as_slice());
223	}
224	#[test]
225	fn new_push(){
226		let mut v=FileVec::new();
227
228		v.push(5);
229		v.push(4);
230		v.push(3);
231		v.push(2);
232		v.push(1);
233
234		assert_eq!([5,4,3,2,1],v.as_slice())
235	}
236	#[test]
237	fn remove_range(){
238		let mut v=FileVec::new();
239
240		v.push(5);
241		v.push(4);
242		v.push(3);
243		v.push(2);
244		v.push(1);
245		v.remove_range(..3);
246
247		assert_eq!([2,1],v.as_slice());
248
249		v.push(2);
250		v.push(3);
251		v.push(4);
252		v.remove_range(2..4);
253
254		assert_eq!([2,1,4],v.as_slice());
255
256		v.remove_range(1..2);
257
258		assert_eq!([2,4],v.as_slice());
259
260		v.remove_range(1..1);
261
262		assert_eq!([2,4],v.as_slice());
263
264		v.push(6);
265		v.push(8);
266		v.push(10);
267		v.push(11);
268		v.push(12);
269		v.remove_range(4..);
270
271		assert_eq!([2,4,6,8],v.as_slice());
272
273		v.remove_range(..);
274
275		assert_eq!([0_i32;0],v.as_slice());
276	}
277	#[test]
278	fn retain(){
279		let mut v=FileVec::new();
280		v.extend_from_slice(&[5,4,3,2,1,0,-2,-4,-6,3,3,3]);
281
282		v.retain(|x|*x%2==0);
283		assert_eq!(v.as_slice(),[4,2,0,-2,-4,-6]);
284	}
285
286	use std::{mem,path::PathBuf,sync::Arc};
287	use super::*;
288}
289/// helper struct for running function tail code that is required for drop soundness even if a panic occurs
290pub (crate) struct FinalizeDrop<F:FnOnce()>(MaybeUninit<F>);
291
292pub mod iter;
293pub mod vec;
294
295pub use vec::FileVec;
296use std::mem::MaybeUninit;