From a4fd2c973ee889f246c58927cadc06328b19ecff Mon Sep 17 00:00:00 2001 From: Lachlan Deakin Date: Sat, 10 Aug 2024 08:45:43 +1000 Subject: [PATCH 1/2] Add `Variable::chunking` --- netcdf/src/variable.rs | 29 +++++++++++++++++++++++++++++ netcdf/tests/group.rs | 3 +++ netcdf/tests/lib.rs | 6 ++++++ 3 files changed, 38 insertions(+) diff --git a/netcdf/src/variable.rs b/netcdf/src/variable.rs index d20cabc..40298e0 100644 --- a/netcdf/src/variable.rs +++ b/netcdf/src/variable.rs @@ -206,6 +206,35 @@ impl<'g> Variable<'g> { pub fn access_collective(&self) -> error::Result<()> { self.access_mode(crate::par::AccessMode::Collective) } + + /// Get the chunking for the variable. + /// Returns None for a contiguous variable. + /// + /// # Errors + /// + /// Not a `netCDF-4` file. + pub fn chunking(&self) -> error::Result>> { + if self.dimensions.is_empty() { + return Ok(None); + } + let mut storage = std::mem::MaybeUninit::::uninit(); + let mut chunk_size = Vec::with_capacity(self.dimensions.len()); + checked_with_lock(|| unsafe { + nc_inq_var_chunking( + self.ncid, + self.varid, + storage.as_mut_ptr(), + chunk_size.spare_capacity_mut().as_mut_ptr().cast(), + ) + })?; + let storage = unsafe { storage.assume_init() }; + if storage == NC_CHUNKED { + unsafe { chunk_size.set_len(self.dimensions.len()) }; + Ok(Some(chunk_size)) + } else { + Ok(None) + } + } } impl<'g> VariableMut<'g> { /// Sets compression on the variable. Must be set before filling in data. diff --git a/netcdf/tests/group.rs b/netcdf/tests/group.rs index 6d60de2..88d64fc 100644 --- a/netcdf/tests/group.rs +++ b/netcdf/tests/group.rs @@ -66,13 +66,16 @@ fn find_variable() { assert!(group.variable("vvvvv").is_none()); for mut var in group.variables_mut() { + assert_eq!(var.chunking().unwrap(), None); if !var.dimensions().is_empty() { var.set_compression(3, false).unwrap(); } if var.name() == "z" { var.set_chunking(&[1]).unwrap(); + assert_eq!(var.chunking().unwrap(), Some(vec![1])); } else { var.set_chunking(&[]).unwrap(); + assert_eq!(var.chunking().unwrap(), None); } } } diff --git a/netcdf/tests/lib.rs b/netcdf/tests/lib.rs index 6a71ccc..c1bb5a5 100644 --- a/netcdf/tests/lib.rs +++ b/netcdf/tests/lib.rs @@ -843,8 +843,10 @@ fn use_compression_chunking() { file.add_dimension("x", 10).unwrap(); let var = &mut file.add_variable::("compressed", &["x"]).unwrap(); + assert_eq!(var.chunking().unwrap(), None); var.set_compression(5, false).unwrap(); var.set_chunking(&[5]).unwrap(); + assert_eq!(var.chunking().unwrap(), Some(vec![5])); let v = vec![0i32; 10]; var.put_values(&v, ..).unwrap(); @@ -852,8 +854,10 @@ fn use_compression_chunking() { let var = &mut file .add_variable::("compressed2", &["x", "x"]) .unwrap(); + assert_eq!(var.chunking().unwrap(), None); var.set_compression(9, true).unwrap(); var.set_chunking(&[5, 5]).unwrap(); + assert_eq!(var.chunking().unwrap(), Some(vec![5, 5])); var.put_values(&[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10], (..10, ..1)) .unwrap(); @@ -866,7 +870,9 @@ fn use_compression_chunking() { file.add_dimension("y", 0).unwrap(); let var = &mut file.add_variable::("chunked4", &["y", "x"]).unwrap(); + assert_eq!(var.chunking().unwrap(), Some(vec![1, 10])); // unlimited dim enables chunking var.set_chunking(&[100, 2]).unwrap(); + assert_eq!(var.chunking().unwrap(), Some(vec![100, 2])); } #[test] From 0c015abe0c3cf963e0b963198c3b2226dac17243 Mon Sep 17 00:00:00 2001 From: Magnus Ulimoen Date: Sat, 10 Aug 2024 07:47:41 +0200 Subject: [PATCH 2/2] Avoid MaybeUninit --- netcdf/src/variable.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/netcdf/src/variable.rs b/netcdf/src/variable.rs index 40298e0..7f794a5 100644 --- a/netcdf/src/variable.rs +++ b/netcdf/src/variable.rs @@ -217,19 +217,12 @@ impl<'g> Variable<'g> { if self.dimensions.is_empty() { return Ok(None); } - let mut storage = std::mem::MaybeUninit::::uninit(); - let mut chunk_size = Vec::with_capacity(self.dimensions.len()); + let mut storage = 0; + let mut chunk_size = vec![0; self.dimensions.len()]; checked_with_lock(|| unsafe { - nc_inq_var_chunking( - self.ncid, - self.varid, - storage.as_mut_ptr(), - chunk_size.spare_capacity_mut().as_mut_ptr().cast(), - ) + nc_inq_var_chunking(self.ncid, self.varid, &mut storage, chunk_size.as_mut_ptr()) })?; - let storage = unsafe { storage.assume_init() }; if storage == NC_CHUNKED { - unsafe { chunk_size.set_len(self.dimensions.len()) }; Ok(Some(chunk_size)) } else { Ok(None)