diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ecf06a..793dc5d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + - **Breaking**: `Array` `retrieve_` methods now return `Vec`/`Vec` instead of `Box<[u8]>`/`Box<[T]>` + - This avoids potential internal reallocations + ## [0.10.0] - 2024-01-17 ### Changed diff --git a/src/array.rs b/src/array.rs index 7e2b7425..e1b28cb8 100644 --- a/src/array.rs +++ b/src/array.rs @@ -832,7 +832,6 @@ mod tests { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // 6 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // 7 ] - .into() ); } diff --git a/src/array/array_async_readable.rs b/src/array/array_async_readable.rs index a94a40cb..c3787c39 100644 --- a/src/array/array_async_readable.rs +++ b/src/array/array_async_readable.rs @@ -39,13 +39,11 @@ macro_rules! array_async_retrieve_elements { bytes.len() / core::mem::size_of::(), bytes.len(), ) - } - .into_boxed_slice()) + }) } else { let elements = safe_transmute::transmute_many_permissive::(&bytes) .map_err(TransmuteError::from)? - .to_vec() - .into_boxed_slice(); + .to_vec(); Ok(elements) } } @@ -66,7 +64,7 @@ macro_rules! array_async_retrieve_ndarray { let length = elements.len(); ndarray::ArrayD::::from_shape_vec( super::iter_u64_to_usize($shape.iter()), - elements.into_vec(), + elements, ) .map_err(|_| { ArrayError::CodecError(crate::array::codec::CodecError::UnexpectedChunkDecodedSize( @@ -104,10 +102,7 @@ impl Array { /// /// # Panics /// Panics if the number of elements in the chunk exceeds `usize::MAX`. - pub async fn async_retrieve_chunk( - &self, - chunk_indices: &[u64], - ) -> Result, ArrayError> { + pub async fn async_retrieve_chunk(&self, chunk_indices: &[u64]) -> Result, ArrayError> { let storage_handle = Arc::new(StorageHandle::new(&*self.storage)); let storage_transformer = self .storage_transformers() @@ -130,7 +125,7 @@ impl Array { let chunk_decoded_size = chunk_representation.num_elements_usize() * chunk_representation.data_type().size(); if chunk_decoded.len() == chunk_decoded_size { - Ok(chunk_decoded.into_boxed_slice()) + Ok(chunk_decoded) } else { Err(ArrayError::UnexpectedChunkDecodedSize( chunk_decoded.len(), @@ -139,9 +134,7 @@ impl Array { } } else { let fill_value = chunk_representation.fill_value().as_ne_bytes(); - Ok(fill_value - .repeat(chunk_representation.num_elements_usize()) - .into_boxed_slice()) + Ok(fill_value.repeat(chunk_representation.num_elements_usize())) } } @@ -157,7 +150,7 @@ impl Array { pub async fn async_retrieve_chunk_elements( &self, chunk_indices: &[u64], - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_async_retrieve_elements!(self, async_retrieve_chunk(chunk_indices)) } @@ -195,10 +188,7 @@ impl Array { /// /// # Panics /// Panics if the number of elements in the chunk exceeds `usize::MAX`. - pub async fn async_retrieve_chunks( - &self, - chunks: &ArraySubset, - ) -> Result, ArrayError> { + pub async fn async_retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { if chunks.dimensionality() != self.chunk_grid().dimensionality() { return Err(ArrayError::InvalidArraySubset( chunks.clone(), @@ -211,7 +201,7 @@ impl Array { // Retrieve chunk bytes let num_chunks = chunks.num_elements(); match num_chunks { - 0 => Ok(vec![].into_boxed_slice()), + 0 => Ok(vec![]), 1 => { let chunk_indices = chunks.start(); self.async_retrieve_chunk(chunk_indices).await @@ -242,7 +232,7 @@ impl Array { } #[allow(clippy::transmute_undefined_repr)] let output: Vec = unsafe { core::mem::transmute(output) }; - Ok(output.into_boxed_slice()) + Ok(output) } } } @@ -254,7 +244,7 @@ impl Array { pub async fn async_retrieve_chunks_elements( &self, chunks: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_async_retrieve_elements!(self, async_retrieve_chunks(chunks)) } @@ -337,7 +327,7 @@ impl Array { pub async fn async_retrieve_array_subset( &self, array_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if array_subset.dimensionality() != self.chunk_grid().dimensionality() { return Err(ArrayError::InvalidArraySubset( array_subset.clone(), @@ -357,7 +347,7 @@ impl Array { // Retrieve chunk bytes let num_chunks = chunks.num_elements(); match num_chunks { - 0 => Ok(vec![].into_boxed_slice()), + 0 => Ok(vec![]), 1 => { let chunk_indices = chunks.start(); let chunk_subset = self.chunk_subset(chunk_indices).unwrap(); @@ -384,7 +374,7 @@ impl Array { .await?; #[allow(clippy::transmute_undefined_repr)] let output: Vec = unsafe { core::mem::transmute(output) }; - Ok(output.into_boxed_slice()) + Ok(output) } } _ => { @@ -481,7 +471,7 @@ impl Array { } #[allow(clippy::transmute_undefined_repr)] let output: Vec = unsafe { core::mem::transmute(output) }; - Ok(output.into_boxed_slice()) + Ok(output) } } } @@ -498,7 +488,7 @@ impl Array { pub async fn async_retrieve_array_subset_elements( &self, array_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_async_retrieve_elements!(self, async_retrieve_array_subset(array_subset)) } @@ -539,7 +529,7 @@ impl Array { &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { let chunk_representation = self.chunk_array_representation(chunk_indices)?; if !chunk_subset.inbounds(chunk_representation.shape()) { return Err(ArrayError::InvalidArraySubset( @@ -567,7 +557,7 @@ impl Array { let total_size = decoded_bytes.iter().map(Vec::len).sum::(); let expected_size = chunk_subset.num_elements_usize() * self.data_type().size(); if total_size == chunk_subset.num_elements_usize() * self.data_type().size() { - Ok(decoded_bytes.concat().into_boxed_slice()) + Ok(decoded_bytes.concat()) } else { Err(ArrayError::UnexpectedChunkDecodedSize( total_size, @@ -588,7 +578,7 @@ impl Array { &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_async_retrieve_elements!( self, async_retrieve_chunk_subset(chunk_indices, chunk_subset) diff --git a/src/array/array_async_readable_writable.rs b/src/array/array_async_readable_writable.rs index d6b9f57b..f88d9d45 100644 --- a/src/array/array_async_readable_writable.rs +++ b/src/array/array_async_readable_writable.rs @@ -244,8 +244,7 @@ impl Array { } // Store the updated chunk - self.async_store_chunk(chunk_indices, chunk_bytes.into_vec()) - .await + self.async_store_chunk(chunk_indices, chunk_bytes).await } } else { Err(ArrayError::InvalidChunkGridIndicesError( diff --git a/src/array/array_sync_readable.rs b/src/array/array_sync_readable.rs index 716e8786..b73365c2 100644 --- a/src/array/array_sync_readable.rs +++ b/src/array/array_sync_readable.rs @@ -37,13 +37,11 @@ macro_rules! array_retrieve_elements { bytes.len() / core::mem::size_of::(), bytes.len(), ) - } - .into_boxed_slice()) + }) } else { let elements = safe_transmute::transmute_many_permissive::(&bytes) .map_err(TransmuteError::from)? - .to_vec() - .into_boxed_slice(); + .to_vec(); Ok(elements) } } @@ -63,7 +61,7 @@ macro_rules! array_retrieve_ndarray { let length = elements.len(); ndarray::ArrayD::::from_shape_vec( super::iter_u64_to_usize($shape.iter()), - elements.into_vec(), + elements, ) .map_err(|_| { ArrayError::CodecError(crate::array::codec::CodecError::UnexpectedChunkDecodedSize( @@ -100,7 +98,7 @@ impl Array { /// /// # Panics /// Panics if the number of elements in the chunk exceeds `usize::MAX`. - pub fn retrieve_chunk(&self, chunk_indices: &[u64]) -> Result, ArrayError> { + pub fn retrieve_chunk(&self, chunk_indices: &[u64]) -> Result, ArrayError> { let storage_handle = Arc::new(StorageHandle::new(&*self.storage)); let storage_transformer = self .storage_transformers() @@ -121,7 +119,7 @@ impl Array { let chunk_decoded_size = chunk_representation.num_elements_usize() * chunk_representation.data_type().size(); if chunk_decoded.len() == chunk_decoded_size { - Ok(chunk_decoded.into_boxed_slice()) + Ok(chunk_decoded) } else { Err(ArrayError::UnexpectedChunkDecodedSize( chunk_decoded.len(), @@ -130,9 +128,7 @@ impl Array { } } else { let fill_value = chunk_representation.fill_value().as_ne_bytes(); - Ok(fill_value - .repeat(chunk_representation.num_elements_usize()) - .into_boxed_slice()) + Ok(fill_value.repeat(chunk_representation.num_elements_usize())) } } @@ -148,7 +144,7 @@ impl Array { pub fn retrieve_chunk_elements( &self, chunk_indices: &[u64], - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_retrieve_elements!(self, retrieve_chunk(chunk_indices)) } @@ -190,7 +186,7 @@ impl Array { &self, chunks: &ArraySubset, parallel: bool, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if chunks.dimensionality() != self.chunk_grid().dimensionality() { return Err(ArrayError::InvalidArraySubset( chunks.clone(), @@ -203,7 +199,7 @@ impl Array { // Retrieve chunk bytes let num_chunks = chunks.num_elements(); match num_chunks { - 0 => Ok(vec![].into_boxed_slice()), + 0 => Ok(vec![]), 1 => { let chunk_indices = chunks.start(); self.retrieve_chunk(chunk_indices) @@ -253,20 +249,20 @@ impl Array { } #[allow(clippy::transmute_undefined_repr)] let output: Vec = unsafe { core::mem::transmute(output) }; - Ok(output.into_boxed_slice()) + Ok(output) } } } /// Serial version of [`Array::retrieve_chunks_opt`]. #[allow(clippy::missing_panics_doc, clippy::missing_errors_doc)] - pub fn retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { + pub fn retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { self.retrieve_chunks_opt(chunks, false) } /// Parallel version of [`Array::retrieve_chunks_opt`]. #[allow(clippy::missing_panics_doc, clippy::missing_errors_doc)] - pub fn par_retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { + pub fn par_retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { self.retrieve_chunks_opt(chunks, true) } @@ -281,7 +277,7 @@ impl Array { &self, chunks: &ArraySubset, parallel: bool, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_retrieve_elements!(self, retrieve_chunks_opt(chunks, parallel)) } @@ -290,7 +286,7 @@ impl Array { pub fn retrieve_chunks_elements( &self, chunks: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.retrieve_chunks_elements_opt(chunks, false) } @@ -299,7 +295,7 @@ impl Array { pub fn par_retrieve_chunks_elements( &self, chunks: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.retrieve_chunks_elements_opt(chunks, true) } @@ -406,7 +402,7 @@ impl Array { &self, array_subset: &ArraySubset, parallel: bool, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if array_subset.dimensionality() != self.chunk_grid().dimensionality() { return Err(ArrayError::InvalidArraySubset( array_subset.clone(), @@ -426,7 +422,7 @@ impl Array { // Retrieve chunk bytes let num_chunks = chunks.num_elements(); match num_chunks { - 0 => Ok(vec![].into_boxed_slice()), + 0 => Ok(vec![]), 1 => { let chunk_indices = chunks.start(); let chunk_subset = self.chunk_subset(chunk_indices).unwrap(); @@ -452,7 +448,7 @@ impl Array { )?; #[allow(clippy::transmute_undefined_repr)] let output: Vec = unsafe { core::mem::transmute(output) }; - Ok(output.into_boxed_slice()) + Ok(output) } } _ => { @@ -500,17 +496,14 @@ impl Array { } #[allow(clippy::transmute_undefined_repr)] let output: Vec = unsafe { core::mem::transmute(output) }; - Ok(output.into_boxed_slice()) + Ok(output) } } } /// Serial version of [`Array::retrieve_array_subset_opt`]. #[allow(clippy::missing_panics_doc, clippy::missing_errors_doc)] - pub fn retrieve_array_subset( - &self, - array_subset: &ArraySubset, - ) -> Result, ArrayError> { + pub fn retrieve_array_subset(&self, array_subset: &ArraySubset) -> Result, ArrayError> { self.retrieve_array_subset_opt(array_subset, false) } @@ -519,7 +512,7 @@ impl Array { pub fn par_retrieve_array_subset( &self, array_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.retrieve_array_subset_opt(array_subset, true) } @@ -536,7 +529,7 @@ impl Array { &self, array_subset: &ArraySubset, parallel: bool, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_retrieve_elements!(self, retrieve_array_subset_opt(array_subset, parallel)) } @@ -545,7 +538,7 @@ impl Array { pub fn retrieve_array_subset_elements( &self, array_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.retrieve_array_subset_elements_opt(array_subset, false) } @@ -554,7 +547,7 @@ impl Array { pub fn par_retrieve_array_subset_elements( &self, array_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.retrieve_array_subset_elements_opt(array_subset, true) } @@ -616,7 +609,7 @@ impl Array { &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { let chunk_representation = self.chunk_array_representation(chunk_indices)?; if !chunk_subset.inbounds(chunk_representation.shape()) { return Err(ArrayError::InvalidArraySubset( @@ -642,7 +635,7 @@ impl Array { let total_size = decoded_bytes.iter().map(Vec::len).sum::(); let expected_size = chunk_subset.num_elements_usize() * self.data_type().size(); if total_size == chunk_subset.num_elements_usize() * self.data_type().size() { - Ok(decoded_bytes.concat().into_boxed_slice()) + Ok(decoded_bytes.concat()) } else { Err(ArrayError::UnexpectedChunkDecodedSize( total_size, @@ -663,7 +656,7 @@ impl Array { &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { array_retrieve_elements!(self, retrieve_chunk_subset(chunk_indices, chunk_subset)) } diff --git a/src/array/array_sync_readable_writable.rs b/src/array/array_sync_readable_writable.rs index 73843123..be639d06 100644 --- a/src/array/array_sync_readable_writable.rs +++ b/src/array/array_sync_readable_writable.rs @@ -312,7 +312,7 @@ impl Array { } // Store the updated chunk - self.store_chunk(chunk_indices, chunk_bytes.into_vec()) + self.store_chunk(chunk_indices, chunk_bytes) } } diff --git a/src/storage/store/store_sync/http_store.rs b/src/storage/store/store_sync/http_store.rs index 6fc7bb22..f74e3cc4 100644 --- a/src/storage/store/store_sync/http_store.rs +++ b/src/storage/store/store_sync/http_store.rs @@ -281,7 +281,7 @@ mod tests { let data_4x2 = array .retrieve_array_subset_elements::(&subset_4x2) .unwrap(); - assert_eq!(data_4x2, [19, 20, 27, 28, 35, 36, 43, 44].into()); + assert_eq!(data_4x2, [19, 20, 27, 28, 35, 36, 43, 44]); // let data = array.retrieve_array_subset_ndarray::(&ArraySubset::new_with_shape(array.shape().to_vec())).unwrap(); // println!("{data:?}");