Skip to content

Commit 1d685da

Browse files
committed
Move ChunkInfo to chunks file
1 parent d7c24fa commit 1d685da

File tree

4 files changed

+153
-132
lines changed

4 files changed

+153
-132
lines changed

src/hl.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
pub mod attribute;
2-
#[cfg(feature = "1.13.0")]
32
pub mod chunks;
43
pub mod container;
54
pub mod dataset;

src/hl/chunks.rs

Lines changed: 147 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,165 @@
11
use crate::internal_prelude::*;
2-
use hdf5_sys::h5d::H5Dchunk_iter;
32

4-
/// Borrowed version of [ChunkInfo](crate::dataset::ChunkInfo)
5-
#[derive(Debug)]
6-
pub struct ChunkInfoBorrowed<'a> {
7-
pub offset: &'a [u64],
3+
#[cfg(feature = "1.10.5")]
4+
use hdf5_sys::h5d::{H5Dget_chunk_info, H5Dget_num_chunks};
5+
6+
#[cfg(feature = "1.10.5")]
7+
#[derive(Clone, Debug, PartialEq, Eq)]
8+
pub struct ChunkInfo {
9+
/// Array with a size equal to the dataset’s rank whose elements contain 0-based
10+
/// logical positions of the chunk’s first element in each dimension.
11+
pub offset: Vec<u64>,
12+
/// Filter mask that indicates which filters were used with the chunk when written.
13+
/// A zero value indicates that all enabled filters are applied on the chunk.
14+
/// A filter is skipped if the bit corresponding to the filter’s position in
15+
/// the pipeline (0 ≤ position < 32) is turned on.
816
pub filter_mask: u32,
17+
/// Chunk address in the file.
918
pub addr: u64,
19+
/// Chunk size in bytes.
1020
pub size: u64,
1121
}
1222

