Range reads M0/M1 (indexed lookups, Storage trait), ZFP, in-place editing #17
@@ -111,14 +111,19 @@ pub fn dataset_fill_value(messages: &[HeaderMessage]) -> Result<Option<Vec<u8>>,
|
|||||||
/// fill value message to where it lives: another object header, or the
|
/// fill value message to where it lives: another object header, or the
|
||||||
/// file's shared-message (SOHM) heap, as libhdf5 writes it when the file has
|
/// file's shared-message (SOHM) heap, as libhdf5 writes it when the file has
|
||||||
/// a SOHM index for fill values.
|
/// a SOHM index for fill values.
|
||||||
pub fn dataset_fill_value_in(
|
///
|
||||||
file_data: &[u8],
|
/// `file_data` is any [`Storage`](crate::storage::Storage): the file as a
|
||||||
|
/// `&[u8]`, or a backend that serves it by range. (The trait is not
|
||||||
|
/// imported here: its `len` would shadow the slice method in this module.)
|
||||||
|
pub fn dataset_fill_value_in<S: crate::storage::Storage + ?Sized>(
|
||||||
|
file_data: &S,
|
||||||
messages: &[HeaderMessage],
|
messages: &[HeaderMessage],
|
||||||
offset_size: u8,
|
offset_size: u8,
|
||||||
length_size: u8,
|
length_size: u8,
|
||||||
) -> Result<Option<Vec<u8>>, FormatError> {
|
) -> Result<Option<Vec<u8>>, FormatError> {
|
||||||
|
let file: &dyn crate::storage::Storage = &file_data;
|
||||||
fill_value_from(messages, |msg| {
|
fill_value_from(messages, |msg| {
|
||||||
crate::shared_message::message_data_with_sohm(file_data, msg, offset_size, length_size)
|
crate::shared_message::message_data_with_sohm_in(file, msg, offset_size, length_size)
|
||||||
.map(|data| data.into_owned())
|
.map(|data| data.into_owned())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -439,4 +444,37 @@ mod tests {
|
|||||||
.collect();
|
.collect();
|
||||||
assert_eq!(filled, [2, 3, 7, 8]);
|
assert_eq!(filled, [2, 3, 7, 8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fill values, shared ones in the SOHM heap included, resolve
|
||||||
|
/// identically through a read_at-only CountingStorage.
|
||||||
|
#[test]
|
||||||
|
fn storage_reads_match_slice_reads() {
|
||||||
|
use crate::object_header::ObjectHeader;
|
||||||
|
use crate::storage::CountingStorage;
|
||||||
|
let file: &[u8] = include_bytes!("../tests/fixtures/shared_fill_value.h5");
|
||||||
|
let sb = crate::superblock::Superblock::parse(file, 0).unwrap();
|
||||||
|
let (os, ls) = (sb.offset_size, sb.length_size);
|
||||||
|
let storage = CountingStorage::new(file.to_vec());
|
||||||
|
let mut shared = 0;
|
||||||
|
let children =
|
||||||
|
crate::group_v2::resolve_group_children(file, &sb, sb.root_group_address).unwrap();
|
||||||
|
assert!(children.len() >= 3);
|
||||||
|
for child in children {
|
||||||
|
let h =
|
||||||
|
ObjectHeader::parse(file, child.object_header_address as usize, os, ls).unwrap();
|
||||||
|
shared += h
|
||||||
|
.messages
|
||||||
|
.iter()
|
||||||
|
.filter(|m| {
|
||||||
|
m.msg_type == MessageType::FillValue
|
||||||
|
&& crate::shared_message::is_shared(m.flags)
|
||||||
|
})
|
||||||
|
.count();
|
||||||
|
let want = dataset_fill_value_in(file, &h.messages, os, ls);
|
||||||
|
assert_eq!(want, Ok(Some((-7i32).to_le_bytes().to_vec())));
|
||||||
|
let got = dataset_fill_value_in(&storage, &h.messages, os, ls);
|
||||||
|
assert_eq!(got, want, "{}", child.name);
|
||||||
|
}
|
||||||
|
assert!(shared >= 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user