Skip to content

Commit ef94007

Browse files
authored
Merge pull request #52 from aldanor/feature/dapl
DAPL API wrappers
2 parents 4d44d22 + b298751 commit ef94007

File tree

6 files changed

+379
-0
lines changed

6 files changed

+379
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Added support for HDF5 1.10.5 with bindings for new functions.
88
- `File::access_plist()` or `File::fapl()` to get file access plist.
99
- `File::create_plist()` or `File::fcpl()` to get file creation plist.
10+
- Added high-level wrappers for dataset access H5P API (`plist::DatasetAccess`).
1011

1112
### Changed
1213

hdf5-sys/src/h5d.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ mod hdf5_1_10_0 {
202202
H5D_VDS_LAST_AVAILABLE = 1,
203203
}
204204

205+
impl Default for H5D_vds_view_t {
206+
fn default() -> Self {
207+
H5D_vds_view_t::H5D_VDS_LAST_AVAILABLE
208+
}
209+
}
210+
205211
pub const H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS: c_uint = 1;
206212

207213
pub type H5D_append_cb_t = Option<

src/hl/plist.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use hdf5_sys::h5p::{
99

1010
use crate::internal_prelude::*;
1111

12+
pub mod dataset_access;
1213
pub mod file_access;
1314
pub mod file_create;
1415

src/hl/plist/dataset_access.rs

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
//! Dataset access properties.
2+
3+
/*
4+
Not implemented:
5+
- H5P{set,get}_append_flush (due to having to deal with raw C extern callbacks)
6+
*/
7+
8+
use std::fmt::{self, Debug};
9+
use std::ops::Deref;
10+
11+
use hdf5_sys::h5p::{H5Pcreate, H5Pget_chunk_cache, H5Pset_chunk_cache};
12+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
13+
use hdf5_sys::h5p::{H5Pget_all_coll_metadata_ops, H5Pset_all_coll_metadata_ops};
14+
#[cfg(hdf5_1_8_17)]
15+
use hdf5_sys::h5p::{H5Pget_efile_prefix, H5Pset_efile_prefix};
16+
#[cfg(hdf5_1_10_0)]
17+
use hdf5_sys::{
18+
h5d::H5D_vds_view_t,
19+
h5p::{
20+
H5Pget_virtual_printf_gap, H5Pget_virtual_view, H5Pset_virtual_printf_gap,
21+
H5Pset_virtual_view,
22+
},
23+
};
24+
25+
pub use super::file_access::ChunkCache;
26+
use crate::globals::H5P_DATASET_ACCESS;
27+
use crate::internal_prelude::*;
28+
29+
/// Dataset access properties.
30+
#[repr(transparent)]
31+
pub struct DatasetAccess(Handle);
32+
33+
impl ObjectClass for DatasetAccess {
34+
const NAME: &'static str = "dataset access property list";
35+
const VALID_TYPES: &'static [H5I_type_t] = &[H5I_GENPROP_LST];
36+
37+
fn from_handle(handle: Handle) -> Self {
38+
Self(handle)
39+
}
40+
41+
fn handle(&self) -> &Handle {
42+
&self.0
43+
}
44+
45+
fn validate(&self) -> Result<()> {
46+
let class = self.class()?;
47+
if class != PropertyListClass::DatasetAccess {
48+
fail!("expected dataset access property list, got {:?}", class);
49+
}
50+
Ok(())
51+
}
52+
}
53+
54+
impl Debug for DatasetAccess {
55+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56+
let _e = silence_errors();
57+
let mut formatter = f.debug_struct("DatasetAccess");
58+
formatter.field("chunk_cache", &self.chunk_cache());
59+
#[cfg(hdf5_1_8_17)]
60+
formatter.field("efile_prefix", &self.efile_prefix());
61+
#[cfg(hdf5_1_10_0)]
62+
{
63+
formatter.field("virtual_view", &self.virtual_view());
64+
formatter.field("virtual_printf_gap", &self.virtual_printf_gap());
65+
}
66+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
67+
formatter.field("all_coll_metadata_ops", &self.all_coll_metadata_ops());
68+
formatter.finish()
69+
}
70+
}
71+
72+
impl Deref for DatasetAccess {
73+
type Target = PropertyList;
74+
75+
fn deref(&self) -> &PropertyList {
76+
unsafe { self.transmute() }
77+
}
78+
}
79+
80+
impl PartialEq for DatasetAccess {
81+
fn eq(&self, other: &Self) -> bool {
82+
<PropertyList as PartialEq>::eq(self, other)
83+
}
84+
}
85+
86+
impl Eq for DatasetAccess {}
87+
88+
impl Clone for DatasetAccess {
89+
fn clone(&self) -> Self {
90+
unsafe { self.deref().clone().cast() }
91+
}
92+
}
93+
94+
#[cfg(hdf5_1_10_0)]
95+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
96+
pub enum VirtualView {
97+
FirstMissing,
98+
LastAvailable,
99+
}
100+
101+
#[cfg(hdf5_1_10_0)]
102+
impl Default for VirtualView {
103+
fn default() -> Self {
104+
VirtualView::LastAvailable
105+
}
106+
}
107+
108+
#[cfg(hdf5_1_10_0)]
109+
impl From<H5D_vds_view_t> for VirtualView {
110+
fn from(view: H5D_vds_view_t) -> Self {
111+
match view {
112+
H5D_vds_view_t::H5D_VDS_FIRST_MISSING => VirtualView::FirstMissing,
113+
_ => VirtualView::LastAvailable,
114+
}
115+
}
116+
}
117+
118+
#[cfg(hdf5_1_10_0)]
119+
impl From<VirtualView> for H5D_vds_view_t {
120+
fn from(view: VirtualView) -> Self {
121+
match view {
122+
VirtualView::FirstMissing => H5D_vds_view_t::H5D_VDS_FIRST_MISSING,
123+
_ => H5D_vds_view_t::H5D_VDS_LAST_AVAILABLE,
124+
}
125+
}
126+
}
127+
128+
/// Builder used to create dataset access property list.
129+
#[derive(Clone, Debug, Default)]
130+
pub struct DatasetAccessBuilder {
131+
chunk_cache: Option<ChunkCache>,
132+
#[cfg(hdf5_1_8_17)]
133+
efile_prefix: Option<String>,
134+
#[cfg(hdf5_1_10_0)]
135+
virtual_view: Option<VirtualView>,
136+
#[cfg(hdf5_1_10_0)]
137+
virtual_printf_gap: Option<usize>,
138+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
139+
all_coll_metadata_ops: Option<bool>,
140+
}
141+
142+
impl DatasetAccessBuilder {
143+
/// Creates a new dataset access property list builder.
144+
pub fn new() -> Self {
145+
Self::default()
146+
}
147+
148+
/// Creates a new builder from an existing property list.
149+
pub fn from_plist(plist: &DatasetAccess) -> Result<Self> {
150+
let mut builder = Self::default();
151+
let v = plist.get_chunk_cache()?;
152+
builder.chunk_cache(v.nslots, v.nbytes, v.w0);
153+
#[cfg(hdf5_1_8_17)]
154+
{
155+
let v = plist.get_efile_prefix()?;
156+
builder.efile_prefix(&v);
157+
}
158+
#[cfg(hdf5_1_10_0)]
159+
{
160+
builder.virtual_view(plist.get_virtual_view()?);
161+
builder.virtual_printf_gap(plist.get_virtual_printf_gap()?);
162+
}
163+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
164+
builder.all_coll_metadata_ops(plist.get_all_coll_metadata_ops()?);
165+
Ok(builder)
166+
}
167+
168+
pub fn chunk_cache(&mut self, nslots: usize, nbytes: usize, w0: f64) -> &mut Self {
169+
self.chunk_cache = Some(ChunkCache { nslots, nbytes, w0 });
170+
self
171+
}
172+
173+
#[cfg(hdf5_1_8_17)]
174+
pub fn efile_prefix(&mut self, prefix: &str) -> &mut Self {
175+
self.efile_prefix = Some(prefix.into());
176+
self
177+
}
178+
179+
#[cfg(hdf5_1_10_0)]
180+
pub fn virtual_view(&mut self, view: VirtualView) -> &mut Self {
181+
self.virtual_view = Some(view);
182+
self
183+
}
184+
185+
#[cfg(hdf5_1_10_0)]
186+
pub fn virtual_printf_gap(&mut self, gap_size: usize) -> &mut Self {
187+
self.virtual_printf_gap = Some(gap_size);
188+
self
189+
}
190+
191+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
192+
pub fn all_coll_metadata_ops(&mut self, is_collective: bool) -> &mut Self {
193+
self.all_coll_metadata_ops = Some(is_collective);
194+
self
195+
}
196+
197+
fn populate_plist(&self, id: hid_t) -> Result<()> {
198+
if let Some(v) = self.chunk_cache {
199+
h5try!(H5Pset_chunk_cache(id, v.nslots as _, v.nbytes as _, v.w0 as _));
200+
}
201+
#[cfg(hdf5_1_8_17)]
202+
{
203+
if let Some(ref v) = self.efile_prefix {
204+
let v = to_cstring(v.as_ref())?;
205+
h5try!(H5Pset_efile_prefix(id, v.as_ptr()));
206+
}
207+
}
208+
#[cfg(hdf5_1_10_0)]
209+
{
210+
if let Some(v) = self.virtual_view {
211+
h5try!(H5Pset_virtual_view(id, v.into()));
212+
}
213+
if let Some(v) = self.virtual_printf_gap {
214+
h5try!(H5Pset_virtual_printf_gap(id, v as _));
215+
}
216+
}
217+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
218+
{
219+
if let Some(v) = self.all_coll_metadata_ops {
220+
h5try!(H5Pset_all_coll_metadata_ops(id, v as _));
221+
}
222+
}
223+
Ok(())
224+
}
225+
226+
pub fn finish(&self) -> Result<DatasetAccess> {
227+
h5lock!({
228+
let plist = DatasetAccess::try_new()?;
229+
self.populate_plist(plist.id())?;
230+
Ok(plist)
231+
})
232+
}
233+
}
234+
235+
/// Dataset access property list.
236+
impl DatasetAccess {
237+
pub fn try_new() -> Result<Self> {
238+
Self::from_id(h5try!(H5Pcreate(*H5P_DATASET_ACCESS)))
239+
}
240+
241+
pub fn copy(&self) -> Self {
242+
unsafe { self.deref().copy().cast() }
243+
}
244+
245+
pub fn build() -> DatasetAccessBuilder {
246+
DatasetAccessBuilder::new()
247+
}
248+
249+
#[doc(hidden)]
250+
pub fn get_chunk_cache(&self) -> Result<ChunkCache> {
251+
h5get!(H5Pget_chunk_cache(self.id()): size_t, size_t, c_double).map(
252+
|(nslots, nbytes, w0)| ChunkCache {
253+
nslots: nslots as _,
254+
nbytes: nbytes as _,
255+
w0: w0 as _,
256+
},
257+
)
258+
}
259+
260+
pub fn chunk_cache(&self) -> ChunkCache {
261+
self.get_chunk_cache().unwrap_or_else(|_| ChunkCache::default())
262+
}
263+
264+
#[cfg(hdf5_1_8_17)]
265+
#[doc(hidden)]
266+
pub fn get_efile_prefix(&self) -> Result<String> {
267+
h5lock!(get_h5_str(|m, s| H5Pget_efile_prefix(self.id(), m, s)))
268+
}
269+
270+
#[cfg(hdf5_1_8_17)]
271+
pub fn efile_prefix(&self) -> String {
272+
self.get_efile_prefix().ok().unwrap_or_else(|| "".into())
273+
}
274+
275+
#[cfg(hdf5_1_10_0)]
276+
#[doc(hidden)]
277+
pub fn get_virtual_view(&self) -> Result<VirtualView> {
278+
h5get!(H5Pget_virtual_view(self.id()): H5D_vds_view_t).map(Into::into)
279+
}
280+
281+
#[cfg(hdf5_1_10_0)]
282+
pub fn virtual_view(&self) -> VirtualView {
283+
self.get_virtual_view().ok().unwrap_or_else(VirtualView::default)
284+
}
285+
286+
#[cfg(hdf5_1_10_0)]
287+
#[doc(hidden)]
288+
pub fn get_virtual_printf_gap(&self) -> Result<usize> {
289+
h5get!(H5Pget_virtual_printf_gap(self.id()): hsize_t).map(|x| x as _)
290+
}
291+
292+
#[cfg(hdf5_1_10_0)]
293+
pub fn virtual_printf_gap(&self) -> usize {
294+
self.get_virtual_printf_gap().unwrap_or(0)
295+
}
296+
297+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
298+
#[doc(hidden)]
299+
pub fn get_all_coll_metadata_ops(&self) -> Result<bool> {
300+
h5get!(H5Pget_all_coll_metadata_ops(self.id()): hbool_t).map(|x| x > 0)
301+
}
302+
303+
#[cfg(all(hdf5_1_10_0, h5_have_parallel))]
304+
pub fn all_coll_metadata_ops(&self) -> bool {
305+
self.get_all_coll_metadata_ops().unwrap_or(false)
306+
}
307+
}

src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,26 @@ mod export {
3535
pub use hdf5_types::*;
3636
}
3737

38+
pub mod dataset {
39+
pub use crate::hl::dataset::{Chunk, Dataset, DatasetBuilder};
40+
pub use crate::hl::plist::dataset_access::*;
41+
}
42+
3843
pub mod file {
3944
pub use crate::hl::file::{File, FileBuilder, OpenMode};
4045
pub use crate::hl::plist::file_access::*;
4146
pub use crate::hl::plist::file_create::*;
4247
}
4348

4449
pub mod plist {
50+
pub use crate::hl::plist::dataset_access::DatasetAccess;
4551
pub use crate::hl::plist::file_access::FileAccess;
4652
pub use crate::hl::plist::file_create::FileCreate;
4753
pub use crate::hl::plist::{PropertyList, PropertyListClass};
4854

55+
pub mod dataset_access {
56+
pub use crate::hl::plist::dataset_access::*;
57+
}
4958
pub mod file_access {
5059
pub use crate::hl::plist::file_access::*;
5160
}

0 commit comments

Comments
 (0)