Skip to main content

file_vec/
vec.rs

1impl<E:Clone> Clone for FileVec<E>{
2	fn clone(&self)->Self{
3		let mut result=FileVec::new();
4
5		result.extend_from_slice(&self);
6		result.set_persistent(self.persistent);
7		result
8	}
9	fn clone_from(&mut self,other:&Self){
10		self.clear();
11		self.extend_from_slice(other);
12	}
13}
14impl<E:Clone> From<&[E]> for FileVec<E>{
15	fn from(slice:&[E])->Self{slice.iter().cloned().collect()}
16}
17impl<E,const N:usize> FileVec<[E;N]>{
18	/// flatten FileVec<[E;N]> to FileVec<E>
19	pub fn into_flattened(mut self)->FileVec<E>{
20		FileVec{
21			len:mem::take(&mut self.len).checked_mul(N).unwrap(),
22			map:self.map.take(),
23			path:self.path.take(),
24			persistent:mem::take(&mut self.persistent),
25			phantom:PhantomData
26		}
27	}
28}
29impl<E,const N:usize> From<[E;N]> for FileVec<E>{
30	fn from(slice:[E;N])->Self{slice.into_iter().collect()}
31}
32impl<E> AsMut<[E]> for FileVec<E>{
33	fn as_mut(&mut self)->&mut [E]{self.as_mut_slice()}
34}
35impl<E> AsMut<Self> for FileVec<E>{
36	fn as_mut(&mut self)->&mut Self{self}
37}
38impl<E> AsRef<[E]> for FileVec<E>{
39	fn as_ref(&self)->&[E]{self.as_slice()}
40}
41impl<E> AsRef<Self> for FileVec<E>{
42	fn as_ref(&self)->&Self{self}
43}
44impl<E> Borrow<[E]> for FileVec<E>{
45	fn borrow(&self)->&[E]{self.as_slice()}
46}
47impl<E> BorrowMut<[E]> for FileVec<E>{
48	fn borrow_mut(&mut self)->&mut [E]{self.as_mut_slice()}
49}
50impl<E> Deref for FileVec<E>{
51	fn deref(&self)->&Self::Target{self.as_slice()}
52	type Target=[E];
53}
54impl<E> DerefMut for FileVec<E>{
55	fn deref_mut(&mut self)->&mut Self::Target{self.as_mut_slice()}
56}
57impl<E> Default for FileVec<E>{
58	fn default()->Self{Self::new()}
59}
60impl<E> Drop for FileVec<E>{
61	fn drop(&mut self){self.close()}
62}
63impl<E> Extend<E> for FileVec<E>{
64	fn extend<I:IntoIterator<Item=E>>(&mut self,iter:I){			// for unknown iter sizes limit reserve to 10^10 bytes to avoid unhinged file resizes from iterators with more conservative size hints than their use case
65		let iter=iter.into_iter();
66		let unknownreservelimit=1_00000_00000/mem::size_of::<E>();
67																	// reserve low if the hint appears exact, otherwise reserve high up to unknownreservelimit. ensure res is at least 1 because size_hint is not guaranteed correct for unsafe purposes. if the iter len actually is 0 for_each would immediately return and the resize in the loop wouldn't be executed
68		let (low,high)=iter.size_hint();
69		let mut cap=self.len;
70		let mut p=0 as *mut E;
71		let res=if Some(low)==high{low}else{high.unwrap_or(low).min(unknownreservelimit)}.max(1);
72
73		iter.for_each(|x|unsafe{									// reserve being at least 1 ensures there's space for 1 more, although p was initialized null, cap was initialized to self.len so p will be set before use
74			if cap<=self.len{										// if first iteration or capacity matches length, reserve space and update capacity
75				self.reserve(res);
76																	// if first iteration or capacity matches length, set the pointer to the end of the length in the current allocation
77				cap=self.capacity();
78				p=self.as_mut_ptr().add(self.len);
79			}
80																	// write the item to the end of the length, then increment length and pointer
81			ptr::write(p,x);
82			p=p.add(1);
83			self.len+=1;
84		});
85	}
86}
87impl<E> FileVec<E>{
88	/// allow len adjustment from other files in the crate
89	pub (crate) unsafe fn len_mut(&mut self)->&mut usize{&mut self.len}
90	/// moves all the elements of other into self, leaving other empty
91	pub fn append(&mut self,other:&mut Self){
92		assert_ne!(self.as_mut_ptr(),other.as_mut_ptr());
93		self.reserve(other.len);
94											// the base pointers are different if the file vec was initialized correctly, so i'd assume the files don't overlap so they shouldn't overlap in the memory map
95		unsafe{ptr::copy_nonoverlapping(other.as_mut_ptr() as *const E,self.as_mut_ptr().add(self.len),other.len)}
96		self.len+=other.len;
97		other.len=0;
98	}
99	/// references the mapped memory up to self.len() as a slice
100	pub fn as_mut_slice(&mut self)->&mut [E]{
101		let bytes:&mut [u8]=if let Some(m)=&mut self.map{m}else{return &mut []};
102		let items=unsafe{					// this should be okay if the file vec was created correctly and nothing modifed the file data
103			bytes.align_to_mut::<MaybeUninit<E>>()
104		};
105											// mmap should align to os page size which should work for anything. assert just in case
106		assert_eq!(items.0.len(),0);
107		assert_eq!(items.2.len(),0);
108
109		unsafe{								// the items up to len are initialized
110			mem::transmute(&mut items.1[..self.len])
111		}
112	}
113	/// returns a pointer to the start of the mapped memory
114	pub fn as_mut_ptr(&mut self)->*mut E{self.as_mut_slice().as_mut_ptr()}
115	/// returns a pointer to the start of the mapped memory
116	pub fn as_ptr(&self)->*const E{self.as_slice().as_ptr()}
117	/// references the mapped memory up to self.len() as a slice
118	pub fn as_slice(&self)->&[E]{
119		let bytes:&[u8]=if let Some(m)=&self.map{m}else{return &[]};
120		let items=unsafe{					// this should be okay if the file vec was created correctly and nothing modifed the file data
121			bytes.align_to::<MaybeUninit<E>>()
122		};
123											// mmap should align to os page size which should work for anything
124		assert_eq!(items.0.len(),0);
125		assert_eq!(items.2.len(),0);
126
127		unsafe{								// the items up to len are initialized
128			mem::transmute(&items.1[..self.len])
129		}
130	}
131	/// returns the capacity of the file FileVec
132	pub fn capacity(&self)->usize{self.map.as_ref().map(|x|x.len()/mem::size_of::<E>()).unwrap_or(0)}
133	/// drops all the items and sets len to 0. use close to make the vec also use a fresh file next time items are added
134	pub fn clear(&mut self){
135		if mem::needs_drop::<E>(){
136			let p=self.as_mut_ptr();
137			while self.len>0{				// file vec keeps data initialized up to len
138				self.len-=1;
139				unsafe{ptr::drop_in_place(p.add(self.len))}
140			}
141		}else{
142			self.len=0;
143		}
144	}
145	/// closes the backing file and resets the path. The file will be deleted unless self.is_persistent() is true. The persistence flag is preserved. self.len() will be 0 after this returns
146	pub fn close(&mut self){				// Take the path out of self.path to use and reset it. No need to close anything if None because there's no file. Shouldn't need to reset len in that case either because the items would need to be stored
147		let l=self.len;
148		let path=if let Some(p)=self.path.take(){p}else{return};
149											// drop items that need drop and reset len to 0
150		self.clear();
151											// drop mmap handle
152		self.map=None;
153											// trim the file to length if persistent for compact storage and ability to infer correct length when opening. delete the file otherwise
154		if self.persistent{
155			let file=OpenOptions::new().create(true).write(true).open(&path).unwrap();
156			file.set_len((mem::size_of::<E>()*l).try_into().unwrap()).unwrap();
157		}else{
158			fs::remove_file(&path).unwrap();
159		}
160	}
161	/// dedup by partial eq
162	pub fn dedup(&mut self) where E:PartialEq{self.dedup_by(|x,y|x==y)}
163	/// remove adjacent duplicates according to the same bucket function
164	pub fn dedup_by<F:FnMut(&mut E,&mut E)->bool>(&mut self,mut f:F){
165		let remaining=Cell::new(self.len);
166		if remaining.get()<=1{return}else{remaining.update(|r|r-1)}
167										// create new length counter and read and write pointers
168		let l:Cell<usize> =Cell::new(1);// a pointer to index 1 is valid because len is greater than 1. Otherwise the function would have returned early 2 lines ago
169		let r:Cell<*mut E>=Cell::new(unsafe{self.as_mut_ptr().add(1)});
170		let w:Cell<*mut E>=Cell::new(r.get());
171										// finalize by updating moving remaining items if any, then updating self.len to reflect the new length
172		let finalize=FinalizeDrop::new(||unsafe{
173			let remainder=remaining.get();
174			if remainder>0{				// if comparison or drop panic, move the rest of the array as if no further duplicates
175				ptr::copy(r.get(),w.get(),remainder);
176				l.update(|l|l+remainder);
177			}
178			self.len=l.get();
179		});								// refill with deduplicated items. the read pointer stays at or ahead of the write pointer
180		while remaining.get()>0{
181			unsafe{						// extract references to current and previous items
182				let current=&mut *r.get();
183				let previous=&mut *r.get().sub(1);
184										// check if duplicate
185				let f=f(current,previous);
186										// update r after f but before drop to ensure even in case of f panic or drop panic, the current item is removed if and only if f returns true
187				r.update(|r|r.add(1));
188				remaining.update(|r|r-1);
189										// if f is true, drop the current item, otherwise, move it to the current write position
190				if f{
191					ptr::drop_in_place(r.get());
192				}else{
193					ptr::copy(current,w.get(),1);
194										// update new length and write pointer after moving
195					l.update(|l|l+1);
196					w.update(|w|w.add(1));
197				}
198			}
199		}
200										// finalize
201		mem::drop(finalize);
202	}
203	/// dedup by key
204	pub fn dedup_by_key<F:FnMut(&mut E)->K,K:PartialEq>(&mut self,mut f:F){self.dedup_by(|x,y|f(x)==f(y))}
205	/// drain a range of items. Panics if start>stop or either start or stop is greater than self.len()
206	pub fn drain<R:RangeBounds<usize>>(&mut self,range:R)->Drain<'_,E>{Drain::new(self,range)}
207	/// pushes clones of all the items in the slice onto the file vec
208	pub fn extend_from_slice(&mut self,slice:&[E]) where E:Clone{
209		let l=slice.len();
210		self.reserve(l);
211										// get pointers
212		let mut p=unsafe{self.as_mut_ptr().add(self.len)};
213		let mut s=slice.as_ptr();
214										// iterate over the length of the slice, cloning slice items onto the vec. the length of the slice was reserved, so we wont run out of space
215		for _ in 0..l{
216			unsafe{
217				ptr::write(p,s.as_ref().unwrap_unchecked().clone());
218				self.len+=1;
219										// increment pointers after writing
220				p=p.add(1);
221				s=s.add(1);
222			}
223		}
224	}
225	/// clone a range of items onto the end. Panics if start>stop or either start or stop is greater than self.len()
226	pub fn extend_from_within<R:RangeBounds<usize>>(&mut self,range:R) where E:Clone{
227		let begin=range.start_bound();
228		let end=range.end_bound();
229		let start=match begin{							// normalize bounds
230			Bound::Excluded(&n)=>n.saturating_add(1),
231			Bound::Included(&n)=>n,
232			Bound::Unbounded   =>0
233		};
234		let stop= match end{
235			Bound::Excluded(&n)=>n,
236			Bound::Included(&n)=>n.saturating_add(1),
237			Bound::Unbounded   =>self.len
238		};
239														// bounds check
240		assert!(start<=self.len);
241		assert!(start<=stop);
242		assert!(stop <=self.len);
243														// reserve the needed space
244		self.reserve(stop-start);
245		let v=self.as_mut_ptr();
246														// get pointers
247		let mut p=unsafe{v.add(self.len)};
248		let mut s=unsafe{v.add(start)};
249														// iterate over the length of the slice, cloning slice items onto the vec. the length of the slice was reserved, so we wont run out of space
250		for _ in 0..stop-start{
251			unsafe{
252				ptr::write(p,s.as_ref().unwrap_unchecked().clone());
253				self.len+=1;
254														// increment pointers after writing
255				p=p.add(1);
256				s=s.add(1);
257			}
258		}
259	}
260	/// removes and yields items from the range where f is true. if the iterator is not exhausted, the remaining items will be left in the collection
261	pub fn extract_if<R:RangeBounds<usize>,F:FnMut(&mut E)->bool>(&mut self,r:R,f:F)->ExtractIf<'_,E,F>{ExtractIf::new(self,r,f)}
262	/// Creates a FileVec<T> where each element is produced by calling f with that element’s index while walking forward through the FileVec<T>
263	pub fn from_fn<F:FnMut(usize)->E>(length:usize,f:F)->Self{(0..length).map(f).collect()}
264	/// insert the item at the index, shifting all items after it
265	pub fn insert(&mut self,index:usize,item:E){
266		self.insert_mut(index,item);
267	}
268	/// insert the item at the index, shifting all items after it
269	pub fn insert_mut(&mut self,index:usize,item:E)->&mut E{
270		assert!(index<=self.len);
271		self.reserve(1);
272		unsafe{											// index is in bounds and should have at least one space available to copy to
273			let p=self.as_mut_ptr().add(index);
274														// copy everything at or above p to one index higher, then write item to p
275			ptr::copy(p,p.add(1),self.len-index);
276			ptr::write(p,item);
277														// adjust len and return the reference
278			self.len+=1;
279			p.as_mut().unwrap_unchecked()
280		}
281	}
282	/// groups every N items into chunks, dropping the remainder
283	pub fn into_chunks<const N:usize>(mut self)->FileVec<[E;N]>{
284		self.truncate(self.len-self.len%N);
285
286		FileVec{
287			len:mem::take(&mut self.len)/N,
288			map:self.map.take(),
289			path:self.path.take(),
290			persistent:mem::take(&mut self.persistent),
291			phantom:PhantomData
292		}
293	}
294	/// checks if empty
295	pub fn is_empty(&self)->bool{self.len==0}
296	/// returns whether the backing file will persist after the vec is dropped
297	pub fn is_persistent(&self)->bool{self.persistent}
298	/// returns the length of the file vec
299	pub fn len(&self)->usize{self.len}
300	/// creates new file vec. The file won't be created and the vec won't allocate until items are added to it
301	pub fn new()->Self{
302		assert_eq!(page_size::get()%mem::align_of::<E>(),0);
303		assert_ne!(mem::size_of::<E>(),0);
304
305		Self{
306			len:0,
307			map:None,
308			path:None,
309			persistent:false,
310			phantom:PhantomData
311		}
312	}
313	/// references the file path. returns none if the vec is new and empty and hasn't created a file yet
314	pub fn path(&self)->Option<&Path>{self.path.as_deref()}
315	/// remove the last item from the file
316	pub fn pop(&mut self)->Option<E>{
317		let l=self.len;
318		if l==0{return None}
319
320		self.len=l-1;
321		Some(unsafe{ptr::read(self.as_mut_ptr().add(l-1))})
322	}
323	/// conditionally remove the last item from the file
324	pub fn pop_if<F:FnOnce(&mut E)->bool>(&mut self,f:F)->Option<E>{
325		let l=self.len;
326		if l==0{return None}
327
328		unsafe{
329			let p=self.as_mut_ptr().add(l-1);
330			if !f(p.as_mut().unwrap_unchecked()){return None}
331
332			self.len=l-1;
333			Some(ptr::read(p))
334		}
335	}
336	/// push an item onto the file vec
337	pub fn push(&mut self,item:E){
338		self.reserve(1);
339		//dbg!((self.capacity(),self.len()));
340		unsafe{ptr::write(self.as_mut_ptr().add(self.len),item)}
341
342		self.len+=1;
343	}
344	/// push an item onto the file vec
345	pub fn push_mut(&mut self,item:E)->&mut E{
346		self.reserve(1);
347		unsafe{
348			let p=self.as_mut_ptr().add(self.len);
349			ptr::write(p,item);
350
351			self.len+=1;
352			p.as_mut().unwrap_unchecked()
353		}
354	}
355	/// push an item onto the file vec
356	pub fn push_within_capacity(&mut self,item:E)->Result<&mut E,E>{
357		if self.len()<self.capacity(){
358			Ok(unsafe{
359				let p=self.as_mut_ptr().add(self.len);
360				ptr::write(p,item);
361
362				self.len+=1;
363				p.as_mut().unwrap_unchecked()
364			})
365		}else{
366			Err(item)
367		}
368	}
369	/// remove and return the item at the index and shift elements after it down 1
370	pub fn remove(&mut self,index:usize)->E{
371		let l=self.len;
372		assert!(index<l);
373
374		unsafe{
375			let p=self.as_mut_ptr().add(index);
376			let item=ptr::read(p);
377
378			self.len=l-1;
379			ptr::copy(p.add(1),p,l-index);
380			item
381		}
382	}
383	/// remove and drop a range of items. Panics if start>stop or either start or stop is greater than self.len()
384	pub fn remove_range<R:RangeBounds<usize>>(&mut self,range:R){
385		Drain::new(self,range);
386	}
387	/// reserves capacity for at least additional more items in the backing file
388	pub fn reserve(&mut self,additional:usize){
389		let required=additional.saturating_add(self.len());
390		assert!(required<isize::MAX as usize);
391														// check if necessary and compute next capacity
392		let newcapacity=if required<=self.capacity(){return}else{required.next_power_of_two()};
393		if self.path.is_none(){							// generate a path if not allocated yet
394			let uid:u64=rand::random();
395			self.path=Some(format!(".file-vec_{uid:x}").into());
396		}
397														// unmap and reopen the file
398		self.map=None;
399		let file=OpenOptions::new().create(true).read(true).write(true).open(self.path.as_ref().unwrap()).unwrap();
400														// extend file length and remap
401		file.set_len((mem::size_of::<E>()*newcapacity).try_into().unwrap()).unwrap();
402		unsafe{self.map=Some(MmapMut::map_mut(&file).unwrap())}
403	}
404	/// reserves capacity for at least additional more items in the backing file
405	pub fn reserve_exect(&mut self,additional:usize){
406		let required=additional.saturating_add(self.len());
407		assert!(required<isize::MAX as usize);
408														// check if necessary and compute next capacity
409		let newcapacity=if required<=self.capacity(){return}else{required};
410		if self.path.is_none(){							// generate a path if not allocated yet
411			let uid:u64=rand::random();
412			self.path=Some(format!(".file-vec_{uid:x}").into());
413		}
414														// unmap and reopen the file
415		self.map=None;
416		let file=OpenOptions::new().create(true).read(true).write(true).open(self.path.as_ref().unwrap()).unwrap();
417														// extend file length and remap
418		file.set_len((mem::size_of::<E>()*newcapacity).try_into().unwrap()).unwrap();
419		unsafe{self.map=Some(MmapMut::map_mut(&file).unwrap())}
420	}
421	/// resize
422	pub fn resize(&mut self,len:usize,val:E) where E:Clone{
423		if len<self.len{return self.truncate(len)}else if len==self.len{return};
424
425		self.extend((self.len..len-1).map(|_|val.clone()));
426		self.push(val);
427	}
428	/// resize
429	pub fn resize_with<F:FnMut()->E>(&mut self,len:usize,mut f:F){
430		if len<self.len{return self.truncate(len)}else if len==self.len{return};
431		self.extend((self.len..len).map(|_|f()))
432	}
433	/// remove all items for which the function returns false
434	pub fn retain<F:FnMut(&E)->bool>(&mut self,mut f:F){self.retain_mut(|x|f(x))}
435	/// remove all items for which the function returns false
436	pub fn retain_mut<F:FnMut(&mut E)->bool>(&mut self,mut f:F){
437		let remaining=Cell::new(self.len);
438		if remaining.get()==0{return}
439										// create new length counter and read and write pointers
440		let l:Cell<usize> =Cell::new(0);
441		let r:Cell<*mut E>=Cell::new(self.as_mut_ptr());
442		let w:Cell<*mut E>=Cell::new(r.get());
443										// finalize by updating moving remaining items if any, then updating self.len to reflect the new length
444		let finalize=FinalizeDrop::new(||unsafe{
445			let remainder=remaining.get();
446			if remainder>0{				// if comparison or drop panic, move the rest of the array as if no further removals
447				ptr::copy(r.get(),w.get(),remainder);
448				l.update(|l|l+remainder);
449			}
450			self.len=l.get();
451		});								// refill with retained items. the read pointer stays at or ahead of the write pointer
452		while remaining.get()>0{
453			unsafe{						// extract references to current item and check if retained
454				let current=&mut *r.get();
455				let f=f(current);
456										// update r after f but before drop to ensure even in case of f panic or drop panic, the current item is removed if and only if f returns false
457				r.update(|r|r.add(1));
458				remaining.update(|r|r-1);
459										// if f is true, drop the current item, otherwise, move it to the current write position
460				if f{
461					ptr::copy(current,w.get(),1);
462										// update new length and write pointer after moving
463					l.update(|l|l+1);
464					w.update(|w|w.add(1));
465				}else{
466					ptr::drop_in_place(r.get());
467				}
468			}
469		}
470										// finalize
471		mem::drop(finalize);
472	}
473	/// sets whether the backing file should persist after the vec is dropped. Technically the file just existing doesn't cause any soundness problems, so this isn't marked as unsafe, but it probably shouldn't be set true on types requiring drop if the intent is to open the file in a new file vec later. Default value is usually false, except it's true for FileVec created by opening an existing file
474	pub fn set_persistent(&mut self,persistent:bool){self.persistent=persistent}
475	/// shrinks the capacity of the vector with a lower bound
476	pub fn shrink_to(&mut self,mut mincap:usize){
477		if mincap>=self.capacity(){return}
478		if mincap<self.len{mincap=self.len}
479											// get file path and unmap so we can edit the file through the file system
480		let path=if let Some(p)=self.path.take(){p}else{return};
481		self.map=None;
482											// trim the file to length
483		let file=OpenOptions::new().create(true).write(true).open(&path).unwrap();
484		file.set_len((mem::size_of::<E>()*mincap).try_into().unwrap()).unwrap();
485											// remap
486		self.path=Some(path);
487		unsafe{self.map=Some(MmapMut::map_mut(&file).unwrap())}
488	}
489	/// Shrinks the capacity of the vector as much as possible.
490	pub fn shrink_to_fit(&mut self){self.shrink_to(self.len)}
491	/// Returns the remaining spare capacity of the vector as a slice of MaybeUninit<E>
492	pub fn spare_capacity_mut(&mut self)->&mut [MaybeUninit<E>]{self.split_at_spare_mut().1}
493	/// Returns vector content as a slice of T, along with the remaining spare capacity of the vector as a slice of MaybeUninit<T>.
494	pub fn split_at_spare_mut(&mut self)->(&mut [E],&mut [MaybeUninit<E>]){
495		let bytes:&mut [u8]=if let Some(m)=&mut self.map{m}else{return (&mut [],&mut [])};
496		let items=unsafe{					// this should be okay if the file vec was created correctly and nothing modifed the file data
497			bytes.align_to_mut::<MaybeUninit<E>>()
498		};
499											// mmap should align to os page size which should work for anything. assert just in case
500		assert_eq!(items.0.len(),0);
501		assert_eq!(items.2.len(),0);
502
503		unsafe{								// the items up to len are initialized
504			mem::transmute(items.1.split_at_mut(self.len))
505		}
506	}
507	/// split the collection in two at the given index
508	pub fn split_off(&mut self,a:usize)->Self{self.drain(a..).collect()}
509	/// returns the item at this index, replacing it with the last item
510	pub fn swap_remove(&mut self,index:usize)->E{
511		assert!(index<self.len);
512
513		let last=self.pop().unwrap();
514		mem::replace(&mut self[index],last)
515	}
516	/// shorten the FileVec length to n if it's longer, dropping the extra
517	pub fn truncate(&mut self,n:usize){
518		if mem::needs_drop::<E>(){
519			unsafe{
520				let p=self.as_mut_ptr();
521				while n<self.len{
522					self.len-=1;
523					ptr::drop_in_place(p.add(self.len));
524				}
525			}
526		}else{
527			self.len=self.len.min(n);
528		}
529	}
530	/// create a file vec with at least an initial capacity
531	pub fn with_capacity(cap:usize)->Self{
532		let mut result=Self::new();
533
534		result.reserve(cap);
535		result
536	}
537	/// opens a file as a FileVec. The bytes in the file must be valid when interpreted as [T], the file should not be modified while in use, and the file must not be open in any other file vec or other memory mapping. An empty file will be created when the file vec allocates if the file doesn't exist. Regardless of whether the file already existed, the FileVec's persistence flag will be initialized to true
538	pub unsafe fn open<P:AsRef<Path>>(path:P)->IOResult<Self>{
539		assert_eq!(page_size::get()%mem::align_of::<E>(),0);
540		assert_ne!(mem::size_of::<E>(),0);
541
542		let path:PathBuf=path.as_ref().into();
543		let persistent=true;
544		let phantom=PhantomData;
545
546		let map=match OpenOptions::new().read(true).write(true).open(&path){
547			Err(e)=>if e.kind()==IOErrorKind::NotFound{
548				None
549			}else{
550				return Err(e)
551			},
552			Ok(file)=>Some(unsafe{MmapMut::map_mut(&file)?}),
553		};
554
555		let len=map.as_ref().map(|x|x.len()/mem::size_of::<E>()).unwrap_or(0);
556		let path=Some(path);
557
558		Ok(Self{len,map,path,persistent,phantom})
559	}
560	/// sets the length of the file vec. The data must be initialized up to the new length, and the new length must be within capacity
561	pub unsafe fn set_len(&mut self,len:usize){self.len=len}
562	/// sets the path to store the data in. The old file will be deleted unless the persistence flag is true. If data is already in the file, it will be copied to the file at the new path. If the new path points to an existing file it will be overwritten. The file should not be modified while in use, and the file must not be open in any other file vec or other memory mapping.
563	pub unsafe fn set_path<P:AsRef<Path>>(&mut self,path:P)->IOResult<()>{
564		if let Some(p)=self.path(){
565			if p==path.as_ref(){return Ok(())}
566		}
567
568		let old=self.path.clone();
569		let persistent=self.is_persistent();
570											// close the file and leave it in the file system so we can copy it
571		self.set_persistent(true);
572		self.close();
573											// copy the old file to the new file and remove if not persistent
574		if let Some(old)=old{
575			fs::copy(&old,&path)?;
576			if !persistent{fs::remove_file(old)?}
577		}
578											// open the new file as a file vec and preserve the persistence flag
579		*self=unsafe{Self::open(path)?};
580		self.set_persistent(persistent);
581
582		Ok(())
583	}
584}
585impl<E> FromIterator<E> for FileVec<E>{
586	fn from_iter<I:IntoIterator<Item=E>>(collection:I)->Self{
587		let mut result=Self::new();
588
589		result.extend(collection);
590		result
591	}
592}
593
594#[derive(Debug)]
595/// memory maps a file into a vec like structure. Avoid modifying the backing file while the file vec is living. Item alignment must be a factor of os page size. Cloning will copy the file. ZST currently not supported
596pub struct FileVec<E>{len:usize,map:Option<MmapMut>,path:Option<PathBuf>,persistent:bool,phantom:PhantomData<E>}
597
598use crate::{
599	FinalizeDrop,iter::{Drain,ExtractIf}
600};
601use memmap2::MmapMut;
602use std::{
603	borrow::{Borrow,BorrowMut},cell::Cell,cmp::PartialEq,fs::{OpenOptions,self},io::{ErrorKind as IOErrorKind,Result as IOResult},iter::FromIterator,marker::PhantomData,mem::{MaybeUninit,self},ops::{Bound,Deref,DerefMut,RangeBounds},path::{PathBuf,Path},ptr
604};