use std::path::Path;
use crate::format::messages::datatype::DatatypeMessage;
use crate::format::superblock::{FLAG_SWMR_WRITE, FLAG_WRITE_ACCESS};
use crate::io::writer::Hdf5Writer;
use crate::io::IoResult;
pub struct SwmrWriter {
writer: Hdf5Writer,
swmr_active: bool,
}
impl SwmrWriter {
pub fn create(path: &Path) -> IoResult<Self> {
let writer = Hdf5Writer::create(path)?;
Ok(Self {
writer,
swmr_active: false,
})
}
pub fn create_streaming_dataset(
&mut self,
name: &str,
datatype: DatatypeMessage,
frame_dims: &[u64],
) -> IoResult<usize> {
let mut dims = vec![0u64];
dims.extend_from_slice(frame_dims);
let mut max_dims = vec![u64::MAX];
max_dims.extend_from_slice(frame_dims);
let mut chunk_dims = vec![1u64];
chunk_dims.extend_from_slice(frame_dims);
self.writer
.create_chunked_dataset(name, datatype, &dims, &max_dims, &chunk_dims)
}
pub fn start_swmr(&mut self) -> IoResult<()> {
self.writer.finalize_for_swmr()?;
self.swmr_active = true;
Ok(())
}
pub fn append_frame(&mut self, ds_index: usize, data: &[u8]) -> IoResult<()> {
let frame_idx = { self.writer.datasets[ds_index].dataspace.dims[0] };
self.writer.write_chunk(ds_index, frame_idx, data)?;
let mut new_dims = self.writer.datasets[ds_index].dataspace.dims.clone();
new_dims[0] = frame_idx + 1;
self.writer.extend_dataset(ds_index, &new_dims)?;
Ok(())
}
pub fn flush(&mut self) -> IoResult<()> {
for i in 0..self.writer.datasets.len() {
if self.writer.datasets[i].chunked.is_some() {
self.writer.flush_dataset(i)?;
}
}
self.writer.handle().sync_data()?;
if self.swmr_active {
for i in 0..self.writer.datasets.len() {
if self.writer.datasets[i].obj_header_written_addr.is_some() {
self.writer.write_dataset_header_inplace(i)?;
}
}
self.writer.handle().sync_data()?;
self.writer
.write_superblock(FLAG_WRITE_ACCESS | FLAG_SWMR_WRITE)?;
self.writer.handle().sync_data()?;
}
Ok(())
}
pub fn writer_mut(&mut self) -> &mut Hdf5Writer {
&mut self.writer
}
pub fn close(self) -> IoResult<()> {
self.writer.close()
}
}