Struct glommio::io::DmaStreamWriter
source · pub struct DmaStreamWriter { /* private fields */ }
Expand description
Provides linear access to a DmaFile
. The DmaFile
is a convenient way
to manage a file through Direct I/O, but its interface is conductive to
random access, as a position must always be specified.
Very rarely does one need to issue random writes to a file. Therefore, the
DmaStreamWriter
is likely your go-to API when it comes to writing files.
The DmaStreamWriter
implements AsyncWrite
. Because it is backed by a
Direct I/O file, the flush method has no effect. Closing the file issues a
sync so that the data can be flushed from the internal NVMe caches.
Implementations§
source§impl DmaStreamWriter
impl DmaStreamWriter
sourcepub fn current_pos(&self) -> u64
pub fn current_pos(&self) -> u64
Acquires the current position of this DmaStreamWriter
.
§Examples
use futures::io::AsyncWriteExt;
use glommio::{
io::{DmaFile, DmaStreamWriterBuilder},
LocalExecutor,
};
let ex = LocalExecutor::default();
ex.run(async {
let file = DmaFile::create("myfile.txt").await.unwrap();
let mut writer = DmaStreamWriterBuilder::new(file).build();
assert_eq!(writer.current_pos(), 0);
writer.write_all(&[0, 1, 2, 3, 4]).await.unwrap();
assert_eq!(writer.current_pos(), 5);
writer.close().await.unwrap();
});
sourcepub fn current_flushed_pos(&self) -> u64
pub fn current_flushed_pos(&self) -> u64
Acquires the current position of this DmaStreamWriter
that is
flushed to the underlying media.
Warning: the position reported by this API is not restart or crash safe.
You need to call sync
for that. Although the DmaStreamWriter
uses Direct I/O, modern storage devices have their own caches and
may still lose data that sits on those caches upon a restart until
sync
is called (Note that close
implies a sync).
However within the same session, new readers trying to read from any position before what we return in this method will be guaranteed to read the data we just wrote.
§Examples
use futures::io::AsyncWriteExt;
use glommio::{
io::{DmaFile, DmaStreamWriterBuilder},
LocalExecutor,
};
let ex = LocalExecutor::default();
ex.run(async {
let file = DmaFile::create("myfile.txt").await.unwrap();
let mut writer = DmaStreamWriterBuilder::new(file).build();
assert_eq!(writer.current_pos(), 0);
writer.write_all(&[0, 1, 2, 3, 4]).await.unwrap();
assert_eq!(writer.current_pos(), 5);
// The write above is not enough to cause a flush
assert_eq!(writer.current_flushed_pos(), 0);
writer.close().await.unwrap();
// Close implies a forced-flush and a sync.
assert_eq!(writer.current_flushed_pos(), 5);
});
sourcepub async fn flush_aligned(&self) -> Result<u64, ()>
pub async fn flush_aligned(&self) -> Result<u64, ()>
Waits for all currently in-flight buffers to be written to the underlying storage.
This does not include the current buffer if it is not full. If all data
must be flushed, use flush
.
Returns the flushed position of the file.
§Examples
use futures::io::AsyncWriteExt;
use glommio::{
io::{DmaFile, DmaStreamWriterBuilder},
LocalExecutor,
};
let ex = LocalExecutor::default();
ex.run(async {
let file = DmaFile::create("myfile.txt").await.unwrap();
let mut writer = DmaStreamWriterBuilder::new(file)
.with_buffer_size(4096)
.with_write_behind(2)
.build();
let buffer = [0u8; 5000];
writer.write_all(&buffer).await.unwrap();
// with 5000 bytes written into a 4096-byte buffer a flush
// has certainly started. But if very likely didn't finish right
// away.
assert_eq!(writer.current_flushed_pos(), 0);
assert_eq!(writer.flush_aligned().await.unwrap(), 4096);
writer.close().await.unwrap();
});
sourcepub async fn sync_aligned(&self) -> Result<u64, ()>
pub async fn sync_aligned(&self) -> Result<u64, ()>
Waits for all currently in-flight buffers to be written to the underlying storage, and ensures they are safely persisted.
This does not include the current buffer if it is not full. If all data
must be synced, use Self::sync
.
Returns the flushed position of the file at the time the sync started.
§Examples
use futures::io::AsyncWriteExt;
use glommio::{
io::{DmaFile, DmaStreamWriterBuilder},
LocalExecutor,
};
let ex = LocalExecutor::default();
ex.run(async {
let file = DmaFile::create("myfile.txt").await.unwrap();
let mut writer = DmaStreamWriterBuilder::new(file)
.with_buffer_size(4096)
.with_write_behind(2)
.build();
let buffer = [0u8; 5000];
writer.write_all(&buffer).await.unwrap();
// with 5000 bytes written into a 4096-byte buffer a flush
// has certainly started. But if very likely didn't finish right
// away.
assert_eq!(writer.current_flushed_pos(), 0);
assert_eq!(writer.sync_aligned().await.unwrap(), 4096);
writer.close().await.unwrap();
});
sourcepub async fn sync(&self) -> Result<u64, ()>
pub async fn sync(&self) -> Result<u64, ()>
Waits for all buffers to be written to the underlying storage, and ensures they are safely persisted.
This includes the current buffer even if it is not full, by padding it.
The padding will get over-written by future writes, or truncated upon
close
.
Returns the flushed position of the file at the time the sync started.
§Examples
use futures::io::AsyncWriteExt;
use glommio::{
io::{DmaFile, DmaStreamWriterBuilder},
LocalExecutor,
};
let ex = LocalExecutor::default();
ex.run(async {
let file = DmaFile::create("myfile.txt").await.unwrap();
let mut writer = DmaStreamWriterBuilder::new(file)
.with_buffer_size(4096)
.with_write_behind(2)
.build();
let buffer = [0u8; 5000];
writer.write_all(&buffer).await.unwrap();
// with 5000 bytes written into a 4096-byte buffer a flush
// has certainly started. But if very likely didn't finish right
// away.
assert_eq!(writer.current_flushed_pos(), 0);
assert_eq!(writer.sync().await.unwrap(), 5000);
writer.close().await.unwrap();
});
Trait Implementations§
source§impl<'a> AsyncWrite for &'a DmaStreamWriter
impl<'a> AsyncWrite for &'a DmaStreamWriter
source§fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize>>
fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8] ) -> Poll<Result<usize>>
buf
into the object. Read moresource§fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>
source§impl AsyncWrite for DmaStreamWriter
impl AsyncWrite for DmaStreamWriter
source§fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize>>
fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8] ) -> Poll<Result<usize>>
buf
into the object. Read moresource§fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>
source§impl Debug for DmaStreamWriter
impl Debug for DmaStreamWriter
Auto Trait Implementations§
impl !Freeze for DmaStreamWriter
impl !RefUnwindSafe for DmaStreamWriter
impl !Send for DmaStreamWriter
impl !Sync for DmaStreamWriter
impl Unpin for DmaStreamWriter
impl !UnwindSafe for DmaStreamWriter
Blanket Implementations§
source§impl<W> AsyncWriteExt for Wwhere
W: AsyncWrite + ?Sized,
impl<W> AsyncWriteExt for Wwhere
W: AsyncWrite + ?Sized,
source§fn write<'a>(&'a mut self, buf: &'a [u8]) -> WriteFuture<'a, Self>where
Self: Unpin,
fn write<'a>(&'a mut self, buf: &'a [u8]) -> WriteFuture<'a, Self>where
Self: Unpin,
source§fn write_vectored<'a>(
&'a mut self,
bufs: &'a [IoSlice<'a>]
) -> WriteVectoredFuture<'a, Self>where
Self: Unpin,
fn write_vectored<'a>(
&'a mut self,
bufs: &'a [IoSlice<'a>]
) -> WriteVectoredFuture<'a, Self>where
Self: Unpin,
source§fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAllFuture<'a, Self>where
Self: Unpin,
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAllFuture<'a, Self>where
Self: Unpin,
source§fn flush(&mut self) -> FlushFuture<'_, Self>where
Self: Unpin,
fn flush(&mut self) -> FlushFuture<'_, Self>where
Self: Unpin,
source§fn boxed_writer<'a>(self) -> Pin<Box<dyn AsyncWrite + Send + 'a>>
fn boxed_writer<'a>(self) -> Pin<Box<dyn AsyncWrite + Send + 'a>>
dyn AsyncWrite + Send + 'a
. Read more