1pub mod drivers;
7pub mod ext;
8
9use crate::io_buffers::{IoVector, IoVectorMut};
10use drivers::CommonStorageHelper;
11use std::any::Any;
12use std::fmt::{Debug, Display};
13use std::future::Future;
14use std::io;
15use std::path::{Path, PathBuf};
16use std::pin::Pin;
17use std::sync::Arc;
18
19#[derive(Clone, Debug, Default)]
21pub struct StorageOpenOptions {
22 pub(crate) filename: Option<PathBuf>,
24
25 pub(crate) writable: bool,
27
28 pub(crate) direct: bool,
30
31 #[cfg(target_os = "macos")]
33 pub(crate) relaxed_sync: bool,
34}
35
36#[derive(Clone, Debug)]
38pub struct StorageCreateOptions {
39 pub(crate) open_opts: StorageOpenOptions,
43
44 pub(crate) size: u64,
46
47 pub(crate) prealloc_mode: PreallocateMode,
49
50 pub(crate) overwrite: bool,
52}
53
54pub trait Storage: Debug + Display + Send + Sized + Sync {
56 #[allow(async_fn_in_trait)] async fn open(_opts: StorageOpenOptions) -> io::Result<Self> {
61 Err(io::Error::new(
62 io::ErrorKind::Unsupported,
63 format!(
64 "Cannot open storage objects of type {}",
65 std::any::type_name::<Self>()
66 ),
67 ))
68 }
69
70 #[cfg(feature = "sync-wrappers")]
72 fn open_sync(opts: StorageOpenOptions) -> io::Result<Self> {
73 tokio::runtime::Builder::new_current_thread()
74 .build()?
75 .block_on(Self::open(opts))
76 }
77
78 #[allow(async_fn_in_trait)] async fn create_open(_opts: StorageCreateOptions) -> io::Result<Self> {
85 Err(io::Error::new(
86 io::ErrorKind::Unsupported,
87 format!(
88 "Cannot create storage objects of type {}",
89 std::any::type_name::<Self>()
90 ),
91 ))
92 }
93
94 #[allow(async_fn_in_trait)] async fn create(opts: StorageCreateOptions) -> io::Result<()> {
99 Self::create_open(opts).await?;
100 Ok(())
101 }
102
103 fn mem_align(&self) -> usize {
105 1
106 }
107
108 fn req_align(&self) -> usize {
110 1
111 }
112
113 fn zero_align(&self) -> usize {
115 1
116 }
117
118 fn discard_align(&self) -> usize {
120 1
121 }
122
123 fn size(&self) -> io::Result<u64>;
125
126 fn resolve_relative_path<P: AsRef<Path>>(&self, _relative: P) -> io::Result<PathBuf> {
136 Err(io::ErrorKind::Unsupported.into())
137 }
138
139 fn get_filename(&self) -> Option<PathBuf> {
144 None
145 }
146
147 #[allow(async_fn_in_trait)] async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()>;
160
161 #[allow(async_fn_in_trait)] async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()>;
177
178 #[allow(async_fn_in_trait)] async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
191 ext::write_full_zeroes(self, offset, length).await
192 }
193
194 #[allow(async_fn_in_trait)] async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
208 ext::write_full_zeroes(self, offset, length).await
209 }
210
211 #[allow(async_fn_in_trait)] async unsafe fn pure_discard(&self, _offset: u64, _length: u64) -> io::Result<()> {
226 Ok(())
227 }
228
229 #[allow(async_fn_in_trait)] async fn flush(&self) -> io::Result<()>;
238
239 #[allow(async_fn_in_trait)] async fn sync(&self) -> io::Result<()>;
245
246 #[allow(async_fn_in_trait)] async unsafe fn invalidate_cache(&self) -> io::Result<()>;
256
257 fn get_storage_helper(&self) -> &CommonStorageHelper;
260
261 #[allow(async_fn_in_trait)] async fn resize(&self, _new_size: u64, _prealloc_mode: PreallocateMode) -> io::Result<()> {
271 Err(io::ErrorKind::Unsupported.into())
272 }
273}
274
275pub trait DynStorage: Any + Debug + Display + Send + Sync {
289 fn dyn_mem_align(&self) -> usize;
291
292 fn dyn_req_align(&self) -> usize;
294
295 fn dyn_zero_align(&self) -> usize;
297
298 fn dyn_discard_align(&self) -> usize;
300
301 fn dyn_size(&self) -> io::Result<u64>;
303
304 fn dyn_resolve_relative_path(&self, relative: &Path) -> io::Result<PathBuf>;
306
307 fn dyn_get_filename(&self) -> Option<PathBuf>;
309
310 unsafe fn dyn_pure_readv<'a>(
315 &'a self,
316 bufv: IoVectorMut<'a>,
317 offset: u64,
318 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>>;
319
320 unsafe fn dyn_pure_writev<'a>(
325 &'a self,
326 bufv: IoVector<'a>,
327 offset: u64,
328 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>>;
329
330 unsafe fn dyn_pure_write_zeroes(
335 &self,
336 offset: u64,
337 length: u64,
338 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
339
340 unsafe fn dyn_pure_write_allocated_zeroes(
345 &self,
346 offset: u64,
347 length: u64,
348 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
349
350 unsafe fn dyn_pure_discard(
355 &self,
356 offset: u64,
357 length: u64,
358 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
359
360 fn dyn_flush(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
362
363 fn dyn_sync(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
365
366 unsafe fn dyn_invalidate_cache(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
371
372 fn dyn_get_storage_helper(&self) -> &CommonStorageHelper;
374
375 fn dyn_resize(
377 &self,
378 new_size: u64,
379 prealloc_mode: PreallocateMode,
380 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
381}
382
383#[derive(Clone, Copy, Debug, Eq, PartialEq)]
388#[non_exhaustive]
389pub enum PreallocateMode {
390 None,
394
395 Zero,
400
401 Allocate,
405
406 WriteData,
410}
411
412impl<S: Storage> Storage for &S {
413 fn mem_align(&self) -> usize {
414 (*self).mem_align()
415 }
416
417 fn req_align(&self) -> usize {
418 (*self).req_align()
419 }
420
421 fn zero_align(&self) -> usize {
422 (*self).zero_align()
423 }
424
425 fn discard_align(&self) -> usize {
426 (*self).discard_align()
427 }
428
429 fn size(&self) -> io::Result<u64> {
430 (*self).size()
431 }
432
433 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
434 (*self).resolve_relative_path(relative)
435 }
436
437 fn get_filename(&self) -> Option<PathBuf> {
438 (*self).get_filename()
439 }
440
441 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
442 unsafe { (*self).pure_readv(bufv, offset).await }
443 }
444
445 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
446 unsafe { (*self).pure_writev(bufv, offset).await }
447 }
448
449 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
450 unsafe { (*self).pure_write_zeroes(offset, length).await }
451 }
452
453 async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
454 unsafe { (*self).pure_write_allocated_zeroes(offset, length).await }
455 }
456
457 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
458 unsafe { (*self).pure_discard(offset, length).await }
459 }
460
461 async fn flush(&self) -> io::Result<()> {
462 (*self).flush().await
463 }
464
465 async fn sync(&self) -> io::Result<()> {
466 (*self).sync().await
467 }
468
469 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
470 unsafe { (*self).invalidate_cache().await }
471 }
472
473 fn get_storage_helper(&self) -> &CommonStorageHelper {
474 (*self).get_storage_helper()
475 }
476
477 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
478 (*self).resize(new_size, prealloc_mode).await
479 }
480}
481
482impl<S: Storage + 'static> DynStorage for S {
483 fn dyn_mem_align(&self) -> usize {
484 <S as Storage>::mem_align(self)
485 }
486
487 fn dyn_req_align(&self) -> usize {
488 <S as Storage>::req_align(self)
489 }
490
491 fn dyn_zero_align(&self) -> usize {
492 <S as Storage>::zero_align(self)
493 }
494
495 fn dyn_discard_align(&self) -> usize {
496 <S as Storage>::discard_align(self)
497 }
498
499 fn dyn_size(&self) -> io::Result<u64> {
500 <S as Storage>::size(self)
501 }
502
503 fn dyn_resolve_relative_path(&self, relative: &Path) -> io::Result<PathBuf> {
504 <S as Storage>::resolve_relative_path(self, relative)
505 }
506
507 fn dyn_get_filename(&self) -> Option<PathBuf> {
508 <S as Storage>::get_filename(self)
509 }
510
511 unsafe fn dyn_pure_readv<'a>(
512 &'a self,
513 bufv: IoVectorMut<'a>,
514 offset: u64,
515 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
516 Box::pin(unsafe { <S as Storage>::pure_readv(self, bufv, offset) })
517 }
518
519 unsafe fn dyn_pure_writev<'a>(
520 &'a self,
521 bufv: IoVector<'a>,
522 offset: u64,
523 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
524 Box::pin(unsafe { <S as Storage>::pure_writev(self, bufv, offset) })
525 }
526
527 unsafe fn dyn_pure_write_zeroes(
528 &self,
529 offset: u64,
530 length: u64,
531 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
532 Box::pin(unsafe { <S as Storage>::pure_write_zeroes(self, offset, length) })
533 }
534
535 unsafe fn dyn_pure_write_allocated_zeroes(
536 &self,
537 offset: u64,
538 length: u64,
539 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
540 Box::pin(unsafe { <S as Storage>::pure_write_allocated_zeroes(self, offset, length) })
541 }
542
543 unsafe fn dyn_pure_discard(
544 &self,
545 offset: u64,
546 length: u64,
547 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
548 Box::pin(unsafe { <S as Storage>::pure_discard(self, offset, length) })
549 }
550
551 fn dyn_flush(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
552 Box::pin(<S as Storage>::flush(self))
553 }
554
555 fn dyn_sync(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
556 Box::pin(<S as Storage>::sync(self))
557 }
558
559 unsafe fn dyn_invalidate_cache(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
560 Box::pin(unsafe { <S as Storage>::invalidate_cache(self) })
561 }
562
563 fn dyn_get_storage_helper(&self) -> &CommonStorageHelper {
564 <S as Storage>::get_storage_helper(self)
565 }
566
567 fn dyn_resize(
568 &self,
569 new_size: u64,
570 prealloc_mode: PreallocateMode,
571 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
572 Box::pin(<S as Storage>::resize(self, new_size, prealloc_mode))
573 }
574}
575
576impl Storage for Box<dyn DynStorage> {
577 async fn open(opts: StorageOpenOptions) -> io::Result<Self> {
578 Ok(Box::new(crate::file::File::open(opts).await?))
582 }
583
584 async fn create_open(opts: StorageCreateOptions) -> io::Result<Self> {
585 Ok(Box::new(crate::file::File::create_open(opts).await?))
587 }
588
589 fn mem_align(&self) -> usize {
590 self.as_ref().dyn_mem_align()
591 }
592
593 fn req_align(&self) -> usize {
594 self.as_ref().dyn_req_align()
595 }
596
597 fn zero_align(&self) -> usize {
598 self.as_ref().dyn_zero_align()
599 }
600
601 fn discard_align(&self) -> usize {
602 self.as_ref().dyn_discard_align()
603 }
604
605 fn size(&self) -> io::Result<u64> {
606 self.as_ref().dyn_size()
607 }
608
609 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
610 self.as_ref().dyn_resolve_relative_path(relative.as_ref())
611 }
612
613 fn get_filename(&self) -> Option<PathBuf> {
614 self.as_ref().dyn_get_filename()
615 }
616
617 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
618 unsafe { self.as_ref().dyn_pure_readv(bufv, offset).await }
619 }
620
621 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
622 unsafe { self.as_ref().dyn_pure_writev(bufv, offset).await }
623 }
624
625 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
626 unsafe { self.as_ref().dyn_pure_write_zeroes(offset, length).await }
627 }
628
629 async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
630 unsafe {
631 self.as_ref()
632 .dyn_pure_write_allocated_zeroes(offset, length)
633 .await
634 }
635 }
636
637 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
638 unsafe { self.as_ref().dyn_pure_discard(offset, length).await }
639 }
640
641 async fn flush(&self) -> io::Result<()> {
642 self.as_ref().dyn_flush().await
643 }
644
645 async fn sync(&self) -> io::Result<()> {
646 self.as_ref().dyn_sync().await
647 }
648
649 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
650 unsafe { self.as_ref().dyn_invalidate_cache().await }
651 }
652
653 fn get_storage_helper(&self) -> &CommonStorageHelper {
654 self.as_ref().dyn_get_storage_helper()
655 }
656
657 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
658 self.as_ref().dyn_resize(new_size, prealloc_mode).await
659 }
660}
661
662impl Storage for Arc<dyn DynStorage> {
663 async fn open(opts: StorageOpenOptions) -> io::Result<Self> {
664 Box::<dyn DynStorage>::open(opts).await.map(Into::into)
665 }
666
667 async fn create_open(opts: StorageCreateOptions) -> io::Result<Self> {
668 Box::<dyn DynStorage>::create_open(opts)
669 .await
670 .map(Into::into)
671 }
672
673 fn mem_align(&self) -> usize {
674 self.as_ref().dyn_mem_align()
675 }
676
677 fn req_align(&self) -> usize {
678 self.as_ref().dyn_req_align()
679 }
680
681 fn zero_align(&self) -> usize {
682 self.as_ref().dyn_zero_align()
683 }
684
685 fn discard_align(&self) -> usize {
686 self.as_ref().dyn_discard_align()
687 }
688
689 fn size(&self) -> io::Result<u64> {
690 self.as_ref().dyn_size()
691 }
692
693 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
694 self.as_ref().dyn_resolve_relative_path(relative.as_ref())
695 }
696
697 fn get_filename(&self) -> Option<PathBuf> {
698 self.as_ref().dyn_get_filename()
699 }
700
701 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
702 unsafe { self.as_ref().dyn_pure_readv(bufv, offset) }.await
703 }
704
705 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
706 unsafe { self.as_ref().dyn_pure_writev(bufv, offset) }.await
707 }
708
709 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
710 unsafe { self.as_ref().dyn_pure_write_zeroes(offset, length) }.await
711 }
712
713 async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
714 unsafe {
715 self.as_ref()
716 .dyn_pure_write_allocated_zeroes(offset, length)
717 }
718 .await
719 }
720
721 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
722 unsafe { self.as_ref().dyn_pure_discard(offset, length) }.await
723 }
724
725 async fn flush(&self) -> io::Result<()> {
726 self.as_ref().dyn_flush().await
727 }
728
729 async fn sync(&self) -> io::Result<()> {
730 self.as_ref().dyn_sync().await
731 }
732
733 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
734 unsafe { self.as_ref().dyn_invalidate_cache().await }
735 }
736
737 fn get_storage_helper(&self) -> &CommonStorageHelper {
738 self.as_ref().dyn_get_storage_helper()
739 }
740
741 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
742 self.as_ref().dyn_resize(new_size, prealloc_mode).await
743 }
744}
745
746impl StorageOpenOptions {
747 pub fn new() -> Self {
749 StorageOpenOptions::default()
750 }
751
752 pub fn filename<P: AsRef<Path>>(mut self, filename: P) -> Self {
754 self.filename = Some(filename.as_ref().to_owned());
755 self
756 }
757
758 pub fn write(mut self, write: bool) -> Self {
760 self.writable = write;
761 self
762 }
763
764 pub fn direct(mut self, direct: bool) -> Self {
766 self.direct = direct;
767 self
768 }
769
770 #[cfg(target_os = "macos")]
777 pub fn relaxed_sync(mut self, relaxed_sync: bool) -> Self {
778 self.relaxed_sync = relaxed_sync;
779 self
780 }
781
782 pub fn get_filename(&self) -> Option<&Path> {
784 self.filename.as_deref()
785 }
786
787 pub fn get_writable(&self) -> bool {
789 self.writable
790 }
791
792 pub fn get_direct(&self) -> bool {
794 self.direct
795 }
796
797 #[cfg(target_os = "macos")]
799 pub fn get_relaxed_sync(&self) -> bool {
800 self.relaxed_sync
801 }
802}
803
804impl StorageCreateOptions {
805 pub fn new() -> Self {
807 StorageCreateOptions::default()
808 }
809
810 pub fn filename<P: AsRef<Path>>(self, filename: P) -> Self {
812 self.modify_open_opts(|o| o.filename(filename))
813 }
814
815 pub fn size(mut self, size: u64) -> Self {
817 self.size = size;
818 self
819 }
820
821 pub fn preallocate(mut self, prealloc_mode: PreallocateMode) -> Self {
823 self.prealloc_mode = prealloc_mode;
824 self
825 }
826
827 pub fn overwrite(mut self, overwrite: bool) -> Self {
829 self.overwrite = overwrite;
830 self
831 }
832
833 pub fn modify_open_opts<F: FnOnce(StorageOpenOptions) -> StorageOpenOptions>(
835 mut self,
836 f: F,
837 ) -> Self {
838 self.open_opts = f(self.open_opts);
839 self
840 }
841
842 pub fn get_filename(&self) -> Option<&Path> {
844 self.open_opts.filename.as_deref()
845 }
846
847 pub fn get_size(&self) -> u64 {
849 self.size
850 }
851
852 pub fn get_preallocate(&self) -> PreallocateMode {
854 self.prealloc_mode
855 }
856
857 pub fn get_overwrite(&self) -> bool {
859 self.overwrite
860 }
861
862 pub fn get_open_options(self) -> StorageOpenOptions {
864 self.open_opts
865 }
866}
867
868impl Default for StorageCreateOptions {
869 fn default() -> Self {
870 StorageCreateOptions {
871 open_opts: Default::default(),
872 size: 0,
873 prealloc_mode: PreallocateMode::None,
874 overwrite: false,
875 }
876 }
877}