1#![deny(missing_docs)]
16
17use rustc_hash::FxHashMap as HashMap;
18use std::cell::Cell;
19use std::cmp::min;
20use std::sync::{Mutex, RwLock};
21
22pub use std::sync::Arc;
23
24#[cfg(feature = "pstd")]
25use pstd::{
26 VecA,
27 collections::{BTreeMapA, btree_map::CustomTuning},
28 localalloc::GTemp,
29 veca as gvec,
30};
31
32#[cfg(not(feature = "pstd"))]
33use std::{collections::BTreeMap, vec as gvec, vec::Vec as GVec};
34
35#[cfg(feature = "pstd")]
36type BTreeMap<K, V> = BTreeMapA<K, V, CustomTuning<GTemp>>;
37
38#[cfg(feature = "pstd")]
39type GVec<T> = VecA<T, GTemp>;
40
41pub type Data = Arc<GVec<u8>>;
43
44pub struct AtomicFile {
61 map: WMap,
63 cf: Arc<RwLock<CommitFile>>,
65 size: u64,
67 tx: std::sync::mpsc::Sender<(u64, WMap)>,
69 busy: Arc<Mutex<()>>,
71 map_lim: usize,
73}
74
75impl AtomicFile {
76 pub fn new(stg: Box<dyn Storage>, upd: Box<dyn BasicStorage>) -> Box<Self> {
78 Self::new_with_limits(stg, upd, &Limits::default())
79 }
80
81 pub fn new_with_limits(
83 stg: Box<dyn Storage>,
84 upd: Box<dyn BasicStorage>,
85 lim: &Limits,
86 ) -> Box<Self> {
87 let size = stg.size();
88 let mut baf = BasicAtomicFile::new(stg.clone(), upd, lim);
89
90 let (tx, rx) = std::sync::mpsc::channel::<(u64, WMap)>();
91 let cf = Arc::new(RwLock::new(CommitFile::new(stg, lim.rbuf_mem)));
92 let busy = Arc::new(Mutex::new(())); let (cf1, busy1) = (cf.clone(), busy.clone());
96
97 std::thread::spawn(move || {
98 while let Ok((size, map)) = rx.recv() {
100 let _lock = busy1.lock();
101 baf.map = map;
102 baf.commit(size);
103 cf1.write().unwrap().done_one();
104 }
105 });
106 Box::new(Self {
107 map: WMap::default(),
108 cf,
109 size,
110 tx,
111 busy,
112 map_lim: lim.map_lim,
113 })
114 }
115}
116
117impl Storage for AtomicFile {
118 fn clone(&self) -> Box<dyn Storage> {
119 panic!()
120 }
121}
122
123impl BasicStorage for AtomicFile {
124 fn commit(&mut self, size: u64) {
125 self.size = size;
126 if self.map.is_empty() {
127 return;
128 }
129 if self.cf.read().unwrap().map.len() > self.map_lim {
130 self.wait_complete();
131 }
132 let map = std::mem::take(&mut self.map);
133 let stop =
134 {
135 let cf = &mut *self.cf.write().unwrap();
136 if cf.stop { true }
137 else
138 {
139 cf.todo += 1;
140 map.to_storage(cf);
142 self.tx.send((size, map)).unwrap();
144 false
145 }
146 };
147 if stop {
148 loop { std::thread::sleep(std::time::Duration::from_millis(100)); }
150 }
151 }
152
153 fn size(&self) -> u64 {
154 self.size
155 }
156
157 fn read(&self, start: u64, data: &mut [u8]) {
158 self.map.read(start, data, &*self.cf.read().unwrap());
159 }
160
161 fn write_data(&mut self, start: u64, data: Data, off: usize, len: usize) {
162 self.map.write(start, data, off, len);
163 }
164
165 fn write(&mut self, start: u64, data: &[u8]) {
166 let len = data.len();
167 let d = Arc::new(data.to_vec());
168 self.write_data(start, d, 0, len);
169 }
170
171 fn wait_complete(&self) {
172 while self.cf.read().unwrap().todo != 0 {
173 std::thread::yield_now();
174 let _x = self.busy.lock();
175 }
176 }
177
178 fn shutdown(&mut self) {
179 self.cf.write().unwrap().stop = true; self.wait_complete();
181 }
182}
183
184struct CommitFile {
185 stg: ReadBufStg<256>,
187 map: WMap,
189 todo: usize,
191 stop: bool,
193}
194
195impl CommitFile {
196 fn new(stg: Box<dyn Storage>, buf_mem: usize) -> Self {
197 Self {
198 stg: ReadBufStg::<256>::new(stg, 50, buf_mem / 256),
199 map: WMap::default(),
200 todo: 0,
201 stop: false,
202 }
203 }
204
205 fn done_one(&mut self) {
206 self.todo -= 1;
207 if self.todo == 0 {
208 self.map = WMap::default();
209 self.stg.reset();
210 }
211 }
212}
213
214impl BasicStorage for CommitFile {
215 fn commit(&mut self, _size: u64) {
216 panic!()
217 }
218
219 fn size(&self) -> u64 {
220 panic!()
221 }
222
223 fn read(&self, start: u64, data: &mut [u8]) {
224 self.map.read(start, data, &self.stg);
225 }
226
227 fn write_data(&mut self, start: u64, data: Data, off: usize, len: usize) {
228 self.map.write(start, data, off, len);
229 }
230
231 fn write(&mut self, _start: u64, _data: &[u8]) {
232 panic!()
233 }
234}
235
236pub trait BasicStorage: Send {
240 fn size(&self) -> u64;
243
244 fn read(&self, start: u64, data: &mut [u8]);
246
247 fn write(&mut self, start: u64, data: &[u8]);
249
250 fn write_vec(&mut self, start: u64, data: Vec<u8>) {
252 let len = data.len();
253 let d = Arc::new(data);
254 self.write_data(start, d, 0, len);
255 }
256
257 fn write_data(&mut self, start: u64, data: Data, off: usize, len: usize) {
259 self.write(start, &data[off..off + len]);
260 }
261
262 fn commit(&mut self, size: u64);
264
265 fn write_u64(&mut self, start: u64, value: u64) {
267 self.write(start, &value.to_le_bytes());
268 }
269
270 fn read_u64(&self, start: u64) -> u64 {
272 let mut bytes = [0; 8];
273 self.read(start, &mut bytes);
274 u64::from_le_bytes(bytes)
275 }
276
277 fn wait_complete(&self){}
279
280 fn shutdown(&mut self){}
282}
283
284pub trait Storage: BasicStorage + Sync {
286 fn clone(&self) -> Box<dyn Storage>;
288}
289
290#[derive(Default)]
292pub struct MemFile {
293 v: Arc<Mutex<Vec<u8>>>,
294}
295
296impl MemFile {
297 pub fn new() -> Box<Self> {
299 Box::default()
300 }
301}
302
303impl Storage for MemFile {
304 fn clone(&self) -> Box<dyn Storage> {
305 Box::new(Self { v: self.v.clone() })
306 }
307}
308
309impl BasicStorage for MemFile {
310 fn size(&self) -> u64 {
311 let v = self.v.lock().unwrap();
312 v.len() as u64
313 }
314
315 fn read(&self, off: u64, bytes: &mut [u8]) {
316 let off = off as usize;
317 let len = bytes.len();
318 let mut v = self.v.lock().unwrap();
319 if off + len > v.len() {
320 v.resize(off + len, 0);
321 }
322 bytes.copy_from_slice(&v[off..off + len]);
323 }
324
325 fn write(&mut self, off: u64, bytes: &[u8]) {
326 let off = off as usize;
327 let len = bytes.len();
328 let mut v = self.v.lock().unwrap();
329 if off + len > v.len() {
330 v.resize(off + len, 0);
331 }
332 v[off..off + len].copy_from_slice(bytes);
333 }
334
335 fn commit(&mut self, size: u64) {
336 let mut v = self.v.lock().unwrap();
337 v.resize(size as usize, 0);
338 }
339}
340
341use std::{fs, fs::OpenOptions, io::Read, io::Seek, io::SeekFrom, io::Write};
342
343struct FileInner {
344 f: fs::File,
345}
346
347impl FileInner {
348 pub fn new(filename: &str) -> Self {
350 Self {
351 f: OpenOptions::new()
352 .read(true)
353 .write(true)
354 .create(true)
355 .truncate(false)
356 .open(filename)
357 .unwrap(),
358 }
359 }
360
361 fn size(&mut self) -> u64 {
362 self.f.seek(SeekFrom::End(0)).unwrap()
363 }
364
365 fn read(&mut self, off: u64, bytes: &mut [u8]) {
366 self.f.seek(SeekFrom::Start(off)).unwrap();
367 let _ = self.f.read(bytes).unwrap();
368 }
369
370 fn write(&mut self, off: u64, bytes: &[u8]) {
371 #[cfg(not(any(target_os = "windows", target_os = "linux")))]
373 {
374 let size = self.f.seek(SeekFrom::End(0)).unwrap();
375 if off > size {
376 self.f.set_len(off).unwrap();
377 }
378 }
379 self.f.seek(SeekFrom::Start(off)).unwrap();
380 let _ = self.f.write(bytes).unwrap();
381 }
382
383 fn commit(&mut self, size: u64) {
384 self.f.set_len(size).unwrap();
385 self.f.sync_all().unwrap();
386 }
387}
388
389pub struct UpdFileStorage {
391 file: Cell<Option<FileInner>>,
392}
393
394impl UpdFileStorage {
395 pub fn new(filename: &str) -> Box<Self> {
397 Box::new(Self {
398 file: Cell::new(Some(FileInner::new(filename))),
399 })
400 }
401}
402
403impl BasicStorage for UpdFileStorage {
404 fn size(&self) -> u64 {
405 let mut f = self.file.take().unwrap();
406 let result = f.size();
407 self.file.set(Some(f));
408 result
409 }
410 fn read(&self, off: u64, bytes: &mut [u8]) {
411 let mut f = self.file.take().unwrap();
412 f.read(off, bytes);
413 self.file.set(Some(f));
414 }
415
416 fn write(&mut self, off: u64, bytes: &[u8]) {
417 let mut f = self.file.take().unwrap();
418 f.write(off, bytes);
419 self.file.set(Some(f));
420 }
421
422 fn commit(&mut self, size: u64) {
423 let mut f = self.file.take().unwrap();
424 f.commit(size);
425 self.file.set(Some(f));
426 }
427}
428
429pub struct SimpleFileStorage {
431 file: Arc<Mutex<FileInner>>,
432}
433
434impl SimpleFileStorage {
435 pub fn new(filename: &str) -> Box<Self> {
437 Box::new(Self {
438 file: Arc::new(Mutex::new(FileInner::new(filename))),
439 })
440 }
441}
442
443impl Storage for SimpleFileStorage {
444 fn clone(&self) -> Box<dyn Storage> {
445 Box::new(Self {
446 file: self.file.clone(),
447 })
448 }
449}
450
451impl BasicStorage for SimpleFileStorage {
452 fn size(&self) -> u64 {
453 self.file.lock().unwrap().size()
454 }
455
456 fn read(&self, off: u64, bytes: &mut [u8]) {
457 self.file.lock().unwrap().read(off, bytes);
458 }
459
460 fn write(&mut self, off: u64, bytes: &[u8]) {
461 self.file.lock().unwrap().write(off, bytes);
462 }
463
464 fn commit(&mut self, size: u64) {
465 self.file.lock().unwrap().commit(size);
466 }
467}
468
469pub struct AnyFileStorage {
471 filename: String,
472 files: Arc<Mutex<Vec<FileInner>>>,
473}
474
475impl AnyFileStorage {
476 pub fn new(filename: &str) -> Box<Self> {
478 Box::new(Self {
479 filename: filename.to_owned(),
480 files: Arc::new(Mutex::new(Vec::new())),
481 })
482 }
483
484 fn get_file(&self) -> FileInner {
485 match self.files.lock().unwrap().pop() {
486 Some(f) => f,
487 _ => FileInner::new(&self.filename),
488 }
489 }
490
491 fn put_file(&self, f: FileInner) {
492 self.files.lock().unwrap().push(f);
493 }
494}
495
496impl Storage for AnyFileStorage {
497 fn clone(&self) -> Box<dyn Storage> {
498 Box::new(Self {
499 filename: self.filename.clone(),
500 files: self.files.clone(),
501 })
502 }
503}
504
505impl BasicStorage for AnyFileStorage {
506 fn size(&self) -> u64 {
507 let mut f = self.get_file();
508 let result = f.size();
509 self.put_file(f);
510 result
511 }
512
513 fn read(&self, off: u64, bytes: &mut [u8]) {
514 let mut f = self.get_file();
515 f.read(off, bytes);
516 self.put_file(f);
517 }
518
519 fn write(&mut self, off: u64, bytes: &[u8]) {
520 let mut f = self.get_file();
521 f.write(off, bytes);
522 self.put_file(f);
523 }
524
525 fn commit(&mut self, size: u64) {
526 let mut f = self.get_file();
527 f.commit(size);
528 self.put_file(f);
529 }
530}
531
532pub struct DummyFile {}
534impl DummyFile {
535 pub fn new() -> Box<Self> {
537 Box::new(Self {})
538 }
539}
540
541impl Storage for DummyFile {
542 fn clone(&self) -> Box<dyn Storage> {
543 Self::new()
544 }
545}
546
547impl BasicStorage for DummyFile {
548 fn size(&self) -> u64 {
549 0
550 }
551
552 fn read(&self, _off: u64, _bytes: &mut [u8]) {}
553
554 fn write(&mut self, _off: u64, _bytes: &[u8]) {}
555
556 fn commit(&mut self, _size: u64) {}
557}
558
559#[non_exhaustive]
561pub struct Limits {
562 pub map_lim: usize,
564 pub rbuf_mem: usize,
566 pub swbuf: usize,
568 pub uwbuf: usize,
570}
571
572impl Default for Limits {
573 fn default() -> Self {
574 Self {
575 map_lim: 5000,
576 rbuf_mem: 0x200000,
577 swbuf: 0x100000,
578 uwbuf: 0x100000,
579 }
580 }
581}
582
583struct WriteBuffer {
585 ix: usize,
587 pos: u64,
589 pub stg: Box<dyn BasicStorage>,
591 buf: Vec<u8>,
593}
594
595impl WriteBuffer {
596 pub fn new(stg: Box<dyn BasicStorage>, buf_size: usize) -> Self {
598 Self {
599 ix: 0,
600 pos: u64::MAX,
601 stg,
602 buf: vec![0; buf_size],
603 }
604 }
605
606 pub fn write(&mut self, off: u64, data: &[u8]) {
608 if self.pos + self.ix as u64 != off {
609 self.flush(off);
610 }
611 let mut done: usize = 0;
612 let mut todo: usize = data.len();
613 while todo > 0 {
614 let mut n: usize = self.buf.len() - self.ix;
615 if n == 0 {
616 self.flush(off + done as u64);
617 n = self.buf.len();
618 }
619 if n > todo {
620 n = todo;
621 }
622 self.buf[self.ix..self.ix + n].copy_from_slice(&data[done..done + n]);
623 todo -= n;
624 done += n;
625 self.ix += n;
626 }
627 }
628
629 fn flush(&mut self, new_pos: u64) {
630 if self.ix > 0 {
631 self.stg.write(self.pos, &self.buf[0..self.ix]);
632 }
633 self.ix = 0;
634 self.pos = new_pos;
635 }
636
637 pub fn commit(&mut self, size: u64) {
639 self.flush(u64::MAX);
640 self.stg.commit(size);
641 }
642
643 pub fn write_u64(&mut self, start: u64, value: u64) {
645 self.write(start, &value.to_le_bytes());
646 }
647}
648
649struct ReadBufStg<const N: usize> {
655 stg: Box<dyn Storage>,
657 buf: Mutex<ReadBuffer<N>>,
659 limit: usize,
661}
662
663impl<const N: usize> Drop for ReadBufStg<N> {
664 fn drop(&mut self) {
665 self.reset();
666 }
667}
668
669impl<const N: usize> ReadBufStg<N> {
670 pub fn new(stg: Box<dyn Storage>, limit: usize, max_buf: usize) -> Self {
672 Self {
673 stg,
674 buf: Mutex::new(ReadBuffer::<N>::new(max_buf)),
675 limit,
676 }
677 }
678
679 fn reset(&mut self) {
681 self.buf.lock().unwrap().reset();
682 }
683}
684
685impl<const N: usize> BasicStorage for ReadBufStg<N> {
686 fn read(&self, start: u64, data: &mut [u8]) {
688 if data.len() <= self.limit {
689 self.buf.lock().unwrap().read(&*self.stg, start, data);
690 } else {
691 self.stg.read(start, data);
692 }
693 }
694
695 fn size(&self) -> u64 {
697 panic!()
698 }
699
700 fn write(&mut self, _start: u64, _data: &[u8]) {
702 panic!();
703 }
704
705 fn commit(&mut self, _size: u64) {
707 panic!();
708 }
709}
710
711struct ReadBuffer<const N: usize> {
712 map: HashMap<u64, Box<[u8; N]>>,
714 max_buf: usize,
716}
717
718impl<const N: usize> ReadBuffer<N> {
719 fn new(max_buf: usize) -> Self {
720 Self {
721 map: HashMap::default(),
722 max_buf,
723 }
724 }
725
726 fn reset(&mut self) {
727 self.map.clear();
728 }
729
730 fn read(&mut self, stg: &dyn BasicStorage, off: u64, data: &mut [u8]) {
731 let mut done = 0;
732 while done < data.len() {
733 let off = off + done as u64;
734 let sector = off / N as u64;
735 let disp = (off % N as u64) as usize;
736 let amount = min(data.len() - done, N - disp);
737
738 let p = self.map.entry(sector).or_insert_with(|| {
739 let mut p: Box<[u8; N]> = vec![0; N].try_into().unwrap();
740 stg.read(sector * N as u64, &mut *p);
741 p
742 });
743 data[done..done + amount].copy_from_slice(&p[disp..disp + amount]);
744 done += amount;
745 }
746 if self.map.len() >= self.max_buf {
747 self.reset();
748 }
749 }
750}
751
752#[derive(Default)]
753struct DataSlice {
755 pub data: Data,
757 pub off: usize,
759 pub len: usize,
761}
762
763impl DataSlice {
764 pub fn all(&self) -> &[u8] {
766 &self.data[self.off..self.off + self.len]
767 }
768 pub fn part(&self, off: usize, len: usize) -> &[u8] {
770 &self.data[self.off + off..self.off + off + len]
771 }
772 pub fn trim(&mut self, trim: usize) {
774 self.off += trim;
775 self.len -= trim;
776 }
777 #[allow(dead_code)]
779 pub fn take(&mut self) -> Data {
780 std::mem::take(&mut self.data)
781 }
782}
783
784#[derive(Default)]
785struct WMap {
787 map: BTreeMap<u64, DataSlice>,
789}
790
791impl WMap {
792 pub fn is_empty(&self) -> bool {
794 self.map.is_empty()
795 }
796
797 pub fn len(&self) -> usize {
799 self.map.len()
800 }
801
802 pub fn convert_to_vec(&mut self) -> GVec<(u64, DataSlice)> {
804 let map = std::mem::take(&mut self.map);
805 let mut result = GVec::with_capacity(map.len());
806 for (end, v) in map {
807 let start = end - v.len as u64;
808 result.push((start, v));
809 }
810 result
811 }
812
813 pub fn to_storage(&self, stg: &mut dyn BasicStorage) {
815 for (end, v) in self.map.iter() {
816 let start = end - v.len as u64;
817 stg.write_data(start, v.data.clone(), v.off, v.len);
818 }
819 }
820
821 #[cfg(not(feature = "pstd"))]
822 pub fn write(&mut self, start: u64, data: Data, off: usize, len: usize) {
824 if len != 0 {
825 let (mut insert, mut remove) = (Vec::new(), Vec::new());
826 let end = start + len as u64;
827 for (ee, v) in self.map.range_mut(start + 1..) {
828 let ee = *ee;
829 let es = ee - v.len as u64; if es >= end {
831 break;
833 } else if start <= es {
834 if end < ee {
835 v.trim((end - es) as usize);
837 break;
838 }
839 remove.push(ee);
841 } else if end < ee {
842 insert.push((es, v.data.clone(), v.off, (start - es) as usize));
845 v.trim((end - es) as usize);
846 break;
847 } else {
848 insert.push((es, v.take(), v.off, (start - es) as usize));
851 remove.push(ee);
852 }
853 }
854 for end in remove {
855 self.map.remove(&end);
856 }
857 for (start, data, off, len) in insert {
858 self.map
859 .insert(start + len as u64, DataSlice { data, off, len });
860 }
861 self.map
862 .insert(start + len as u64, DataSlice { data, off, len });
863 }
864 }
865
866 #[cfg(feature = "pstd")]
867 pub fn write(&mut self, start: u64, data: Data, off: usize, len: usize) {
869 if len != 0 {
870 let end = start + len as u64;
871 let mut c = self
872 .map
873 .lower_bound_mut(std::ops::Bound::Excluded(&start))
874 .with_mutable_key();
875 while let Some((eend, v)) = c.next() {
876 let ee = *eend;
877 let es = ee - v.len as u64; if es >= end {
879 c.prev();
881 break;
882 } else if start <= es {
883 if end < ee {
884 v.trim((end - es) as usize);
886 c.prev();
887 break;
888 }
889 c.remove_prev();
891 } else if end < ee {
892 let (data, off, len) = (v.data.clone(), v.off, (start - es) as usize);
895 v.trim((end - es) as usize);
896 c.prev();
897 c.insert_before_unchecked(es + len as u64, DataSlice { data, off, len });
898 break;
899 } else {
900 v.len = (start - es) as usize;
903 *eend = es + v.len as u64;
904 }
905 }
906 c.insert_after_unchecked(start + len as u64, DataSlice { data, off, len });
908 }
909 }
910
911 pub fn read(&self, start: u64, data: &mut [u8], u: &dyn BasicStorage) {
913 let len = data.len();
914 if len != 0 {
915 let mut done = 0;
916 for (&end, v) in self.map.range(start + 1..) {
917 let es = end - v.len as u64; let doff = start + done as u64;
919 if es > doff {
920 let a = min(len - done, (es - doff) as usize);
922 u.read(doff, &mut data[done..done + a]);
923 done += a;
924 if done == len {
925 return;
926 }
927 }
928 let skip = (start + done as u64 - es) as usize;
930 let a = min(len - done, v.len - skip);
931 data[done..done + a].copy_from_slice(v.part(skip, a));
932 done += a;
933 if done == len {
934 return;
935 }
936 }
937 u.read(start + done as u64, &mut data[done..]);
938 }
939 }
940}
941
942pub struct BasicAtomicFile {
944 stg: WriteBuffer,
946 upd: WriteBuffer,
948 map: WMap,
950 list: GVec<(u64, DataSlice)>,
952 size: u64,
953 stop: bool,
954}
955
956impl BasicAtomicFile {
957 pub fn new(stg: Box<dyn BasicStorage>, upd: Box<dyn BasicStorage>, lim: &Limits) -> Box<Self> {
959 let size = stg.size();
960 let mut result = Box::new(Self {
961 stg: WriteBuffer::new(stg, lim.swbuf),
962 upd: WriteBuffer::new(upd, lim.uwbuf),
963 map: WMap::default(),
964 list: GVec::new(),
965 size,
966 stop: false,
967 });
968 result.init();
969 result
970 }
971
972 fn init(&mut self) {
974 let end = self.upd.stg.read_u64(0);
975 let size = self.upd.stg.read_u64(8);
976 if end == 0 {
977 return;
978 }
979 assert!(end == self.upd.stg.size());
980 let mut pos = 16;
981 while pos < end {
982 let start = self.upd.stg.read_u64(pos);
983 pos += 8;
984 let len = self.upd.stg.read_u64(pos);
985 pos += 8;
986 let mut buf: GVec<u8> = gvec![0; len as usize];
987 self.upd.stg.read(pos, &mut buf);
988 pos += len;
989 self.stg.write(start, &buf);
990 }
991 self.stg.commit(size);
992 self.upd.commit(0);
993 }
994
995 pub fn commit_phase(&mut self, size: u64, phase: u8) {
997 if self.map.is_empty() && self.list.is_empty() {
998 return;
999 }
1000 if phase == 1 {
1001 self.list = self.map.convert_to_vec();
1002
1003 self.upd.write_u64(0, 0);
1006 self.upd.write_u64(8, size);
1007 self.upd.commit(16); let mut stg_written = false;
1011 let mut pos: u64 = 16;
1012 for (start, v) in self.list.iter() {
1013 let (start, len, data) = (*start, v.len as u64, v.all());
1014 if start >= self.size {
1015 stg_written = true;
1017 self.stg.write(start, data);
1018 } else {
1019 self.upd.write_u64(pos, start);
1020 pos += 8;
1021 self.upd.write_u64(pos, len);
1022 pos += 8;
1023 self.upd.write(pos, data);
1024 pos += len;
1025 }
1026 }
1027 if stg_written {
1028 self.stg.commit(size);
1029 }
1030 self.upd.commit(pos); self.upd.write_u64(0, pos);
1034 self.upd.write_u64(8, size);
1035 self.upd.commit(pos);
1036 } else {
1037 for (start, v) in self.list.iter() {
1038 if *start < self.size {
1039 self.stg.write(*start, v.all());
1041 }
1042 }
1043 self.list = GVec::new();
1044 self.stg.commit(size);
1045 self.upd.commit(0);
1046 }
1047 }
1048}
1049
1050impl BasicStorage for BasicAtomicFile {
1051 fn commit(&mut self, size: u64) {
1052 if self.stop { return; }
1053 self.commit_phase(size, 1);
1054 self.commit_phase(size, 2);
1055 self.size = size;
1056 }
1057
1058 fn size(&self) -> u64 {
1059 self.size
1060 }
1061
1062 fn read(&self, start: u64, data: &mut [u8]) {
1063 self.map.read(start, data, &*self.stg.stg);
1064 }
1065
1066 fn write_data(&mut self, start: u64, data: Data, off: usize, len: usize) {
1067 self.map.write(start, data, off, len);
1068 }
1069
1070 fn write(&mut self, start: u64, data: &[u8]) {
1071 let len = data.len();
1072 let d = Arc::new(data.to_vec());
1073 self.write_data(start, d, 0, len);
1074 }
1075
1076 fn shutdown(&mut self)
1077 {
1078 self.stop = true;
1079 }
1080}
1081
1082#[cfg(target_family = "unix")]
1084pub struct UnixFileStorage {
1085 size: Arc<Mutex<u64>>,
1086 f: fs::File,
1087}
1088#[cfg(target_family = "unix")]
1089impl UnixFileStorage {
1090 pub fn new(filename: &str) -> Box<Self> {
1092 let mut f = OpenOptions::new()
1093 .read(true)
1094 .write(true)
1095 .create(true)
1096 .truncate(false)
1097 .open(filename)
1098 .unwrap();
1099 let size = f.seek(SeekFrom::End(0)).unwrap();
1100 let size = Arc::new(Mutex::new(size));
1101 Box::new(Self { size, f })
1102 }
1103}
1104
1105#[cfg(target_family = "unix")]
1106impl Storage for UnixFileStorage {
1107 fn clone(&self) -> Box<dyn Storage> {
1108 Box::new(Self {
1109 size: self.size.clone(),
1110 f: self.f.try_clone().unwrap(),
1111 })
1112 }
1113}
1114
1115#[cfg(target_family = "unix")]
1116use std::os::unix::fs::FileExt;
1117
1118#[cfg(target_family = "unix")]
1119impl BasicStorage for UnixFileStorage {
1120 fn read(&self, start: u64, data: &mut [u8]) {
1121 let _ = self.f.read_at(data, start);
1122 }
1123
1124 fn write(&mut self, start: u64, data: &[u8]) {
1125 let _ = self.f.write_at(data, start);
1126 }
1127
1128 fn size(&self) -> u64 {
1129 *self.size.lock().unwrap()
1130 }
1131
1132 fn commit(&mut self, size: u64) {
1133 *self.size.lock().unwrap() = size;
1134 self.f.set_len(size).unwrap();
1135 self.f.sync_all().unwrap();
1136 }
1137}
1138
1139#[cfg(target_family = "windows")]
1141pub struct WindowsFileStorage {
1142 size: Arc<Mutex<u64>>,
1143 f: fs::File,
1144}
1145#[cfg(target_family = "windows")]
1146impl WindowsFileStorage {
1147 pub fn new(filename: &str) -> Box<Self> {
1149 let mut f = OpenOptions::new()
1150 .read(true)
1151 .write(true)
1152 .create(true)
1153 .truncate(false)
1154 .open(filename)
1155 .unwrap();
1156 let size = f.seek(SeekFrom::End(0)).unwrap();
1157 let size = Arc::new(Mutex::new(size));
1158 Box::new(Self { size, f })
1159 }
1160}
1161
1162#[cfg(target_family = "windows")]
1163impl Storage for WindowsFileStorage {
1164 fn clone(&self) -> Box<dyn Storage> {
1165 Box::new(Self {
1166 size: self.size.clone(),
1167 f: self.f.try_clone().unwrap(),
1168 })
1169 }
1170}
1171
1172#[cfg(target_family = "windows")]
1173use std::os::windows::fs::FileExt;
1174
1175#[cfg(target_family = "windows")]
1176impl BasicStorage for WindowsFileStorage {
1177 fn read(&self, start: u64, data: &mut [u8]) {
1178 let _ = self.f.seek_read(data, start);
1179 }
1180
1181 fn write(&mut self, start: u64, data: &[u8]) {
1182 let _ = self.f.seek_write(data, start);
1183 }
1184
1185 fn size(&self) -> u64 {
1186 *self.size.lock().unwrap()
1187 }
1188
1189 fn commit(&mut self, size: u64) {
1190 *self.size.lock().unwrap() = size;
1191 self.f.set_len(size).unwrap();
1192 self.f.sync_all().unwrap();
1193 }
1194}
1195
1196#[cfg(target_family = "windows")]
1198pub type MultiFileStorage = WindowsFileStorage;
1199
1200#[cfg(target_family = "unix")]
1202pub type MultiFileStorage = UnixFileStorage;
1203
1204#[cfg(not(any(target_family = "unix", target_family = "windows")))]
1206pub type MultiFileStorage = AnyFileStorage;
1207
1208#[cfg(any(target_family = "windows", target_family = "unix"))]
1210pub type FastFileStorage = MultiFileStorage;
1211
1212#[cfg(not(any(target_family = "windows", target_family = "unix")))]
1214pub type FastFileStorage = UpdFileStorage;
1215
1216#[cfg(test)]
1217fn test_amount() -> usize {
1219 str::parse(&std::env::var("TA").unwrap_or("1".to_string())).unwrap()
1220}
1221
1222#[test]
1223fn test_atomic_file() {
1224 use rand::Rng;
1225 let ta = test_amount();
1228 println!(" Test amount={}", ta);
1229
1230 let mut rng = rand::thread_rng();
1231
1232 for _ in 0..100 {
1233 let mut s1 = AtomicFile::new(MemFile::new(), MemFile::new());
1234 let mut s2 = MemFile::new();
1236
1237 for _ in 0..1000 * ta {
1238 let off: usize = rng.r#gen::<usize>() % 100;
1239 let mut len = 1 + rng.r#gen::<usize>() % 20;
1240 let w: bool = rng.r#gen();
1241 if w {
1242 let mut bytes = Vec::new();
1243 while len > 0 {
1244 len -= 1;
1245 let b: u8 = rng.r#gen::<u8>();
1246 bytes.push(b);
1247 }
1248 s1.write(off as u64, &bytes);
1249 s2.write(off as u64, &bytes);
1250 } else {
1251 let mut b2 = vec![0; len];
1252 let mut b3 = vec![0; len];
1253 s1.read(off as u64, &mut b2);
1254 s2.read(off as u64, &mut b3);
1255 assert!(b2 == b3);
1256 }
1257 if rng.r#gen::<usize>() % 50 == 0 {
1258 s1.commit(200);
1259 s2.commit(200);
1260 }
1261 }
1262 }
1263}