Skip to content

Commit

Permalink
Add array::decode_fill_value_into()
Browse files Browse the repository at this point in the history
  • Loading branch information
LDeakin committed Oct 27, 2024
1 parent cbe67c5 commit 0ba54a4
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add a `makefile` and simplify `BUILD.md`
- Add chunk-by-chunk update example in `Array` docs
- Add `array::decode_fill_value_into()`

### Changed
- Bump `unsafe_cell_slice` to 0.2.0
Expand Down
2 changes: 1 addition & 1 deletion zarrs/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use std::sync::Arc;

pub use self::{
array_builder::ArrayBuilder,
array_bytes::{ArrayBytes, ArrayBytesError, RawBytes, RawBytesOffsets},
array_bytes::{decode_fill_value_into, ArrayBytes, ArrayBytesError, RawBytes, RawBytesOffsets},
array_errors::{ArrayCreateError, ArrayError},
array_metadata_options::ArrayMetadataOptions,
array_representation::{
Expand Down
29 changes: 10 additions & 19 deletions zarrs/src/array/array_async_readable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ use crate::{
};

use super::{
array_bytes::{merge_chunks_vlen, update_bytes_flen},
array_bytes::{decode_fill_value_into, merge_chunks_vlen},
codec::{
options::CodecOptions, ArrayToBytesCodecTraits, AsyncArrayPartialDecoderTraits,
AsyncStoragePartialDecoder, CodecError,
AsyncStoragePartialDecoder,
},
concurrency::concurrency_chunks_and_codec,
element::ElementOwned,
Expand Down Expand Up @@ -381,23 +381,14 @@ impl<TStorage: ?Sized + AsyncReadableStorageTraits + 'static> Array<TStorage> {
)
.map_err(ArrayError::CodecError)
} else {
// Fill with the fill value
let array_size = ArraySize::new(self.data_type().size(), output_subset.num_elements());
if let ArrayBytes::Fixed(fill_value_bytes) =
ArrayBytes::new_fill_value(array_size, self.fill_value())
{
update_bytes_flen(
output,
output_shape,
&fill_value_bytes,
output_subset,
self.data_type().fixed_size().unwrap(),
);
Ok(())
} else {
// TODO: Variable length data type support?
Err(ArrayError::CodecError(CodecError::ExpectedFixedLengthBytes))
}
decode_fill_value_into(
self.data_type(),
self.fill_value(),
output,
output_shape,
output_subset,
)
.map_err(ArrayError::CodecError)
}
}

Expand Down
39 changes: 39 additions & 0 deletions zarrs/src/array/array_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,45 @@ pub fn extract_decoded_regions_vlen<'a>(
Ok(out)
}

/// Decode the fill value into a subset of a preallocated output.
///
/// This method is intended for internal use by Array.
/// It currently only works for fixed length data types.
///
/// # Errors
/// Returns [`CodecError::ExpectedFixedLengthBytes`] for variable-sized data.
///
/// # Safety
/// The caller must ensure that:
/// - `data_type` and `fill_value` are compatible,
/// - `output` holds enough space for the preallocated bytes of an array with `output_shape` and `data_type`, and
/// - `output_subset` is within the bounds of `output_shape`.
pub unsafe fn decode_fill_value_into(
data_type: &DataType,
fill_value: &FillValue,
output: &UnsafeCellSlice<u8>,
output_shape: &[u64],
output_subset: &ArraySubset,
) -> Result<(), CodecError> {
let array_size = ArraySize::new(data_type.size(), output_subset.num_elements());
if let (ArrayBytes::Fixed(fill_value_bytes), Some(data_type_size)) = (
ArrayBytes::new_fill_value(array_size, fill_value),
data_type.fixed_size(),
) {
update_bytes_flen(
output,
output_shape,
&fill_value_bytes,
output_subset,
data_type_size,
);
Ok(())
} else {
// TODO: Variable length data type support?
Err(CodecError::ExpectedFixedLengthBytes)
}
}

impl<'a> From<RawBytes<'a>> for ArrayBytes<'a> {
fn from(bytes: RawBytes<'a>) -> Self {
Self::new_flen(bytes)
Expand Down
29 changes: 10 additions & 19 deletions zarrs/src/array/array_sync_readable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use crate::{
};

use super::{
array_bytes::{merge_chunks_vlen, update_bytes_flen},
array_bytes::{decode_fill_value_into, merge_chunks_vlen},
codec::{
options::CodecOptions, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, CodecError,
options::CodecOptions, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits,
StoragePartialDecoder,
},
concurrency::concurrency_chunks_and_codec,
Expand Down Expand Up @@ -502,23 +502,14 @@ impl<TStorage: ?Sized + ReadableStorageTraits + 'static> Array<TStorage> {
)
.map_err(ArrayError::CodecError)
} else {
// Fill with the fill value
let array_size = ArraySize::new(self.data_type().size(), output_subset.num_elements());
if let ArrayBytes::Fixed(fill_value_bytes) =
ArrayBytes::new_fill_value(array_size, self.fill_value())
{
update_bytes_flen(
output,
output_shape,
&fill_value_bytes,
output_subset,
self.data_type().fixed_size().unwrap(),
);
Ok(())
} else {
// TODO: Variable length data type support?
Err(ArrayError::CodecError(CodecError::ExpectedFixedLengthBytes))
}
decode_fill_value_into(
self.data_type(),
self.fill_value(),
output,
output_shape,
output_subset,
)
.map_err(ArrayError::CodecError)
}
}

Expand Down

0 comments on commit 0ba54a4

Please sign in to comment.