13-
struct RustCallback<F> {
14-
ndims: usize,
15-
callback: F,
16-
}
23+
#[cfg(feature = "1.10.5")]
24+
impl ChunkInfo {
25+
pub(crate) fn new(ndim: usize) -> Self {
26+
let offset = vec![0; ndim];
27+
Self { offset, filter_mask: 0, addr: 0, size: 0 }
28+
}
1729

18-
extern "C" fn chunks_callback<F>(
19-
offset: *const hsize_t, filter_mask: u32, addr: haddr_t, nbytes: u32, op_data: *mut c_void,
20-
) -> herr_t
21-
where
22-
F: FnMut(ChunkInfoBorrowed) -> i32,
23-
{
24-
unsafe {
25-
std::panic::catch_unwind(|| {
26-
let data: *mut RustCallback<F> = op_data.cast::<RustCallback<F>>();
27-
let ndims = (*data).ndims;
28-
let callback = &mut (*data).callback;
29-
30-
let offset = std::slice::from_raw_parts(offset, ndims);
31-
32-
let info =
33-
ChunkInfoBorrowed { offset, filter_mask, addr: addr as u64, size: nbytes as u64 };
34-
35-
callback(info)
36-
})
37-
.unwrap_or(-1)
30+
/// Returns positional indices of disabled filters.
31+
pub fn disabled_filters(&self) -> Vec<usize> {
32+
(0..32).filter(|i| self.filter_mask & (1 << i) != 0).collect()
3833
}
3934
}
4035

41-
pub(crate) fn visit<F>(ds: &Dataset, callback: F) -> Result<()>
42-
where
43-
F: for<'a> FnMut(ChunkInfoBorrowed<'a>) -> i32,
44-
{
45-
let mut data = RustCallback::<F> { ndims: ds.ndim(), callback };
46-
47-
h5try!(H5Dchunk_iter(
48-
ds.id(),
49-
H5P_DEFAULT,
50-
Some(chunks_callback::<F>),
51-
std::ptr::addr_of_mut!(data).cast()
52-
));
36+
#[cfg(feature = "1.10.5")]
37+
pub(crate) fn chunk_info(ds: &Dataset, index: usize) -> Option<ChunkInfo> {
38+
if !ds.is_chunked() {
39+
return None;
40+
}
41+
h5lock!(ds.space().map_or(None, |s| {
42+
let mut chunk_info = ChunkInfo::new(ds.ndim());
43+
h5check(H5Dget_chunk_info(
44+
ds.id(),
45+
s.id(),
46+
index as _,
47+
chunk_info.offset.as_mut_ptr(),
48+
&mut chunk_info.filter_mask,
49+
&mut chunk_info.addr,
50+
&mut chunk_info.size,
51+
))
52+
.map(|_| chunk_info)
53+
.ok()
54+
}))
55+
}
5356

54-
Ok(())
57+
#[cfg(feature = "1.10.5")]
58+
pub(crate) fn get_num_chunks(ds: &Dataset) -> Option<usize> {
59+
if !ds.is_chunked() {
60+
return None;
61+
}
62+
h5lock!(ds.space().map_or(None, |s| {
63+
let mut n: hsize_t = 0;
64+
h5check(H5Dget_num_chunks(ds.id(), s.id(), &mut n)).map(|_| n as _).ok()
65+
}))
5566
}
5667

57-
#[cfg(test)]
58-
mod test {
68+
#[cfg(feature = "1.13.0")]
69+
mod one_thirteen {
5970
use super::*;
71+
use hdf5_sys::h5d::H5Dchunk_iter;
72+
/// Borrowed version of [ChunkInfo](crate::dataset::ChunkInfo)
73+
#[derive(Debug)]
74+
pub struct ChunkInfoBorrowed<'a> {
75+
pub offset: &'a [u64],
76+
pub filter_mask: u32,
77+
pub addr: u64,
78+
pub size: u64,
79+
}
80+
81+
struct RustCallback<F> {
82+
ndims: usize,
83+
callback: F,
84+
}
85+
86+
extern "C" fn chunks_callback<F>(
87+
offset: *const hsize_t, filter_mask: u32, addr: haddr_t, nbytes: u32, op_data: *mut c_void,
88+
) -> herr_t
89+
where
90+
F: FnMut(ChunkInfoBorrowed) -> i32,
91+
{
92+
unsafe {
93+
std::panic::catch_unwind(|| {
94+
let data: *mut RustCallback<F> = op_data.cast::<RustCallback<F>>();
95+
let ndims = (*data).ndims;
96+
let callback = &mut (*data).callback;
97+
98+
let offset = std::slice::from_raw_parts(offset, ndims);
99+
100+
let info = ChunkInfoBorrowed {
101+
offset,
102+
filter_mask,
103+
addr: addr as u64,
104+
size: nbytes as u64,
105+
};
106+
107+
callback(info)
108+
})
109+
.unwrap_or(-1)
110+
}
111+
}
112+
113+
pub(crate) fn visit<F>(ds: &Dataset, callback: F) -> Result<()>
114+
where
115+
F: for<'a> FnMut(ChunkInfoBorrowed<'a>) -> i32,
116+
{
117+
let mut data = RustCallback::<F> { ndims: ds.ndim(), callback };
118+
119+
h5try!(H5Dchunk_iter(
120+
ds.id(),
121+
H5P_DEFAULT,
122+
Some(chunks_callback::<F>),
123+
std::ptr::addr_of_mut!(data).cast()
124+
));
125+
126+
Ok(())
127+
}
128+
129+
#[cfg(test)]
130+
mod test {
131+
use super::*;
132+
133+
#[test]
134+
fn chunks_visit() {
135+
with_tmp_file(|f| {
136+
let ds = f.new_dataset::<i16>().no_chunk().shape((4, 4)).create("nochunk").unwrap();
137+
assert_err_re!(visit(&ds, |_| 0), "not a chunked dataset");
138+
139+
let ds =
140+
f.new_dataset::<i16>().shape([3, 2]).chunk([1, 1]).create("chunk").unwrap();
141+
ds.write(&ndarray::arr2(&[[1, 2], [3, 4], [5, 6]])).unwrap();
60142

61-
#[test]
62-
fn chunks_visit() {
63-
with_tmp_file(|f| {
64-
let ds = f.new_dataset::<i16>().no_chunk().shape((4, 4)).create("nochunk").unwrap();
65-
assert_err_re!(visit(&ds, |_| 0), "not a chunked dataset");
66-
67-
let ds = f.new_dataset::<i16>().shape([3, 2]).chunk([1, 1]).create("chunk").unwrap();
68-
ds.write(&ndarray::arr2(&[[1, 2], [3, 4], [5, 6]])).unwrap();
69-
70-
let mut i = 0;
71-
let f = |c: ChunkInfoBorrowed| {
72-
match i {
73-
0 => assert_eq!(c.offset, [0, 0]),
74-
1 => assert_eq!(c.offset, [0, 1]),
75-
2 => assert_eq!(c.offset, [1, 0]),
76-
3 => assert_eq!(c.offset, [1, 1]),
77-
4 => assert_eq!(c.offset, [2, 0]),
78-
5 => assert_eq!(c.offset, [2, 1]),
79-
_ => unreachable!(),
80-
}
81-
assert_eq!(c.size, std::mem::size_of::<i16>() as u64);
82-
i += 1;
83-
0
84-
};
85-
visit(&ds, f).unwrap();
86-
assert_eq!(i, 6);
87-
})
143+
let mut i = 0;
144+
let f = |c: ChunkInfoBorrowed| {
145+
match i {
146+
0 => assert_eq!(c.offset, [0, 0]),
147+
1 => assert_eq!(c.offset, [0, 1]),
148+
2 => assert_eq!(c.offset, [1, 0]),
149+
3 => assert_eq!(c.offset, [1, 1]),
150+
4 => assert_eq!(c.offset, [2, 0]),
151+
5 => assert_eq!(c.offset, [2, 1]),
152+
_ => unreachable!(),
153+
}
154+
assert_eq!(c.size, std::mem::size_of::<i16>() as u64);
155+
i += 1;
156+
0
157+
};
158+
visit(&ds, f).unwrap();
159+
assert_eq!(i, 6);
160+
})
161+
}
88162
}
89163
}
164+
#[cfg(feature = "1.13.0")]
165+
pub use one_thirteen::*;

src/hl/dataset.rs

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ use hdf5_sys::h5d::{
88
H5Dcreate2, H5Dcreate_anon, H5Dget_access_plist, H5Dget_create_plist, H5Dget_offset,
99
H5Dset_extent,
1010
};
11-
#[cfg(feature = "1.10.5")]
12-
use hdf5_sys::h5d::{H5Dget_chunk_info, H5Dget_num_chunks};
1311
use hdf5_sys::h5l::H5Ldelete;
1412
use hdf5_sys::h5p::H5P_DEFAULT;
1513
use hdf5_sys::h5z::H5Z_filter_t;
@@ -66,36 +64,6 @@ impl Deref for Dataset {
6664
}
6765
}
6866

69-
#[cfg(feature = "1.10.5")]
70-
#[derive(Clone, Debug, PartialEq, Eq)]
71-
pub struct ChunkInfo {
72-
/// Array with a size equal to the dataset’s rank whose elements contain 0-based
73-
/// logical positions of the chunk’s first element in each dimension.
74-
pub offset: Vec<u64>,
75-
/// Filter mask that indicates which filters were used with the chunk when written.
76-
/// A zero value indicates that all enabled filters are applied on the chunk.
77-
/// A filter is skipped if the bit corresponding to the filter’s position in
78-
/// the pipeline (0 ≤ position < 32) is turned on.
79-
pub filter_mask: u32,
80-
/// Chunk address in the file.
81-
pub addr: u64,
82-
/// Chunk size in bytes.
83-
pub size: u64,
84-
}
85-
86-
#[cfg(feature = "1.10.5")]
87-
impl ChunkInfo {
88-
pub(crate) fn new(ndim: usize) -> Self {
89-
let offset = vec![0; ndim];
90-
Self { offset, filter_mask: 0, addr: 0, size: 0 }
91-
}
92-
93-
/// Returns positional indices of disabled filters.
94-
pub fn disabled_filters(&self) -> Vec<usize> {
95-
(0..32).filter(|i| self.filter_mask & (1 << i) != 0).collect()
96-
}
97-
}
98-
9967
impl Dataset {
10068
/// Returns a copy of the dataset access property list.
10169
pub fn access_plist(&self) -> Result<DatasetAccess> {
@@ -135,35 +103,13 @@ impl Dataset {
135103
#[cfg(feature = "1.10.5")]
136104
/// Returns the number of chunks if the dataset is chunked.
137105
pub fn num_chunks(&self) -> Option<usize> {
138-
if !self.is_chunked() {
139-
return None;
140-
}
141-
h5lock!(self.space().map_or(None, |s| {
142-
let mut n: hsize_t = 0;
143-
h5check(H5Dget_num_chunks(self.id(), s.id(), &mut n)).map(|_| n as _).ok()
144-
}))
106+
crate::hl::chunks::get_num_chunks(self)
145107
}
146108

147109
#[cfg(feature = "1.10.5")]
148110
/// Retrieves the chunk information for the chunk specified by its index.
149-
pub fn chunk_info(&self, index: usize) -> Option<ChunkInfo> {
150-
if !self.is_chunked() {
151-
return None;
152-
}
153-
h5lock!(self.space().map_or(None, |s| {
154-
let mut chunk_info = ChunkInfo::new(self.ndim());
155-
h5check(H5Dget_chunk_info(
156-
self.id(),
157-
s.id(),
158-
index as _,
159-
chunk_info.offset.as_mut_ptr(),
160-
&mut chunk_info.filter_mask,
161-
&mut chunk_info.addr,
162-
&mut chunk_info.size,
163-
))
164-
.map(|_| chunk_info)
165-
.ok()
166-
}))
111+
pub fn chunk_info(&self, index: usize) -> Option<crate::dataset::ChunkInfo> {
112+
crate::hl::chunks::chunk_info(self, index)
167113
}
168114

169115
/// Returns the chunk shape if the dataset is chunked.
@@ -175,7 +121,7 @@ impl Dataset {
175121
#[cfg(feature = "1.13.0")]
176122
pub fn chunks_visit<F>(&self, callback: F) -> Result<()>
177123
where
178-
F: for<'a> FnMut(crate::hl::chunks::ChunkInfoBorrowed<'a>) -> i32,
124+
F: for<'a> FnMut(crate::dataset::ChunkInfoBorrowed<'a>) -> i32,
179125
{
180126
crate::hl::chunks::visit(self, callback)
181127
}

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ mod export {
7777
}
7878

7979
pub mod dataset {
80+
#[cfg(feature = "1.10.5")]
81+
pub use crate::hl::chunks::ChunkInfo;
8082
#[cfg(feature = "1.13.0")]
8183
pub use crate::hl::chunks::ChunkInfoBorrowed;
82-
#[cfg(feature = "1.10.5")]
83-
pub use crate::hl::dataset::ChunkInfo;
8484
pub use crate::hl::dataset::{Chunk, Dataset, DatasetBuilder};
8585
pub use crate::hl::plist::dataset_access::*;
8686
pub use crate::hl::plist::dataset_create::*;

0 commit comments

Comments
 (0)