1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*-------------------------------------------------------------------------
15  *
16  * Created:		H5Pdapl.c
17  *              October 27, 2008
18  *              Neil Fortner <nfortne2@hdfgroup.org>
19  *
20  * Purpose:		Dataset access property list class routines
21  *
22  *-------------------------------------------------------------------------
23  */
24 
25 /****************/
26 /* Module Setup */
27 /****************/
28 
29 #include "H5Pmodule.h"          /* This source code file is part of the H5P module */
30 
31 
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h"		/* Generic Functions */
36 #include "H5Dprivate.h"		/* Datasets */
37 #include "H5Eprivate.h"		/* Error handling */
38 #include "H5Fprivate.h"		/* Files */
39 #include "H5Iprivate.h"		/* IDs */
40 #include "H5Ppkg.h"         /* Property lists */
41 #include "H5MMprivate.h"	/* Memory management */
42 
43 
44 /****************/
45 /* Local Macros */
46 /****************/
47 
48 /* ========= Dataset Access properties ============ */
49 /* Definitions for size of raw data chunk cache(slots) */
50 #define H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE       sizeof(size_t)
51 #define H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF        H5D_CHUNK_CACHE_NSLOTS_DEFAULT
52 #define H5D_ACS_DATA_CACHE_NUM_SLOTS_ENC        H5P__encode_chunk_cache_nslots
53 #define H5D_ACS_DATA_CACHE_NUM_SLOTS_DEC        H5P__decode_chunk_cache_nslots
54 /* Definition for size of raw data chunk cache(bytes) */
55 #define H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE       sizeof(size_t)
56 #define H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF        H5D_CHUNK_CACHE_NBYTES_DEFAULT
57 #define H5D_ACS_DATA_CACHE_BYTE_SIZE_ENC        H5P__encode_chunk_cache_nbytes
58 #define H5D_ACS_DATA_CACHE_BYTE_SIZE_DEC        H5P__decode_chunk_cache_nbytes
59 /* Definition for preemption read chunks first */
60 #define H5D_ACS_PREEMPT_READ_CHUNKS_SIZE        sizeof(double)
61 #define H5D_ACS_PREEMPT_READ_CHUNKS_DEF         H5D_CHUNK_CACHE_W0_DEFAULT
62 #define H5D_ACS_PREEMPT_READ_CHUNKS_ENC         H5P__encode_double
63 #define H5D_ACS_PREEMPT_READ_CHUNKS_DEC         H5P__decode_double
64 /* Definitions for VDS view option */
65 #define H5D_ACS_VDS_VIEW_SIZE                   sizeof(H5D_vds_view_t)
66 #define H5D_ACS_VDS_VIEW_DEF                    H5D_VDS_LAST_AVAILABLE
67 #define H5D_ACS_VDS_VIEW_ENC                    H5P__dacc_vds_view_enc
68 #define H5D_ACS_VDS_VIEW_DEC                    H5P__dacc_vds_view_dec
69 /* Definitions for VDS printf gap */
70 #define H5D_ACS_VDS_PRINTF_GAP_SIZE             sizeof(hsize_t)
71 #define H5D_ACS_VDS_PRINTF_GAP_DEF              (hsize_t)0
72 #define H5D_ACS_VDS_PRINTF_GAP_ENC              H5P__encode_hsize_t
73 #define H5D_ACS_VDS_PRINTF_GAP_DEC              H5P__decode_hsize_t
74 /* Definition for append flush */
75 #define H5D_ACS_APPEND_FLUSH_SIZE            	sizeof(H5D_append_flush_t)
76 #define H5D_ACS_APPEND_FLUSH_DEF             	{0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},NULL,NULL}
77 /* Definitions for external file prefix */
78 #define H5D_ACS_EFILE_PREFIX_SIZE               sizeof(char *)
79 #define H5D_ACS_EFILE_PREFIX_DEF                NULL /*default is no prefix */
80 #define H5D_ACS_EFILE_PREFIX_SET                H5P__dapl_efile_pref_set
81 #define H5D_ACS_EFILE_PREFIX_GET                H5P__dapl_efile_pref_get
82 #define H5D_ACS_EFILE_PREFIX_ENC                H5P__dapl_efile_pref_enc
83 #define H5D_ACS_EFILE_PREFIX_DEC                H5P__dapl_efile_pref_dec
84 #define H5D_ACS_EFILE_PREFIX_DEL                H5P__dapl_efile_pref_del
85 #define H5D_ACS_EFILE_PREFIX_COPY               H5P__dapl_efile_pref_copy
86 #define H5D_ACS_EFILE_PREFIX_CMP                H5P__dapl_efile_pref_cmp
87 #define H5D_ACS_EFILE_PREFIX_CLOSE              H5P__dapl_efile_pref_close
88 
89 /******************/
90 /* Local Typedefs */
91 /******************/
92 
93 
94 /********************/
95 /* Package Typedefs */
96 /********************/
97 
98 
99 /********************/
100 /* Local Prototypes */
101 /********************/
102 
103 /* Property class callbacks */
104 static herr_t H5P__dacc_reg_prop(H5P_genclass_t *pclass);
105 static herr_t H5P__encode_chunk_cache_nslots(const void *value, void **_pp,
106     size_t *size);
107 static herr_t H5P__decode_chunk_cache_nslots(const void **_pp, void *_value);
108 static herr_t H5P__encode_chunk_cache_nbytes(const void *value, void **_pp,
109     size_t *size);
110 static herr_t H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value);
111 
112 /* Property list callbacks */
113 static herr_t H5P__dacc_vds_view_enc(const void *value, void **pp, size_t *size);
114 static herr_t H5P__dacc_vds_view_dec(const void **pp, void *value);
115 
116 /* Property list callbacks */
117 static herr_t H5P__dapl_efile_pref_set(hid_t prop_id, const char* name, size_t size, void* value);
118 static herr_t H5P__dapl_efile_pref_get(hid_t prop_id, const char* name, size_t size, void* value);
119 static herr_t H5P__dapl_efile_pref_enc(const void *value, void **_pp, size_t *size);
120 static herr_t H5P__dapl_efile_pref_dec(const void **_pp, void *value);
121 static herr_t H5P__dapl_efile_pref_del(hid_t prop_id, const char* name, size_t size, void* value);
122 static herr_t H5P__dapl_efile_pref_copy(const char* name, size_t size, void* value);
123 static int H5P__dapl_efile_pref_cmp(const void *value1, const void *value2, size_t size);
124 static herr_t H5P__dapl_efile_pref_close(const char* name, size_t size, void* value);
125 
126 
127 /*********************/
128 /* Package Variables */
129 /*********************/
130 
131 /* Dataset access property list class library initialization object */
132 const H5P_libclass_t H5P_CLS_DACC[1] = {{
133     "dataset access",		/* Class name for debugging     */
134     H5P_TYPE_DATASET_ACCESS,    /* Class type                   */
135 
136     &H5P_CLS_LINK_ACCESS_g,	/* Parent class                 */
137     &H5P_CLS_DATASET_ACCESS_g,	/* Pointer to class             */
138     &H5P_CLS_DATASET_ACCESS_ID_g,	/* Pointer to class ID          */
139     &H5P_LST_DATASET_ACCESS_ID_g,	/* Pointer to default property list ID */
140     H5P__dacc_reg_prop,		/* Default property registration routine */
141 
142     NULL,		        /* Class creation callback      */
143     NULL,		        /* Class creation callback info */
144     NULL,		        /* Class copy callback          */
145     NULL,		        /* Class copy callback info     */
146     NULL,		        /* Class close callback         */
147     NULL 		        /* Class close callback info    */
148 }};
149 
150 
151 /*****************************/
152 /* Library Private Variables */
153 /*****************************/
154 
155 
156 /*******************/
157 /* Local Variables */
158 /*******************/
159 
160 /* Property value defaults */
161 static const H5D_append_flush_t H5D_def_append_flush_g = H5D_ACS_APPEND_FLUSH_DEF;       /* Default setting for append flush */
162 static const char *H5D_def_efile_prefix_g = H5D_ACS_EFILE_PREFIX_DEF; /* Default external file prefix string */
163 
164 
165 /*-------------------------------------------------------------------------
166  * Function:    H5P__dacc_reg_prop
167  *
168  * Purpose:     Register the dataset access property list class's
169  *              properties
170  *
171  * Return:      Non-negative on success/Negative on failure
172  *
173  * Programmer:  Neil Fortner
174  *              October 27, 2008
175  *-------------------------------------------------------------------------
176  */
177 static herr_t
H5P__dacc_reg_prop(H5P_genclass_t * pclass)178 H5P__dacc_reg_prop(H5P_genclass_t *pclass)
179 {
180     size_t rdcc_nslots = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF;      /* Default raw data chunk cache # of slots */
181     size_t rdcc_nbytes = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF;      /* Default raw data chunk cache # of bytes */
182     double rdcc_w0 = H5D_ACS_PREEMPT_READ_CHUNKS_DEF;           /* Default raw data chunk cache dirty ratio */
183     H5D_vds_view_t virtual_view = H5D_ACS_VDS_VIEW_DEF;         /* Default VDS view option */
184     hsize_t printf_gap = H5D_ACS_VDS_PRINTF_GAP_DEF;            /* Default VDS printf gap */
185     herr_t ret_value = SUCCEED;         /* Return value */
186 
187     FUNC_ENTER_STATIC
188 
189     /* Register the size of raw data chunk cache (elements) */
190     if(H5P_register_real(pclass, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots,
191              NULL, NULL, NULL, H5D_ACS_DATA_CACHE_NUM_SLOTS_ENC, H5D_ACS_DATA_CACHE_NUM_SLOTS_DEC, NULL, NULL, NULL, NULL) < 0)
192          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
193 
194     /* Register the size of raw data chunk cache(bytes) */
195     if(H5P_register_real(pclass, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes,
196              NULL, NULL, NULL, H5D_ACS_DATA_CACHE_BYTE_SIZE_ENC, H5D_ACS_DATA_CACHE_BYTE_SIZE_DEC, NULL, NULL, NULL, NULL) < 0)
197          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
198 
199     /* Register the preemption for reading chunks */
200     if(H5P_register_real(pclass, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, H5D_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0,
201              NULL, NULL, NULL, H5D_ACS_PREEMPT_READ_CHUNKS_ENC, H5D_ACS_PREEMPT_READ_CHUNKS_DEC, NULL, NULL, NULL, NULL) < 0)
202          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
203 
204     /* Register the VDS view option */
205     if(H5P_register_real(pclass, H5D_ACS_VDS_VIEW_NAME, H5D_ACS_VDS_VIEW_SIZE, &virtual_view,
206             NULL, NULL, NULL, H5D_ACS_VDS_VIEW_ENC, H5D_ACS_VDS_VIEW_DEC,
207             NULL, NULL, NULL, NULL) < 0)
208         HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
209 
210     /* Register the VDS printf gap */
211     if(H5P_register_real(pclass, H5D_ACS_VDS_PRINTF_GAP_NAME, H5D_ACS_VDS_PRINTF_GAP_SIZE, &printf_gap,
212             NULL, NULL, NULL, H5D_ACS_VDS_PRINTF_GAP_ENC, H5D_ACS_VDS_PRINTF_GAP_DEC,
213             NULL, NULL, NULL, NULL) < 0)
214         HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
215 
216     /* Register info for append flush */
217     /* (Note: this property should not have an encode/decode callback -QAK) */
218     if(H5P_register_real(pclass, H5D_ACS_APPEND_FLUSH_NAME, H5D_ACS_APPEND_FLUSH_SIZE, &H5D_def_append_flush_g,
219              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
220          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
221 
222     /* Register property for external file prefix */
223     if(H5P_register_real(pclass, H5D_ACS_EFILE_PREFIX_NAME, H5D_ACS_EFILE_PREFIX_SIZE, &H5D_def_efile_prefix_g,
224             NULL, H5D_ACS_EFILE_PREFIX_SET, H5D_ACS_EFILE_PREFIX_GET, H5D_ACS_EFILE_PREFIX_ENC, H5D_ACS_EFILE_PREFIX_DEC,
225             H5D_ACS_EFILE_PREFIX_DEL, H5D_ACS_EFILE_PREFIX_COPY, H5D_ACS_EFILE_PREFIX_CMP, H5D_ACS_EFILE_PREFIX_CLOSE) < 0)
226          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
227 
228 done:
229     FUNC_LEAVE_NOAPI(ret_value)
230 } /* end H5P__dacc_reg_prop() */
231 
232 
233 /*-------------------------------------------------------------------------
234  * Function:    H5P__dapl_efile_pref_set
235  *
236  * Purpose:     Copies an external file prefix property when it's set
237  *              for a property list
238  *
239  * Return:      SUCCEED/FAIL
240  *
241  *-------------------------------------------------------------------------
242  */
243 static herr_t
H5P__dapl_efile_pref_set(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)244 H5P__dapl_efile_pref_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
245     size_t H5_ATTR_UNUSED size, void *value)
246 {
247     FUNC_ENTER_STATIC_NOERR
248 
249     /* Sanity check */
250     HDassert(value);
251 
252     /* Copy the prefix */
253     *(char **)value = H5MM_xstrdup(*(const char **)value);
254 
255     FUNC_LEAVE_NOAPI(SUCCEED)
256 } /* end H5P__dapl_efile_pref_set() */
257 
258 
259 /*-------------------------------------------------------------------------
260  * Function:    H5P__dapl_efile_pref_get
261  *
262  * Purpose:     Copies an external file prefix property when it's retrieved
263  *              from a property list
264  *
265  * Return:      SUCCEED/FAIL
266  *
267  *-------------------------------------------------------------------------
268  */
269 static herr_t
H5P__dapl_efile_pref_get(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)270 H5P__dapl_efile_pref_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
271     size_t H5_ATTR_UNUSED size, void *value)
272 {
273     FUNC_ENTER_STATIC_NOERR
274 
275     /* Sanity check */
276     HDassert(value);
277 
278     /* Copy the prefix */
279     *(char **)value = H5MM_xstrdup(*(const char **)value);
280 
281     FUNC_LEAVE_NOAPI(SUCCEED)
282 } /* end H5P__dapl_efile_pref_get() */
283 
284 
285 /*-------------------------------------------------------------------------
286  * Function:    H5P__dapl_efile_pref_enc
287  *
288  * Purpose:     Callback routine which is called whenever the efile flags
289  *              property in the dataset access property list is
290  *              encoded.
291  *
292  * Return:      SUCCEED/FAIL
293  *
294  *-------------------------------------------------------------------------
295  */
296 static herr_t
H5P__dapl_efile_pref_enc(const void * value,void ** _pp,size_t * size)297 H5P__dapl_efile_pref_enc(const void *value, void **_pp, size_t *size)
298 {
299     const char *efile_pref = *(const char * const *)value;
300     uint8_t **pp = (uint8_t **)_pp;
301     size_t len = 0;
302     uint64_t enc_value;
303     unsigned enc_size;
304 
305     FUNC_ENTER_NOAPI_NOINIT_NOERR
306 
307     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
308 
309     /* calculate prefix length */
310     if(NULL != efile_pref)
311         len = HDstrlen(efile_pref);
312 
313     enc_value = (uint64_t)len;
314     enc_size = H5VM_limit_enc_size(enc_value);
315     HDassert(enc_size < 256);
316 
317     if(NULL != *pp) {
318         /* encode the length of the prefix */
319         *(*pp)++ = (uint8_t)enc_size;
320         UINT64ENCODE_VAR(*pp, enc_value, enc_size);
321 
322         /* encode the prefix */
323         if(NULL != efile_pref) {
324             HDmemcpy(*(char **)pp, efile_pref, len);
325             *pp += len;
326         } /* end if */
327     } /* end if */
328 
329     *size += (1 + enc_size);
330     if(NULL != efile_pref)
331         *size += len;
332 
333     FUNC_LEAVE_NOAPI(SUCCEED)
334 } /* end H5P__dapl_efile_pref_enc() */
335 
336 
337 /*-------------------------------------------------------------------------
338  * Function:    H5P__dapl_efile_pref_dec
339  *
340  * Purpose:     Callback routine which is called whenever the efile prefix
341  *              property in the dataset access property list is
342  *              decoded.
343  *
344  * Return:	    SUCCEED/FAIL
345  *
346  *-------------------------------------------------------------------------
347  */
348 static herr_t
H5P__dapl_efile_pref_dec(const void ** _pp,void * _value)349 H5P__dapl_efile_pref_dec(const void **_pp, void *_value)
350 {
351     char **efile_pref = (char **)_value;
352     const uint8_t **pp = (const uint8_t **)_pp;
353     size_t len;
354     uint64_t enc_value;                 /* Decoded property value */
355     unsigned enc_size;                  /* Size of encoded property */
356     herr_t ret_value = SUCCEED;
357 
358     FUNC_ENTER_NOAPI_NOINIT
359 
360     HDassert(pp);
361     HDassert(*pp);
362     HDassert(efile_pref);
363     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
364 
365     /* Decode the size */
366     enc_size = *(*pp)++;
367     HDassert(enc_size < 256);
368 
369     /* Decode the value */
370     UINT64DECODE_VAR(*pp, enc_value, enc_size);
371     len = (size_t)enc_value;
372 
373     if(0 != len) {
374         /* Make a copy of the user's prefix string */
375         if(NULL == (*efile_pref = (char *)H5MM_malloc(len + 1)))
376             HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix")
377         HDstrncpy(*efile_pref, *(const char **)pp, len);
378         (*efile_pref)[len] = '\0';
379 
380         *pp += len;
381     } /* end if */
382     else
383         *efile_pref = NULL;
384 
385 done:
386     FUNC_LEAVE_NOAPI(ret_value)
387 } /* end H5P__dapl_efile_pref_dec() */
388 
389 
390 /*-------------------------------------------------------------------------
391  * Function:    H5P__dapl_efile_pref_del
392  *
393  * Purpose:     Frees memory used to store the external file prefix string
394  *
395  * Return:      SUCCEED (Can't fail)
396  *
397  *-------------------------------------------------------------------------
398  */
399 static herr_t
H5P__dapl_efile_pref_del(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)400 H5P__dapl_efile_pref_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
401     size_t H5_ATTR_UNUSED size, void *value)
402 {
403     FUNC_ENTER_NOAPI_NOINIT_NOERR
404 
405     HDassert(value);
406 
407     H5MM_xfree(*(void **)value);
408 
409     FUNC_LEAVE_NOAPI(SUCCEED)
410 } /* end H5P__dapl_efile_pref_del() */
411 
412 
413 /*-------------------------------------------------------------------------
414  * Function:    H5P__dapl_efile_pref_copy
415  *
416  * Purpose:     Creates a copy of the external file prefix string
417  *
418  * Return:      SUCCEED/FAIL
419  *
420  *-------------------------------------------------------------------------
421  */
422 static herr_t
H5P__dapl_efile_pref_copy(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)423 H5P__dapl_efile_pref_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
424 {
425     FUNC_ENTER_NOAPI_NOINIT_NOERR
426 
427     HDassert(value);
428 
429     *(char **)value = H5MM_xstrdup(*(const char **)value);
430 
431     FUNC_LEAVE_NOAPI(SUCCEED)
432 } /* end H5P__dapl_efile_pref_copy() */
433 
434 
435 /*-------------------------------------------------------------------------
436  * Function:       H5P__dapl_efile_pref_cmp
437  *
438  * Purpose:        Callback routine which is called whenever the efile prefix
439  *                 property in the dataset creation property list is
440  *                 compared.
441  *
442  * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
443  *
444  *-------------------------------------------------------------------------
445  */
446 static int
H5P__dapl_efile_pref_cmp(const void * value1,const void * value2,size_t H5_ATTR_UNUSED size)447 H5P__dapl_efile_pref_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
448 {
449     const char *pref1 = *(const char * const *)value1;
450     const char *pref2 = *(const char * const *)value2;
451     int ret_value = 0;
452 
453     FUNC_ENTER_NOAPI_NOINIT_NOERR
454 
455     if(NULL == pref1 && NULL != pref2)
456         HGOTO_DONE(1);
457     if(NULL != pref1 && NULL == pref2)
458         HGOTO_DONE(-1);
459     if(NULL != pref1 && NULL != pref2)
460         ret_value = HDstrcmp(pref1, pref2);
461 
462 done:
463     FUNC_LEAVE_NOAPI(ret_value)
464 } /* end H5P__dapl_efile_pref_cmp() */
465 
466 
467 /*-------------------------------------------------------------------------
468  * Function:    H5P__dapl_efile_pref_close
469  *
470  * Purpose:     Frees memory used to store the external file prefix string
471  *
472  * Return:      SUCCEED/FAIL
473  *
474  *-------------------------------------------------------------------------
475  */
476 static herr_t
H5P__dapl_efile_pref_close(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)477 H5P__dapl_efile_pref_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
478 {
479     FUNC_ENTER_NOAPI_NOINIT_NOERR
480 
481     HDassert(value);
482 
483     H5MM_xfree(*(void **)value);
484 
485     FUNC_LEAVE_NOAPI(SUCCEED)
486 } /* end H5P__dapl_efile_pref_close() */
487 
488 
489 /*-------------------------------------------------------------------------
490  * Function:	H5Pset_chunk_cache
491  *
492  * Purpose:	Set the number of objects in the meta data cache and the
493  *		maximum number of chunks and bytes in the raw data chunk cache.
494  *      Once set, these values will override the values in the file access
495  *      property list.  Each of thhese values can be individually unset
496  *      (or not set at all) by passing the macros:
497  *      H5D_CHUNK_CACHE_NCHUNKS_DEFAULT,
498  *      H5D_CHUNK_CACHE_NSLOTS_DEFAULT, and/or
499  *      H5D_CHUNK_CACHE_W0_DEFAULT
500  *      as appropriate.
501  *
502  * 		The RDCC_W0 value should be between 0 and 1 inclusive and
503  *		indicates how much chunks that have been fully read or fully
504  *		written are favored for preemption.  A value of zero means
505  *		fully read or written chunks are treated no differently than
506  *		other chunks (the preemption is strictly LRU) while a value
507  *		of one means fully read chunks are always preempted before
508  *		other chunks.
509  *
510  * Return:	Non-negative on success/Negative on failure
511  *
512  * Programmer:	Neil Fortner
513  *              Monday, October 27, 2008
514  *
515  * Modifications:
516  *
517  *-------------------------------------------------------------------------
518  */
519 herr_t
H5Pset_chunk_cache(hid_t dapl_id,size_t rdcc_nslots,size_t rdcc_nbytes,double rdcc_w0)520 H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0)
521 {
522     H5P_genplist_t *plist;      /* Property list pointer */
523     herr_t ret_value = SUCCEED; /* return value */
524 
525     FUNC_ENTER_API(FAIL)
526     H5TRACE4("e", "izzd", dapl_id, rdcc_nslots, rdcc_nbytes, rdcc_w0);
527 
528     /* Check arguments.  Note that we allow negative values - they are
529      * considered to "unset" the property. */
530     if(rdcc_w0 > (double)1.0f)
531         HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 inclusive, or H5D_CHUNK_CACHE_W0_DEFAULT");
532 
533     /* Get the plist structure */
534     if(NULL == (plist = H5P_object_verify(dapl_id,H5P_DATASET_ACCESS)))
535         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
536 
537     /* Set sizes */
538     if(H5P_set(plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc_nslots) < 0)
539         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache number of chunks");
540     if(H5P_set(plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc_nbytes) < 0)
541         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache byte size");
542     if(H5P_set(plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc_w0) < 0)
543         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set preempt read chunks");
544 
545 done:
546     FUNC_LEAVE_API(ret_value)
547 } /* end H5Pset_chunk_cache() */
548 
549 
550 /*-------------------------------------------------------------------------
551  * Function:	H5Pget_chunk_cache
552  *
553  * Purpose:	Retrieves the maximum possible number of elements in the meta
554  *		data cache and the maximum possible number of elements and
555  *		bytes and the RDCC_W0 value in the raw data chunk cache.  Any
556  *		(or all) arguments may be null pointers in which case the
557  *		corresponding datum is not returned.  If these properties have
558  *      not been set on this property list, the default values for a
559  *      file access property list are returned.
560  *
561  * Return:	Non-negative on success/Negative on failure
562  *
563  * Programmer:	Neil Fortner
564  *              Monday, October 27, 2008
565  *
566  * Modifications:
567  *
568  *-------------------------------------------------------------------------
569  */
570 herr_t
H5Pget_chunk_cache(hid_t dapl_id,size_t * rdcc_nslots,size_t * rdcc_nbytes,double * rdcc_w0)571 H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots, size_t *rdcc_nbytes, double *rdcc_w0)
572 {
573     H5P_genplist_t *plist;      /* Property list pointer */
574     H5P_genplist_t *def_plist;  /* Default file access property list */
575     herr_t ret_value = SUCCEED; /* return value */
576 
577     FUNC_ENTER_API(FAIL)
578     H5TRACE4("e", "i*z*z*d", dapl_id, rdcc_nslots, rdcc_nbytes, rdcc_w0);
579 
580     /* Get the plist structure */
581     if (NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS)))
582         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
583 
584     /* Get default file access plist */
585     if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
586         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for default fapl ID");
587 
588     /* Get the properties.  If a property is set to the default value, the value
589      * from the default fapl is used. */
590     if (rdcc_nslots) {
591         if (H5P_get(plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
592             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots");
593         if (*rdcc_nslots == H5D_CHUNK_CACHE_NSLOTS_DEFAULT)
594             if (H5P_get(def_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
595                 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get default data cache number of slots");
596     } /* end if */
597     if (rdcc_nbytes) {
598         if (H5P_get(plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
599             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache byte size");
600         if (*rdcc_nbytes == H5D_CHUNK_CACHE_NBYTES_DEFAULT)
601             if (H5P_get(def_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
602                 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get default data cache byte size");
603     } /* end if */
604     if (rdcc_w0) {
605         if (H5P_get(plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, rdcc_w0) < 0)
606             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get preempt read chunks");
607         if (*rdcc_w0 < 0)
608             if (H5P_get(def_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, rdcc_w0) < 0)
609                 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get default preempt read chunks");
610     } /* end if */
611 
612 done:
613     FUNC_LEAVE_API(ret_value)
614 } /* end H5Pget_chunk_cache() */
615 
616 
617 /*-------------------------------------------------------------------------
618  * Function:       H5P__encode_chunk_cache_nslots
619  *
620  * Purpose:        Encode the rdcc_nslots parameter to a serialized
621  *                 property list.  Similar to H5P__encode_size_t except
622  *                 the value of 255 for the enc_size field is reserved to
623  *                 indicate H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF, in which
624  *                 nothing further is encoded.
625  *
626  * Return:         Success:     Non-negative
627  *                 Failure:     Negative
628  *
629  * Programmer:     Neil Fortner
630  *                 Wednesday, January 23, 2013
631  *
632  *-------------------------------------------------------------------------
633  */
634 static herr_t
H5P__encode_chunk_cache_nslots(const void * value,void ** _pp,size_t * size)635 H5P__encode_chunk_cache_nslots(const void *value, void **_pp, size_t *size)
636 {
637     uint64_t enc_value;     /* Property value to encode */
638     uint8_t **pp = (uint8_t **)_pp;
639     unsigned enc_size;      /* Size of encoded property */
640 
641     FUNC_ENTER_PACKAGE_NOERR
642 
643     /* Sanity checks */
644     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
645     HDassert(size);
646 
647     /* Determine if this is the default value, in which case only encode
648      * enc_size (as 255).  Also set size needed for encoding. */
649     if(*(const size_t *)value == H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF) {
650         enc_size = 0;
651         *size += 1;
652     } /* end if */
653     else {
654         enc_value = (uint64_t)*(const size_t *)value;
655         enc_size = H5VM_limit_enc_size(enc_value);
656         HDassert(enc_size > 0);
657         *size += (1 + enc_size);
658     } /* end else */
659 
660     HDassert(enc_size < 256);
661 
662     if(NULL != *pp) {
663         /* Encode the size */
664         *(*pp)++ = (uint8_t)enc_size;
665 
666         /* Encode the value if necessary */
667         if(enc_size != 0) {
668             UINT64ENCODE_VAR(*pp, enc_value, enc_size);
669         } /* end if */
670     } /* end if */
671 
672     FUNC_LEAVE_NOAPI(SUCCEED)
673 } /* end H5P__encode_chunk_cache_nslots() */
674 
675 
676 /*-------------------------------------------------------------------------
677  * Function:       H5P__decode_chunk_cache_nslots
678  *
679  * Purpose:        Decode the rdcc_nslots parameter from a serialized
680  *                 property list.  Similar to H5P__decode_size_t except
681  *                 the value of 255 for the enc_size field is reserved to
682  *                 indicate H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF, in which
683  *                 nothing further needs to be decoded.
684  *
685  * Return:         Success:     Non-negative
686  *                 Failure:     Negative
687  *
688  * Programmer:     Neil Fortner
689  *                 Wednesday, January 23, 2013
690  *
691  *-------------------------------------------------------------------------
692  */
693 static herr_t
H5P__decode_chunk_cache_nslots(const void ** _pp,void * _value)694 H5P__decode_chunk_cache_nslots(const void **_pp, void *_value)
695 {
696     size_t *value = (size_t *)_value;   /* Property value to return */
697     const uint8_t **pp = (const uint8_t **)_pp;
698     uint64_t enc_value;                 /* Decoded property value */
699     unsigned enc_size;                  /* Size of encoded property */
700 
701     FUNC_ENTER_PACKAGE_NOERR
702 
703     /* Sanity check */
704     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
705     HDassert(pp);
706     HDassert(*pp);
707     HDassert(value);
708 
709     /* Decode the size */
710     enc_size = *(*pp)++;
711     HDassert(enc_size < 256);
712 
713     /* Determine if enc_size indicates that this is the default value, in which
714      * case set value to H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF and return */
715     if(enc_size == 0)
716         *value = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF;
717     else {
718         /* Decode the value */
719         UINT64DECODE_VAR(*pp, enc_value, enc_size);
720         H5_CHECKED_ASSIGN(*value, uint64_t, enc_value, size_t);
721     } /* end else */
722 
723     FUNC_LEAVE_NOAPI(SUCCEED)
724 } /* end H5P__decode_chunk_cache_nslots() */
725 
726 
727 /*-------------------------------------------------------------------------
728  * Function:       H5P__encode_chunk_cache_nbytes
729  *
730  * Purpose:        Encode the rdcc_nbytes parameter to a serialized
731  *                 property list.  Similar to H5P__encode_size_t except
732  *                 the value of 255 for the enc_size field is reserved to
733  *                 indicate H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF, in which
734  *                 nothing further is encoded.
735  *
736  * Return:         Success:     Non-negative
737  *                 Failure:     Negative
738  *
739  * Programmer:     Neil Fortner
740  *                 Wednesday, January 23, 2013
741  *
742  *-------------------------------------------------------------------------
743  */
744 static herr_t
H5P__encode_chunk_cache_nbytes(const void * value,void ** _pp,size_t * size)745 H5P__encode_chunk_cache_nbytes(const void *value, void **_pp, size_t *size)
746 {
747     uint64_t enc_value;     /* Property value to encode */
748     uint8_t **pp = (uint8_t **)_pp;
749     unsigned enc_size;      /* Size of encoded property */
750 
751     FUNC_ENTER_PACKAGE_NOERR
752 
753     /* Sanity checks */
754     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
755     HDassert(size);
756 
757     /* Determine if this is the default value, in which case only encode
758      * enc_size (as 255).  Also set size needed for encoding. */
759     if(*(const size_t *)value == H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF) {
760         enc_size = 0;
761         *size += 1;
762     } /* end if */
763     else {
764         enc_value = (uint64_t)*(const size_t *)value;
765         enc_size = H5VM_limit_enc_size(enc_value);
766         HDassert(enc_size > 0);
767         *size += (1 + enc_size);
768     } /* end else */
769 
770     HDassert(enc_size < 256);
771 
772     if(NULL != *pp) {
773         /* Encode the size */
774         *(*pp)++ = (uint8_t)enc_size;
775 
776         /* Encode the value if necessary */
777         if(enc_size != 0) {
778             UINT64ENCODE_VAR(*pp, enc_value, enc_size);
779         } /* end if */
780     } /* end if */
781 
782     FUNC_LEAVE_NOAPI(SUCCEED)
783 } /* end H5P__encode_chunk_cache_nbytes() */
784 
785 
786 /*-------------------------------------------------------------------------
787  * Function:       H5P__decode_chunk_cache_nbytes
788  *
789  * Purpose:        Decode the rdcc_nbytes parameter from a serialized
790  *                 property list.  Similar to H5P__decode_size_t except
791  *                 the value of 255 for the enc_size field is reserved to
792  *                 indicate H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF, in which
793  *                 nothing further needs to be decoded.
794  *
795  * Return:         Success:     Non-negative
796  *                 Failure:     Negative
797  *
798  * Programmer:     Neil Fortner
799  *                 Wednesday, January 23, 2013
800  *
801  *-------------------------------------------------------------------------
802  */
803 static herr_t
H5P__decode_chunk_cache_nbytes(const void ** _pp,void * _value)804 H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value)
805 {
806     size_t *value = (size_t *)_value;   /* Property value to return */
807     const uint8_t **pp = (const uint8_t **)_pp;
808     uint64_t enc_value;                 /* Decoded property value */
809     unsigned enc_size;                  /* Size of encoded property */
810 
811     FUNC_ENTER_PACKAGE_NOERR
812 
813     /* Sanity check */
814     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
815     HDassert(pp);
816     HDassert(*pp);
817     HDassert(value);
818 
819     /* Decode the size */
820     enc_size = *(*pp)++;
821     HDassert(enc_size < 256);
822 
823     /* Determine if enc_size indicates that this is the default value, in which
824      * case set value to H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF and return */
825     if(enc_size == 0)
826         *value = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF;
827     else {
828         /* Decode the value */
829         UINT64DECODE_VAR(*pp, enc_value, enc_size);
830         H5_CHECKED_ASSIGN(*value, uint64_t, enc_value, size_t);
831     } /* end else */
832 
833     FUNC_LEAVE_NOAPI(SUCCEED)
834 } /* end H5P__decode_chunk_cache_nbytes() */
835 
836 
837 /*-------------------------------------------------------------------------
838  * Function:    H5Pset_virtual_view
839  *
840  * Purpose:     Takes the access property list for the virtual dataset,
841  *              dapl_id, and the flag, view, and sets the VDS view
842  *              according to the flag value.  The view will include all
843  *              data before the first missing mapped data found if the
844  *              flag is set to H5D_VDS_FIRST_MISSING or to include all
845  *              available mapped data if the flag is set to
846  *              H5D_VDS_LAST_AVAIALBLE.  Missing mapped data will be
847  *              filled with the fill value according to the VDS creation
848  *              property settings.  For VDS with unlimited mappings, the
849  *              view defines the extent.
850  *
851  * Return:      Non-negative on success/Negative on failure
852  *
853  * Programmer:  Neil Fortner
854  *              May 4, 2015
855  *
856  *-------------------------------------------------------------------------
857  */
858 herr_t
H5Pset_virtual_view(hid_t plist_id,H5D_vds_view_t view)859 H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view)
860 {
861     H5P_genplist_t *plist;      /* Property list pointer */
862     herr_t ret_value = SUCCEED; /* return value */
863 
864     FUNC_ENTER_API(FAIL)
865     H5TRACE2("e", "iDv", plist_id, view);
866 
867     /* Check argument */
868     if((view != H5D_VDS_FIRST_MISSING) && (view != H5D_VDS_LAST_AVAILABLE))
869         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid bounds option")
870 
871     /* Get the plist structure */
872     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
873         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
874 
875     /* Update property list */
876     if(H5P_set(plist, H5D_ACS_VDS_VIEW_NAME, &view) < 0)
877         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
878 
879 done:
880     FUNC_LEAVE_API(ret_value)
881 } /* end H5Pset_virtual_view() */
882 
883 
884 /*-------------------------------------------------------------------------
885  * Function:    H5Pget_virtual_view
886  *
887  * Purpose:     Takes the access property list for the virtual dataset,
888  *              dapl_id, and gets the flag, view, set by the
889  *              H5Pset_virtual_view call.  The possible values of view are
890  *              H5D_VDS_FIRST_MISSING or H5D_VDS_LAST_AVAIALBLE.
891  *
892  * Return:      Non-negative on success/Negative on failure
893  *
894  * Programmer:  Neil Fortner
895  *              May 4, 2015
896  *
897  *-------------------------------------------------------------------------
898  */
899 herr_t
H5Pget_virtual_view(hid_t plist_id,H5D_vds_view_t * view)900 H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view)
901 {
902     H5P_genplist_t *plist;      /* Property list pointer */
903     herr_t ret_value = SUCCEED; /* Return value */
904 
905     FUNC_ENTER_API(FAIL)
906     H5TRACE2("e", "i*Dv", plist_id, view);
907 
908     /* Get the plist structure */
909     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
910         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
911 
912     /* Get value from property list */
913     if(view)
914         if(H5P_get(plist, H5D_ACS_VDS_VIEW_NAME, view) < 0)
915             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value")
916 
917 done:
918     FUNC_LEAVE_API(ret_value)
919 } /* end H5Pget_virtual_view() */
920 
921 
922 /*-------------------------------------------------------------------------
923  * Function:    H5P__dacc_vds_view_enc
924  *
925  * Purpose:     Callback routine which is called whenever the vds view
926  *              property in the dataset access property list is encoded.
927  *
928  * Return:      Success:        Non-negative
929  *              Failure:        Negative
930  *
931  * Programmer:  Neil Fortner
932  *              Tuesday, May 5, 2015
933  *
934  *-------------------------------------------------------------------------
935  */
936 static herr_t
H5P__dacc_vds_view_enc(const void * value,void ** _pp,size_t * size)937 H5P__dacc_vds_view_enc(const void *value, void **_pp, size_t *size)
938 {
939     const H5D_vds_view_t *view = (const H5D_vds_view_t *)value; /* Create local alias for values */
940     uint8_t **pp = (uint8_t **)_pp;
941 
942     FUNC_ENTER_STATIC_NOERR
943 
944     /* Sanity check */
945     HDassert(view);
946     HDassert(size);
947 
948     if(NULL != *pp)
949         /* Encode EDC property */
950         *(*pp)++ = (uint8_t)*view;
951 
952     /* Size of EDC property */
953     (*size)++;
954 
955     FUNC_LEAVE_NOAPI(SUCCEED)
956 } /* end H5P__dacc_vds_view_enc() */
957 
958 
959 /*-------------------------------------------------------------------------
960  * Function:    H5P__dacc_vds_view_dec
961  *
962  * Purpose:     Callback routine which is called whenever the vds view
963  *              property in the dataset access property list is encoded.
964  *
965  * Return:      Success:        Non-negative
966  *              Failure:        Negative
967  *
968  * Programmer:  Neil Fortner
969  *              Tuesday, May 5, 2015
970  *
971  *-------------------------------------------------------------------------
972  */
973 static herr_t
H5P__dacc_vds_view_dec(const void ** _pp,void * _value)974 H5P__dacc_vds_view_dec(const void **_pp, void *_value)
975 {
976     H5D_vds_view_t *view = (H5D_vds_view_t *)_value;
977     const uint8_t **pp = (const uint8_t **)_pp;
978 
979     FUNC_ENTER_STATIC_NOERR
980 
981     /* Sanity checks */
982     HDassert(pp);
983     HDassert(*pp);
984     HDassert(view);
985 
986     /* Decode EDC property */
987     *view = (H5D_vds_view_t)*(*pp)++;
988 
989     FUNC_LEAVE_NOAPI(SUCCEED)
990 } /* end H5P__dacc_vds_view_dec() */
991 
992 
993 /*-------------------------------------------------------------------------
994  * Function:    H5Pset_virtual_printf_gap
995  *
996  * Purpose:     Sets the access property list for the virtual dataset,
997  *              dapl_id, to instruct the library to stop looking for the
998  *              mapped data stored in the files and/or datasets with the
999  *              printf-style names after not finding gap_size files and/or
1000  *              datasets.  The found source files and datasets will
1001  *              determine the extent of the unlimited VDS with the printf
1002  *              -style mappings.
1003  *
1004  *              For example, if regularly spaced blocks of VDS are mapped
1005  *              to datasets with the names d-1, d-2, d-3, ..., d-N, ...,
1006  *              and d-2 dataset is missing and gap_size is set to 0, then
1007  *              VDS will contain only data found in d-1.  If d-2 and d-3
1008  *              are missing and gap_size is set to 2, then VDS will
1009  *              contain the data from d-1, d-3, ..., d-N, ....  The blocks
1010  *              that are mapped to d-2 and d-3 will be filled according to
1011  *              the VDS fill value setting.
1012  *
1013  * Return:      Non-negative on success/Negative on failure
1014  *
1015  * Programmer:  Neil Fortner
1016  *              May 21, 2015
1017  *
1018  *-------------------------------------------------------------------------
1019  */
1020 herr_t
H5Pset_virtual_printf_gap(hid_t plist_id,hsize_t gap_size)1021 H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size)
1022 {
1023     H5P_genplist_t *plist;      /* Property list pointer */
1024     herr_t ret_value = SUCCEED; /* Return value */
1025 
1026     FUNC_ENTER_API(FAIL)
1027     H5TRACE2("e", "ih", plist_id, gap_size);
1028 
1029     /* Check argument */
1030     if(gap_size == HSIZE_UNDEF)
1031         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid printf gap size")
1032 
1033     /* Get the plist structure */
1034     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
1035         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1036 
1037     /* Update property list */
1038     if(H5P_set(plist, H5D_ACS_VDS_PRINTF_GAP_NAME, &gap_size) < 0)
1039         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
1040 
1041 done:
1042     FUNC_LEAVE_API(ret_value)
1043 } /* end H5Pset_virtual_printf_gap() */
1044 
1045 
1046 /*-------------------------------------------------------------------------
1047  * Function:    H5Pget_virtual_printf_gap
1048  *
1049  * Purpose:     Gets the maximum number of missing printf-style files
1050  *              and/or datasets for determining the extent of the
1051  *              unlimited VDS, gap_size, using the access property list
1052  *              for the virtual dataset, dapl_id.  The default library
1053  *              value for gap_size is 0.
1054  *
1055  * Return:      Non-negative on success/Negative on failure
1056  *
1057  * Programmer:  Neil Fortner
1058  *              May 21, 2015
1059  *
1060  *-------------------------------------------------------------------------
1061  */
1062 herr_t
H5Pget_virtual_printf_gap(hid_t plist_id,hsize_t * gap_size)1063 H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size)
1064 {
1065     H5P_genplist_t *plist;      /* Property list pointer */
1066     herr_t ret_value = SUCCEED; /* Return value */
1067 
1068     FUNC_ENTER_API(FAIL)
1069     H5TRACE2("e", "i*h", plist_id, gap_size);
1070 
1071     /* Get the plist structure */
1072     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
1073         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1074 
1075     /* Get value from property list */
1076     if(gap_size)
1077         if(H5P_get(plist, H5D_ACS_VDS_PRINTF_GAP_NAME, gap_size) < 0)
1078             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value")
1079 
1080 done:
1081     FUNC_LEAVE_API(ret_value)
1082 } /* end H5Pget_virtual_printf_gap() */
1083 
1084 
1085 /*-------------------------------------------------------------------------
1086  * Function:	H5Pset_append_flush
1087  *
1088  * Purpose:	Sets the boundary, callback function, and user data in the
1089  *		property list.
1090  *		"ndims": number of array elements for boundary
1091  *		"boundary": used to determine whether the current dimension hits
1092  *			  a boundary; if so, invoke the callback function and
1093  *			  flush the dataset.
1094  *		"func": the callback function to invoke when the boundary is hit
1095  *		"udata": the user data to pass as parameter with the callback function
1096  *
1097  * Return:	Non-negative on success/Negative on failure
1098  *
1099  * Programmer:	Vailin Choi; Dec 2013
1100  *
1101  *-------------------------------------------------------------------------
1102  */
1103 herr_t
H5Pset_append_flush(hid_t plist_id,unsigned ndims,const hsize_t * boundary,H5D_append_cb_t func,void * udata)1104 H5Pset_append_flush(hid_t plist_id, unsigned ndims, const hsize_t *boundary, H5D_append_cb_t func, void *udata)
1105 {
1106     H5P_genplist_t *plist;      	/* Property list pointer */
1107     H5D_append_flush_t info;            /* Property for append flush parameters */
1108     unsigned u;				/* Local index variable */
1109     herr_t ret_value = SUCCEED;   	/* Return value */
1110 
1111     FUNC_ENTER_API(FAIL)
1112     H5TRACE5("e", "iIu*hx*x", plist_id, ndims, boundary, func, udata);
1113 
1114     /* Check arguments */
1115     if(0 == ndims)
1116         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality cannot be zero")
1117     if(ndims > H5S_MAX_RANK)
1118         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality is too large")
1119     if(!boundary)
1120         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no boundary dimensions specified")
1121 
1122     /* Check if the callback function is NULL and the user data is non-NULL.
1123      * This is almost certainly an error as the user data will not be used. */
1124     if(!func && udata)
1125         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
1126 
1127     /* Get the plist structure */
1128     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
1129         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1130 
1131     /* Set up values */
1132     info.ndims = ndims;
1133     info.func = func;
1134     info.udata = udata;
1135 
1136     HDmemset(info.boundary, 0, sizeof(info.boundary));
1137     /* boundary can be 0 to indicate no boundary is set */
1138     for(u = 0; u < ndims; u++) {
1139         if(boundary[u] != (boundary[u] & 0xffffffff)) /* negative value (including H5S_UNLIMITED) */
1140             HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "all boundary dimensions must be less than 2^32")
1141         info.boundary[u] = boundary[u]; /* Store user's boundary dimensions */
1142     } /* end for */
1143 
1144     /* Set values */
1145     if(H5P_set(plist, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
1146         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set append flush")
1147 
1148 done:
1149     FUNC_LEAVE_API(ret_value)
1150 } /* H5Pset_append_flush() */
1151 
1152 
1153 /*-------------------------------------------------------------------------
1154  * Function:	H5Pget_append_flush()
1155  *
1156  * Purpose:	Retrieves the boundary, callback function and user data set in
1157  *		property list.
1158  *		Note that the # of boundary sizes to retrieve will not exceed
1159  *		the parameter "ndims" and the ndims set previously via
1160  *		H5Pset_append_flush().
1161  *
1162  * Return:	Non-negative on success/Negative on failure
1163  *
1164  * Programmer:	Vailin Choi; Dec 2013
1165  *
1166  *-------------------------------------------------------------------------
1167  */
1168 herr_t
H5Pget_append_flush(hid_t plist_id,unsigned ndims,hsize_t boundary[],H5D_append_cb_t * func,void ** udata)1169 H5Pget_append_flush(hid_t plist_id, unsigned ndims, hsize_t boundary[], H5D_append_cb_t *func, void **udata)
1170 {
1171     H5P_genplist_t *plist;      /* property list pointer */
1172     H5D_append_flush_t  info;
1173     unsigned u;			/* local index variable */
1174     herr_t ret_value = SUCCEED; /* return value */
1175 
1176     FUNC_ENTER_API(FAIL)
1177     H5TRACE5("e", "iIu*h*x**x", plist_id, ndims, boundary, func, udata);
1178 
1179     /* Get the plist structure */
1180     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
1181         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1182 
1183     /* Retrieve info for append flush */
1184     if(H5P_get(plist, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
1185         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object flush callback")
1186 
1187     /* Assign return values */
1188     if(boundary) {
1189 	HDmemset(boundary, 0, ndims * sizeof(hsize_t));
1190 	if(info.ndims > 0)
1191 	    for(u = 0; u < info.ndims && u < ndims; u++)
1192 		boundary[u] = info.boundary[u];
1193     } /* end if */
1194     if(func)
1195 	*func = info.func;
1196     if(udata)
1197 	*udata = info.udata;
1198 
1199 done:
1200     FUNC_LEAVE_API(ret_value)
1201 } /* H5Pget_append_flush() */
1202 
1203 
1204 /*-------------------------------------------------------------------------
1205  * Function:    H5Pset_efile_prefix
1206  *
1207  * Purpose:     Set a prefix to be used for any external files.
1208  *
1209  *              If the prefix starts with ${ORIGIN}, this will be replaced by
1210  *              the absolute path of the directory of the HDF5 file containing
1211  *              the dataset.
1212  *
1213  *              If the prefix is ".", no prefix will be applied.
1214  *
1215  *              This property can be overwritten by the environment variable
1216  *              HDF5_EXTFILE_PREFIX.
1217  *
1218  * Return:	Non-negative on success/Negative on failure
1219  *
1220  *-------------------------------------------------------------------------
1221  */
1222 herr_t
H5Pset_efile_prefix(hid_t plist_id,const char * prefix)1223 H5Pset_efile_prefix(hid_t plist_id, const char *prefix)
1224 {
1225     H5P_genplist_t *plist;              /* Property list pointer */
1226     herr_t ret_value = SUCCEED;         /* Return value */
1227 
1228     FUNC_ENTER_API(FAIL)
1229     H5TRACE2("e", "i*s", plist_id, prefix);
1230 
1231     /* Get the plist structure */
1232     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
1233         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1234 
1235     /* Set prefix */
1236     if(H5P_set(plist, H5D_ACS_EFILE_PREFIX_NAME, &prefix) < 0)
1237         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set prefix info")
1238 
1239 done:
1240     FUNC_LEAVE_API(ret_value)
1241 } /* end H5Pset_efile_prefix() */
1242 
1243 
1244 /*-------------------------------------------------------------------------
1245  * Function:    H5Pget_efile_prefix
1246  *
1247  * Purpose:	Gets the prefix to be used for any external files.
1248  *
1249  *              If the pointer is not NULL, it points to a user-allocated
1250  *              buffer.
1251  *
1252  * Return:	Non-negative on success/Negative on failure
1253  *
1254  *-------------------------------------------------------------------------
1255  */
1256 ssize_t
H5Pget_efile_prefix(hid_t plist_id,char * prefix,size_t size)1257 H5Pget_efile_prefix(hid_t plist_id, char *prefix, size_t size)
1258 {
1259     H5P_genplist_t *plist;              /* Property list pointer */
1260     char *my_prefix;                    /* Library's copy of the prefix */
1261     size_t	len;                    /* Length of prefix string */
1262     ssize_t 	ret_value;              /* Return value */
1263 
1264     FUNC_ENTER_API(FAIL)
1265     H5TRACE3("Zs", "i*sz", plist_id, prefix, size);
1266 
1267     /* Get the plist structure */
1268     if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
1269         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1270 
1271     /* Get the current prefix */
1272     if(H5P_peek(plist, H5D_ACS_EFILE_PREFIX_NAME, &my_prefix) < 0)
1273         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file prefix")
1274 
1275     /* Check for prefix being set */
1276     if(my_prefix) {
1277         /* Copy to user's buffer, if given */
1278         len = HDstrlen(my_prefix);
1279         if(prefix) {
1280             HDstrncpy(prefix, my_prefix, MIN(len + 1, size));
1281             if(len >= size)
1282                 prefix[size - 1] = '\0';
1283         } /* end if */
1284     } /* end if */
1285     else
1286         len = 0;
1287 
1288     /* Set return value */
1289     ret_value = (ssize_t)len;
1290 
1291 done:
1292     FUNC_LEAVE_API(ret_value)
1293 } /* end H5Pget_efile_prefix() */
1294 
1295