Merge branch 'feat/p3-python-remote-edit' into feat/p3-wasm-swmr-python
# Conflicts: # CHANGELOG.md # docs/design/range-reads.md # docs/known-issues.md
This commit is contained in:
@@ -135,6 +135,12 @@ impl ChunkGrid {
|
||||
let mut rem = index;
|
||||
for p in 0..rank {
|
||||
let d = self.order[p];
|
||||
// A zero stride: a later dimension has no chunks (its maximum,
|
||||
// or with none recorded its current extent, is 0), so no slot of
|
||||
// the index is a chunk of the dataset.
|
||||
if self.down[p] == 0 {
|
||||
return None;
|
||||
}
|
||||
let scaled = rem / self.down[p];
|
||||
rem %= self.down[p];
|
||||
if scaled >= self.cur_chunks[d] {
|
||||
@@ -193,6 +199,28 @@ mod tests {
|
||||
assert_eq!(g.offsets(11), Some(vec![2, 3]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_extent_has_no_chunks() {
|
||||
// No maximum recorded and a zero current dimension: every stride
|
||||
// before it is 0 (this divided by zero).
|
||||
let g = ChunkGrid::fixed_array(&[1, 0], None, &[6, 6]).unwrap();
|
||||
for i in 0..16 {
|
||||
assert_eq!(g.offsets(i), None);
|
||||
}
|
||||
let g = ChunkGrid::fixed_array(&[0, 0, 3], Some(&[4, 0, 3]), &[2, 2, 3]).unwrap();
|
||||
for i in 0..16 {
|
||||
assert_eq!(g.offsets(i), None);
|
||||
}
|
||||
let g = ChunkGrid::extensible_array(&[0, 5], Some(&[u64::MAX, 0]), &[2, 2]).unwrap();
|
||||
for i in 0..16 {
|
||||
assert_eq!(g.offsets(i), None);
|
||||
}
|
||||
// A zero last dimension leaves the other strides alone.
|
||||
let g = ChunkGrid::fixed_array(&[4, 0], Some(&[4, 6]), &[2, 3]).unwrap();
|
||||
assert_eq!(g.offsets(0), None);
|
||||
assert_eq!(g.linear_index(&[1, 1]), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_two_unlimited_dims_after_the_first() {
|
||||
assert!(ChunkGrid::fixed_array(&[4, 6], Some(&[u64::MAX, u64::MAX]), &[2, 3]).is_err());
|
||||
|
||||
@@ -130,6 +130,22 @@ pub(crate) fn build_chunked_dataset_oh(
|
||||
fill_message: &[u8],
|
||||
refcount: u32,
|
||||
) -> Result<Vec<u8>, FormatError> {
|
||||
// libhdf5 records every simple dataspace's maximum dimensions (the
|
||||
// dimensions themselves when none are given, `H5S_set_extent_simple`).
|
||||
// Without them libhdf5 takes the maximum to be the current dimensions,
|
||||
// so a resize by libhdf5 (h5py's `Dataset.resize`) would also change
|
||||
// the maximum a Fixed Array chunk index is laid out by, and move every
|
||||
// chunk already written.
|
||||
let recorded;
|
||||
let ds = if ds.space_type == DataspaceType::Simple && ds.max_dimensions.is_none() {
|
||||
recorded = Dataspace {
|
||||
max_dimensions: Some(ds.dimensions.clone()),
|
||||
..ds.clone()
|
||||
};
|
||||
&recorded
|
||||
} else {
|
||||
ds
|
||||
};
|
||||
let mut w = ObjectHeaderWriter::new();
|
||||
w.add_message_with_flags(MessageType::Datatype, dt.serialize(), 0x01);
|
||||
w.add_message(MessageType::Dataspace, ds.serialize(LENGTH_SIZE));
|
||||
|
||||
Reference in New Issue
Block a user