Coverage Report

Created: 2026-01-17 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Pdapl.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:        H5Pdapl.c
16
 *
17
 * Purpose:        Dataset access property list class routines
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5Pmodule.h" /* This source code file is part of the H5P module */
27
28
/***********/
29
/* Headers */
30
/***********/
31
#include "H5private.h"   /* Generic Functions                        */
32
#include "H5Dprivate.h"  /* Datasets                                 */
33
#include "H5Eprivate.h"  /* Error handling                           */
34
#include "H5Fprivate.h"  /* Files                                    */
35
#include "H5Iprivate.h"  /* IDs                                      */
36
#include "H5MMprivate.h" /* Memory management                        */
37
#include "H5Ppkg.h"      /* Property lists                           */
38
#include "H5VMprivate.h" /* Vector Functions                         */
39
40
/****************/
41
/* Local Macros */
42
/****************/
43
44
/* ========= Dataset Access properties ============ */
45
/* Definitions for size of raw data chunk cache(slots) */
46
1
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE sizeof(size_t)
47
1
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF  H5D_CHUNK_CACHE_NSLOTS_DEFAULT
48
1
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_ENC  H5P__encode_chunk_cache_nslots
49
1
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_DEC  H5P__decode_chunk_cache_nslots
50
/* Definition for size of raw data chunk cache(bytes) */
51
1
#define H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE sizeof(size_t)
52
1
#define H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF  H5D_CHUNK_CACHE_NBYTES_DEFAULT
53
1
#define H5D_ACS_DATA_CACHE_BYTE_SIZE_ENC  H5P__encode_chunk_cache_nbytes
54
1
#define H5D_ACS_DATA_CACHE_BYTE_SIZE_DEC  H5P__decode_chunk_cache_nbytes
55
/* Definition for preemption read chunks first */
56
1
#define H5D_ACS_PREEMPT_READ_CHUNKS_SIZE sizeof(double)
57
1
#define H5D_ACS_PREEMPT_READ_CHUNKS_DEF  H5D_CHUNK_CACHE_W0_DEFAULT
58
1
#define H5D_ACS_PREEMPT_READ_CHUNKS_ENC  H5P__encode_double
59
1
#define H5D_ACS_PREEMPT_READ_CHUNKS_DEC  H5P__decode_double
60
/* Definitions for VDS view option */
61
1
#define H5D_ACS_VDS_VIEW_SIZE sizeof(H5D_vds_view_t)
62
1
#define H5D_ACS_VDS_VIEW_DEF  H5D_VDS_LAST_AVAILABLE
63
1
#define H5D_ACS_VDS_VIEW_ENC  H5P__dacc_vds_view_enc
64
1
#define H5D_ACS_VDS_VIEW_DEC  H5P__dacc_vds_view_dec
65
/* Definitions for VDS printf gap */
66
1
#define H5D_ACS_VDS_PRINTF_GAP_SIZE sizeof(hsize_t)
67
1
#define H5D_ACS_VDS_PRINTF_GAP_DEF  (hsize_t)0
68
1
#define H5D_ACS_VDS_PRINTF_GAP_ENC  H5P__encode_hsize_t
69
1
#define H5D_ACS_VDS_PRINTF_GAP_DEC  H5P__decode_hsize_t
70
/* Definitions for VDS file prefix */
71
1
#define H5D_ACS_VDS_PREFIX_SIZE  sizeof(char *)
72
#define H5D_ACS_VDS_PREFIX_DEF   NULL /*default is no prefix */
73
1
#define H5D_ACS_VDS_PREFIX_SET   H5P__dapl_vds_file_pref_set
74
1
#define H5D_ACS_VDS_PREFIX_GET   H5P__dapl_vds_file_pref_get
75
1
#define H5D_ACS_VDS_PREFIX_ENC   H5P__dapl_vds_file_pref_enc
76
1
#define H5D_ACS_VDS_PREFIX_DEC   H5P__dapl_vds_file_pref_dec
77
1
#define H5D_ACS_VDS_PREFIX_DEL   H5P__dapl_vds_file_pref_del
78
1
#define H5D_ACS_VDS_PREFIX_COPY  H5P__dapl_vds_file_pref_copy
79
1
#define H5D_ACS_VDS_PREFIX_CMP   H5P__dapl_vds_file_pref_cmp
80
1
#define H5D_ACS_VDS_PREFIX_CLOSE H5P__dapl_vds_file_pref_close
81
/* Definition for append flush */
82
1
#define H5D_ACS_APPEND_FLUSH_SIZE sizeof(H5D_append_flush_t)
83
#define H5D_ACS_APPEND_FLUSH_DEF                                                                             \
84
    {                                                                                                        \
85
        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}, \
86
            NULL, NULL                                                                                       \
87
    }
88
/* Definitions for external file prefix */
89
1
#define H5D_ACS_EFILE_PREFIX_SIZE  sizeof(char *)
90
#define H5D_ACS_EFILE_PREFIX_DEF   NULL /*default is no prefix */
91
1
#define H5D_ACS_EFILE_PREFIX_SET   H5P__dapl_efile_pref_set
92
1
#define H5D_ACS_EFILE_PREFIX_GET   H5P__dapl_efile_pref_get
93
1
#define H5D_ACS_EFILE_PREFIX_ENC   H5P__dapl_efile_pref_enc
94
1
#define H5D_ACS_EFILE_PREFIX_DEC   H5P__dapl_efile_pref_dec
95
1
#define H5D_ACS_EFILE_PREFIX_DEL   H5P__dapl_efile_pref_del
96
1
#define H5D_ACS_EFILE_PREFIX_COPY  H5P__dapl_efile_pref_copy
97
1
#define H5D_ACS_EFILE_PREFIX_CMP   H5P__dapl_efile_pref_cmp
98
1
#define H5D_ACS_EFILE_PREFIX_CLOSE H5P__dapl_efile_pref_close
99
100
/* Definitions for use of VDS mapping spatial tree */
101
1
#define H5D_ACS_USE_TREE_SIZE sizeof(bool)
102
#define H5D_ACS_USE_TREE_DEF  true
103
1
#define H5D_ACS_USE_TREE_ENC  H5P__encode_bool
104
1
#define H5D_ACS_USE_TREE_DEC  H5P__decode_bool
105
106
/******************/
107
/* Local Typedefs */
108
/******************/
109
110
/********************/
111
/* Package Typedefs */
112
/********************/
113
114
/********************/
115
/* Local Prototypes */
116
/********************/
117
118
/* Property class callbacks */
119
static herr_t H5P__dacc_reg_prop(H5P_genclass_t *pclass);
120
static herr_t H5P__encode_chunk_cache_nslots(const void *value, void **_pp, size_t *size);
121
static herr_t H5P__decode_chunk_cache_nslots(const void **_pp, void *_value);
122
static herr_t H5P__encode_chunk_cache_nbytes(const void *value, void **_pp, size_t *size);
123
static herr_t H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value);
124
125
/* Property list callbacks */
126
static herr_t H5P__dacc_vds_view_enc(const void *value, void **pp, size_t *size);
127
static herr_t H5P__dacc_vds_view_dec(const void **pp, void *value);
128
static herr_t H5P__dapl_vds_file_pref_set(hid_t prop_id, const char *name, size_t size, void *value);
129
static herr_t H5P__dapl_vds_file_pref_get(hid_t prop_id, const char *name, size_t size, void *value);
130
static herr_t H5P__dapl_vds_file_pref_enc(const void *value, void **_pp, size_t *size);
131
static herr_t H5P__dapl_vds_file_pref_dec(const void **_pp, void *value);
132
static herr_t H5P__dapl_vds_file_pref_del(hid_t prop_id, const char *name, size_t size, void *value);
133
static herr_t H5P__dapl_vds_file_pref_copy(const char *name, size_t size, void *value);
134
static int    H5P__dapl_vds_file_pref_cmp(const void *value1, const void *value2, size_t size);
135
static herr_t H5P__dapl_vds_file_pref_close(const char *name, size_t size, void *value);
136
137
/* Property list callbacks */
138
static herr_t H5P__dapl_efile_pref_set(hid_t prop_id, const char *name, size_t size, void *value);
139
static herr_t H5P__dapl_efile_pref_get(hid_t prop_id, const char *name, size_t size, void *value);
140
static herr_t H5P__dapl_efile_pref_enc(const void *value, void **_pp, size_t *size);
141
static herr_t H5P__dapl_efile_pref_dec(const void **_pp, void *value);
142
static herr_t H5P__dapl_efile_pref_del(hid_t prop_id, const char *name, size_t size, void *value);
143
static herr_t H5P__dapl_efile_pref_copy(const char *name, size_t size, void *value);
144
static int    H5P__dapl_efile_pref_cmp(const void *value1, const void *value2, size_t size);
145
static herr_t H5P__dapl_efile_pref_close(const char *name, size_t size, void *value);
146
147
/*********************/
148
/* Package Variables */
149
/*********************/
150
151
/* Dataset access property list class library initialization object */
152
const H5P_libclass_t H5P_CLS_DACC[1] = {{
153
    "dataset access",        /* Class name for debugging     */
154
    H5P_TYPE_DATASET_ACCESS, /* Class type                   */
155
156
    &H5P_CLS_LINK_ACCESS_g,       /* Parent class                 */
157
    &H5P_CLS_DATASET_ACCESS_g,    /* Pointer to class             */
158
    &H5P_CLS_DATASET_ACCESS_ID_g, /* Pointer to class ID          */
159
    &H5P_LST_DATASET_ACCESS_ID_g, /* Pointer to default property list ID */
160
    H5P__dacc_reg_prop,           /* Default property registration routine */
161
162
    NULL, /* Class creation callback      */
163
    NULL, /* Class creation callback info */
164
    NULL, /* Class copy callback          */
165
    NULL, /* Class copy callback info     */
166
    NULL, /* Class close callback         */
167
    NULL  /* Class close callback info    */
168
}};
169
170
/*****************************/
171
/* Library Private Variables */
172
/*****************************/
173
174
/*******************/
175
/* Local Variables */
176
/*******************/
177
178
/* Property value defaults */
179
static const H5D_append_flush_t H5D_def_append_flush_g =
180
    H5D_ACS_APPEND_FLUSH_DEF; /* Default setting for append flush */
181
static const char *H5D_def_efile_prefix_g =
182
    H5D_ACS_EFILE_PREFIX_DEF;                                     /* Default external file prefix string */
183
static const char *H5D_def_vds_prefix_g = H5D_ACS_VDS_PREFIX_DEF; /* Default vds prefix string */
184
static const bool  H5D_def_tree_g = H5D_ACS_USE_TREE_DEF; /* Default use of spatial tree for VDS mappings */
185
186
/*-------------------------------------------------------------------------
187
 * Function:    H5P__dacc_reg_prop
188
 *
189
 * Purpose:     Register the dataset access property list class's
190
 *              properties
191
 *
192
 * Return:      Non-negative on success/Negative on failure
193
 *-------------------------------------------------------------------------
194
 */
195
static herr_t
196
H5P__dacc_reg_prop(H5P_genclass_t *pclass)
197
1
{
198
1
    size_t rdcc_nslots = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF;    /* Default raw data chunk cache # of slots */
199
1
    size_t rdcc_nbytes = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF;    /* Default raw data chunk cache # of bytes */
200
1
    double rdcc_w0     = H5D_ACS_PREEMPT_READ_CHUNKS_DEF;     /* Default raw data chunk cache dirty ratio */
201
1
    H5D_vds_view_t virtual_view = H5D_ACS_VDS_VIEW_DEF;       /* Default VDS view option */
202
1
    hsize_t        printf_gap   = H5D_ACS_VDS_PRINTF_GAP_DEF; /* Default VDS printf gap */
203
1
    herr_t         ret_value    = SUCCEED;                    /* Return value */
204
205
1
    FUNC_ENTER_PACKAGE
206
207
    /* Register the size of raw data chunk cache (elements) */
208
1
    if (H5P__register_real(pclass, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE,
209
1
                           &rdcc_nslots, NULL, NULL, NULL, H5D_ACS_DATA_CACHE_NUM_SLOTS_ENC,
210
1
                           H5D_ACS_DATA_CACHE_NUM_SLOTS_DEC, NULL, NULL, NULL, NULL) < 0)
211
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
212
213
    /* Register the size of raw data chunk cache(bytes) */
214
1
    if (H5P__register_real(pclass, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE,
215
1
                           &rdcc_nbytes, NULL, NULL, NULL, H5D_ACS_DATA_CACHE_BYTE_SIZE_ENC,
216
1
                           H5D_ACS_DATA_CACHE_BYTE_SIZE_DEC, NULL, NULL, NULL, NULL) < 0)
217
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
218
219
    /* Register the preemption for reading chunks */
220
1
    if (H5P__register_real(pclass, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, H5D_ACS_PREEMPT_READ_CHUNKS_SIZE,
221
1
                           &rdcc_w0, NULL, NULL, NULL, H5D_ACS_PREEMPT_READ_CHUNKS_ENC,
222
1
                           H5D_ACS_PREEMPT_READ_CHUNKS_DEC, NULL, NULL, NULL, NULL) < 0)
223
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
224
225
    /* Register the VDS view option */
226
1
    if (H5P__register_real(pclass, H5D_ACS_VDS_VIEW_NAME, H5D_ACS_VDS_VIEW_SIZE, &virtual_view, NULL, NULL,
227
1
                           NULL, H5D_ACS_VDS_VIEW_ENC, H5D_ACS_VDS_VIEW_DEC, NULL, NULL, NULL, NULL) < 0)
228
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
229
230
    /* Register the VDS printf gap */
231
1
    if (H5P__register_real(pclass, H5D_ACS_VDS_PRINTF_GAP_NAME, H5D_ACS_VDS_PRINTF_GAP_SIZE, &printf_gap,
232
1
                           NULL, NULL, NULL, H5D_ACS_VDS_PRINTF_GAP_ENC, H5D_ACS_VDS_PRINTF_GAP_DEC, NULL,
233
1
                           NULL, NULL, NULL) < 0)
234
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
235
236
    /* Register property for vds prefix */
237
1
    if (H5P__register_real(pclass, H5D_ACS_VDS_PREFIX_NAME, H5D_ACS_VDS_PREFIX_SIZE, &H5D_def_vds_prefix_g,
238
1
                           NULL, H5D_ACS_VDS_PREFIX_SET, H5D_ACS_VDS_PREFIX_GET, H5D_ACS_VDS_PREFIX_ENC,
239
1
                           H5D_ACS_VDS_PREFIX_DEC, H5D_ACS_VDS_PREFIX_DEL, H5D_ACS_VDS_PREFIX_COPY,
240
1
                           H5D_ACS_VDS_PREFIX_CMP, H5D_ACS_VDS_PREFIX_CLOSE) < 0)
241
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
242
243
    /* Register info for append flush */
244
    /* (Note: this property should not have an encode/decode callback -QAK) */
245
1
    if (H5P__register_real(pclass, H5D_ACS_APPEND_FLUSH_NAME, H5D_ACS_APPEND_FLUSH_SIZE,
246
1
                           &H5D_def_append_flush_g, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
247
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
248
249
    /* Register property for external file prefix */
250
1
    if (H5P__register_real(pclass, H5D_ACS_EFILE_PREFIX_NAME, H5D_ACS_EFILE_PREFIX_SIZE,
251
1
                           &H5D_def_efile_prefix_g, NULL, H5D_ACS_EFILE_PREFIX_SET, H5D_ACS_EFILE_PREFIX_GET,
252
1
                           H5D_ACS_EFILE_PREFIX_ENC, H5D_ACS_EFILE_PREFIX_DEC, H5D_ACS_EFILE_PREFIX_DEL,
253
1
                           H5D_ACS_EFILE_PREFIX_COPY, H5D_ACS_EFILE_PREFIX_CMP,
254
1
                           H5D_ACS_EFILE_PREFIX_CLOSE) < 0)
255
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
256
257
    /* Register the spatial tree use property */
258
1
    if (H5P__register_real(pclass, H5D_ACS_USE_TREE_NAME, H5D_ACS_USE_TREE_SIZE, &H5D_def_tree_g, NULL, NULL,
259
1
                           NULL, H5D_ACS_USE_TREE_ENC, H5D_ACS_USE_TREE_DEC, NULL, NULL, NULL, NULL) < 0)
260
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
261
262
1
done:
263
1
    FUNC_LEAVE_NOAPI(ret_value)
264
1
} /* end H5P__dacc_reg_prop() */
265
266
/*-------------------------------------------------------------------------
267
 * Function:    H5P__dapl_vds_file_pref_set
268
 *
269
 * Purpose:     Copies a vds file prefix property when it's set
270
 *              for a property list
271
 *
272
 * Return:      SUCCEED/FAIL
273
 *-------------------------------------------------------------------------
274
 */
275
static herr_t
276
H5P__dapl_vds_file_pref_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
277
                            size_t H5_ATTR_UNUSED size, void *value)
278
0
{
279
0
    FUNC_ENTER_PACKAGE_NOERR
280
281
    /* Sanity check */
282
0
    assert(value);
283
284
    /* Copy the prefix */
285
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
286
287
0
    FUNC_LEAVE_NOAPI(SUCCEED)
288
0
} /* end H5P__dapl_vds_file_pref_set() */
289
290
/*-------------------------------------------------------------------------
291
 * Function:    H5P__dapl_vds_file_pref_get
292
 *
293
 * Purpose:     Copies a vds file prefix property when it's retrieved
294
 *              from a property list
295
 *
296
 * Return:      SUCCEED/FAIL
297
 *-------------------------------------------------------------------------
298
 */
299
static herr_t
300
H5P__dapl_vds_file_pref_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
301
                            size_t H5_ATTR_UNUSED size, void *value)
302
0
{
303
0
    FUNC_ENTER_PACKAGE_NOERR
304
305
    /* Sanity check */
306
0
    assert(value);
307
308
    /* Copy the prefix */
309
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
310
311
0
    FUNC_LEAVE_NOAPI(SUCCEED)
312
0
} /* end H5P__dapl_vds_file_pref_get() */
313
314
/*-------------------------------------------------------------------------
315
 * Function:    H5P__dapl_vds_file_pref_enc
316
 *
317
 * Purpose:     Callback routine which is called whenever the vds file prefix
318
 *              property in the dataset access property list is
319
 *              encoded.
320
 *
321
 * Return:      SUCCEED/FAIL
322
 *-------------------------------------------------------------------------
323
 */
324
static herr_t
325
H5P__dapl_vds_file_pref_enc(const void *value, void **_pp, size_t *size)
326
0
{
327
0
    const char *vds_file_pref = *(const char *const *)value;
328
0
    uint8_t   **pp            = (uint8_t **)_pp;
329
0
    size_t      len           = 0;
330
0
    uint64_t    enc_value;
331
0
    unsigned    enc_size;
332
333
0
    FUNC_ENTER_PACKAGE_NOERR
334
335
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
336
337
    /* calculate prefix length */
338
0
    if (NULL != vds_file_pref)
339
0
        len = strlen(vds_file_pref);
340
341
0
    enc_value = (uint64_t)len;
342
0
    enc_size  = H5VM_limit_enc_size(enc_value);
343
0
    assert(enc_size < 256);
344
345
0
    if (NULL != *pp) {
346
        /* encode the length of the prefix */
347
0
        *(*pp)++ = (uint8_t)enc_size;
348
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
349
350
        /* encode the prefix */
351
0
        if (NULL != vds_file_pref) {
352
0
            H5MM_memcpy(*(char **)pp, vds_file_pref, len);
353
0
            *pp += len;
354
0
        } /* end if */
355
0
    }     /* end if */
356
357
0
    *size += (1 + enc_size);
358
0
    if (NULL != vds_file_pref)
359
0
        *size += len;
360
361
0
    FUNC_LEAVE_NOAPI(SUCCEED)
362
0
} /* end H5P__dapl_vds_file_pref_enc() */
363
364
/*-------------------------------------------------------------------------
365
 * Function:    H5P__dapl_vds_file_pref_dec
366
 *
367
 * Purpose:     Callback routine which is called whenever the vds file prefix
368
 *              property in the dataset access property list is
369
 *              decoded.
370
 *
371
 * Return:      SUCCEED/FAIL
372
 *-------------------------------------------------------------------------
373
 */
374
static herr_t
375
H5P__dapl_vds_file_pref_dec(const void **_pp, void *_value)
376
0
{
377
0
    char          **vds_file_pref = (char **)_value;
378
0
    const uint8_t **pp            = (const uint8_t **)_pp;
379
0
    size_t          len;
380
0
    uint64_t        enc_value; /* Decoded property value */
381
0
    unsigned        enc_size;  /* Size of encoded property */
382
0
    herr_t          ret_value = SUCCEED;
383
384
0
    FUNC_ENTER_PACKAGE
385
386
0
    assert(pp);
387
0
    assert(*pp);
388
0
    assert(vds_file_pref);
389
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
390
391
    /* Decode the size */
392
0
    enc_size = *(*pp)++;
393
0
    assert(enc_size < 256);
394
395
    /* Decode the value */
396
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
397
0
    len = (size_t)enc_value;
398
399
0
    if (0 != len) {
400
        /* Make a copy of the user's prefix string */
401
0
        if (NULL == (*vds_file_pref = (char *)H5MM_malloc(len + 1)))
402
0
            HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix");
403
0
        strncpy(*vds_file_pref, *(const char **)pp, len);
404
0
        (*vds_file_pref)[len] = '\0';
405
406
0
        *pp += len;
407
0
    } /* end if */
408
0
    else
409
0
        *vds_file_pref = NULL;
410
411
0
done:
412
0
    FUNC_LEAVE_NOAPI(ret_value)
413
0
} /* end H5P__dapl_vds_file_pref_dec() */
414
415
/*-------------------------------------------------------------------------
416
 * Function:    H5P__dapl_vds_file_pref_del
417
 *
418
 * Purpose:     Frees memory used to store the vds file prefix string
419
 *
420
 * Return:      SUCCEED (Can't fail)
421
 *-------------------------------------------------------------------------
422
 */
423
static herr_t
424
H5P__dapl_vds_file_pref_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
425
                            size_t H5_ATTR_UNUSED size, void *value)
426
0
{
427
0
    FUNC_ENTER_PACKAGE_NOERR
428
429
0
    assert(value);
430
431
0
    H5MM_xfree(*(void **)value);
432
433
0
    FUNC_LEAVE_NOAPI(SUCCEED)
434
0
} /* end H5P__dapl_vds_file_pref_del() */
435
436
/*-------------------------------------------------------------------------
437
 * Function:    H5P__dapl_vds_file_pref_copy
438
 *
439
 * Purpose:     Creates a copy of the vds file prefix string
440
 *
441
 * Return:      SUCCEED/FAIL
442
 *-------------------------------------------------------------------------
443
 */
444
static herr_t
445
H5P__dapl_vds_file_pref_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
446
0
{
447
0
    FUNC_ENTER_PACKAGE_NOERR
448
449
0
    assert(value);
450
451
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
452
453
0
    FUNC_LEAVE_NOAPI(SUCCEED)
454
0
} /* end H5P__dapl_vds_file_pref_copy() */
455
456
/*-------------------------------------------------------------------------
457
 * Function:       H5P__dapl_vds_file_pref_cmp
458
 *
459
 * Purpose:        Callback routine which is called whenever the vds file prefix
460
 *                 property in the dataset creation property list is
461
 *                 compared.
462
 *
463
 * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
464
 *-------------------------------------------------------------------------
465
 */
466
static int
467
H5P__dapl_vds_file_pref_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
468
0
{
469
0
    const char *pref1     = *(const char *const *)value1;
470
0
    const char *pref2     = *(const char *const *)value2;
471
0
    int         ret_value = 0;
472
473
0
    FUNC_ENTER_PACKAGE_NOERR
474
475
0
    if (NULL == pref1 && NULL != pref2)
476
0
        HGOTO_DONE(1);
477
0
    if (NULL != pref1 && NULL == pref2)
478
0
        HGOTO_DONE(-1);
479
0
    if (NULL != pref1 && NULL != pref2)
480
0
        ret_value = strcmp(pref1, pref2);
481
482
0
done:
483
0
    FUNC_LEAVE_NOAPI(ret_value)
484
0
} /* end H5P__dapl_vds_file_pref_cmp() */
485
486
/*-------------------------------------------------------------------------
487
 * Function:    H5P__dapl_vds_file_pref_close
488
 *
489
 * Purpose:     Frees memory used to store the vds file prefix string
490
 *
491
 * Return:      SUCCEED/FAIL
492
 *-------------------------------------------------------------------------
493
 */
494
static herr_t
495
H5P__dapl_vds_file_pref_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
496
1
{
497
1
    FUNC_ENTER_PACKAGE_NOERR
498
499
1
    assert(value);
500
501
1
    H5MM_xfree(*(void **)value);
502
503
1
    FUNC_LEAVE_NOAPI(SUCCEED)
504
1
} /* end H5P__dapl_vds_file_pref_close() */
505
506
/*-------------------------------------------------------------------------
507
 * Function:    H5P__dapl_efile_pref_set
508
 *
509
 * Purpose:     Copies an external file prefix property when it's set
510
 *              for a property list
511
 *
512
 * Return:      SUCCEED/FAIL
513
 *-------------------------------------------------------------------------
514
 */
515
static herr_t
516
H5P__dapl_efile_pref_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
517
                         size_t H5_ATTR_UNUSED size, void *value)
518
0
{
519
0
    FUNC_ENTER_PACKAGE_NOERR
520
521
    /* Sanity check */
522
0
    assert(value);
523
524
    /* Copy the prefix */
525
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
526
527
0
    FUNC_LEAVE_NOAPI(SUCCEED)
528
0
} /* end H5P__dapl_efile_pref_set() */
529
530
/*-------------------------------------------------------------------------
531
 * Function:    H5P__dapl_efile_pref_get
532
 *
533
 * Purpose:     Copies an external file prefix property when it's retrieved
534
 *              from a property list
535
 *
536
 * Return:      SUCCEED/FAIL
537
 *-------------------------------------------------------------------------
538
 */
539
static herr_t
540
H5P__dapl_efile_pref_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
541
                         size_t H5_ATTR_UNUSED size, void *value)
542
0
{
543
0
    FUNC_ENTER_PACKAGE_NOERR
544
545
    /* Sanity check */
546
0
    assert(value);
547
548
    /* Copy the prefix */
549
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
550
551
0
    FUNC_LEAVE_NOAPI(SUCCEED)
552
0
} /* end H5P__dapl_efile_pref_get() */
553
554
/*-------------------------------------------------------------------------
555
 * Function:    H5P__dapl_efile_pref_enc
556
 *
557
 * Purpose:     Callback routine which is called whenever the efile flags
558
 *              property in the dataset access property list is
559
 *              encoded.
560
 *
561
 * Return:      SUCCEED/FAIL
562
 *-------------------------------------------------------------------------
563
 */
564
static herr_t
565
H5P__dapl_efile_pref_enc(const void *value, void **_pp, size_t *size)
566
0
{
567
0
    const char *efile_pref = *(const char *const *)value;
568
0
    uint8_t   **pp         = (uint8_t **)_pp;
569
0
    size_t      len        = 0;
570
0
    uint64_t    enc_value;
571
0
    unsigned    enc_size;
572
573
0
    FUNC_ENTER_PACKAGE_NOERR
574
575
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
576
577
    /* calculate prefix length */
578
0
    if (NULL != efile_pref)
579
0
        len = strlen(efile_pref);
580
581
0
    enc_value = (uint64_t)len;
582
0
    enc_size  = H5VM_limit_enc_size(enc_value);
583
0
    assert(enc_size < 256);
584
585
0
    if (NULL != *pp) {
586
        /* encode the length of the prefix */
587
0
        *(*pp)++ = (uint8_t)enc_size;
588
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
589
590
        /* encode the prefix */
591
0
        if (NULL != efile_pref) {
592
0
            H5MM_memcpy(*(char **)pp, efile_pref, len);
593
0
            *pp += len;
594
0
        } /* end if */
595
0
    }     /* end if */
596
597
0
    *size += (1 + enc_size);
598
0
    if (NULL != efile_pref)
599
0
        *size += len;
600
601
0
    FUNC_LEAVE_NOAPI(SUCCEED)
602
0
} /* end H5P__dapl_efile_pref_enc() */
603
604
/*-------------------------------------------------------------------------
605
 * Function:    H5P__dapl_efile_pref_dec
606
 *
607
 * Purpose:     Callback routine which is called whenever the efile prefix
608
 *              property in the dataset access property list is
609
 *              decoded.
610
 *
611
 * Return:        SUCCEED/FAIL
612
 *-------------------------------------------------------------------------
613
 */
614
static herr_t
615
H5P__dapl_efile_pref_dec(const void **_pp, void *_value)
616
0
{
617
0
    char          **efile_pref = (char **)_value;
618
0
    const uint8_t **pp         = (const uint8_t **)_pp;
619
0
    size_t          len;
620
0
    uint64_t        enc_value; /* Decoded property value */
621
0
    unsigned        enc_size;  /* Size of encoded property */
622
0
    herr_t          ret_value = SUCCEED;
623
624
0
    FUNC_ENTER_PACKAGE
625
626
0
    assert(pp);
627
0
    assert(*pp);
628
0
    assert(efile_pref);
629
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
630
631
    /* Decode the size */
632
0
    enc_size = *(*pp)++;
633
0
    assert(enc_size < 256);
634
635
    /* Decode the value */
636
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
637
0
    len = (size_t)enc_value;
638
639
0
    if (0 != len) {
640
        /* Make a copy of the user's prefix string */
641
0
        if (NULL == (*efile_pref = (char *)H5MM_malloc(len + 1)))
642
0
            HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix");
643
0
        strncpy(*efile_pref, *(const char **)pp, len);
644
0
        (*efile_pref)[len] = '\0';
645
646
0
        *pp += len;
647
0
    } /* end if */
648
0
    else
649
0
        *efile_pref = NULL;
650
651
0
done:
652
0
    FUNC_LEAVE_NOAPI(ret_value)
653
0
} /* end H5P__dapl_efile_pref_dec() */
654
655
/*-------------------------------------------------------------------------
656
 * Function:    H5P__dapl_efile_pref_del
657
 *
658
 * Purpose:     Frees memory used to store the external file prefix string
659
 *
660
 * Return:      SUCCEED (Can't fail)
661
 *-------------------------------------------------------------------------
662
 */
663
static herr_t
664
H5P__dapl_efile_pref_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
665
                         size_t H5_ATTR_UNUSED size, void *value)
666
0
{
667
0
    FUNC_ENTER_PACKAGE_NOERR
668
669
0
    assert(value);
670
671
0
    H5MM_xfree(*(void **)value);
672
673
0
    FUNC_LEAVE_NOAPI(SUCCEED)
674
0
} /* end H5P__dapl_efile_pref_del() */
675
676
/*-------------------------------------------------------------------------
677
 * Function:    H5P__dapl_efile_pref_copy
678
 *
679
 * Purpose:     Creates a copy of the external file prefix string
680
 *
681
 * Return:      SUCCEED/FAIL
682
 *-------------------------------------------------------------------------
683
 */
684
static herr_t
685
H5P__dapl_efile_pref_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
686
0
{
687
0
    FUNC_ENTER_PACKAGE_NOERR
688
689
0
    assert(value);
690
691
0
    *(char **)value = H5MM_xstrdup(*(const char **)value);
692
693
0
    FUNC_LEAVE_NOAPI(SUCCEED)
694
0
} /* end H5P__dapl_efile_pref_copy() */
695
696
/*-------------------------------------------------------------------------
697
 * Function:       H5P__dapl_efile_pref_cmp
698
 *
699
 * Purpose:        Callback routine which is called whenever the efile prefix
700
 *                 property in the dataset creation property list is
701
 *                 compared.
702
 *
703
 * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
704
 *-------------------------------------------------------------------------
705
 */
706
static int
707
H5P__dapl_efile_pref_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
708
0
{
709
0
    const char *pref1     = *(const char *const *)value1;
710
0
    const char *pref2     = *(const char *const *)value2;
711
0
    int         ret_value = 0;
712
713
0
    FUNC_ENTER_PACKAGE_NOERR
714
715
0
    if (NULL == pref1 && NULL != pref2)
716
0
        HGOTO_DONE(1);
717
0
    if (NULL != pref1 && NULL == pref2)
718
0
        HGOTO_DONE(-1);
719
0
    if (NULL != pref1 && NULL != pref2)
720
0
        ret_value = strcmp(pref1, pref2);
721
722
0
done:
723
0
    FUNC_LEAVE_NOAPI(ret_value)
724
0
} /* end H5P__dapl_efile_pref_cmp() */
725
726
/*-------------------------------------------------------------------------
727
 * Function:    H5P__dapl_efile_pref_close
728
 *
729
 * Purpose:     Frees memory used to store the external file prefix string
730
 *
731
 * Return:      SUCCEED/FAIL
732
 *-------------------------------------------------------------------------
733
 */
734
static herr_t
735
H5P__dapl_efile_pref_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
736
1
{
737
1
    FUNC_ENTER_PACKAGE_NOERR
738
739
1
    assert(value);
740
741
1
    H5MM_xfree(*(void **)value);
742
743
1
    FUNC_LEAVE_NOAPI(SUCCEED)
744
1
} /* end H5P__dapl_efile_pref_close() */
745
746
/*-------------------------------------------------------------------------
747
 * Function:    H5Pset_chunk_cache
748
 *
749
 * Purpose:    Set the number of objects in the meta data cache and the
750
 *        maximum number of chunks and bytes in the raw data chunk cache.
751
 *        Once set, these values will override the values in the file access
752
 *        property list.  Each of these values can be individually unset
753
 *        (or not set at all) by passing the macros:
754
 *        H5D_CHUNK_CACHE_NCHUNKS_DEFAULT,
755
 *        H5D_CHUNK_CACHE_NSLOTS_DEFAULT, and/or
756
 *        H5D_CHUNK_CACHE_W0_DEFAULT
757
 *        as appropriate.
758
 *
759
 *        The RDCC_W0 value should be between 0 and 1 inclusive and
760
 *        indicates how much chunks that have been fully read or fully
761
 *        written are favored for preemption.  A value of zero means
762
 *        fully read or written chunks are treated no differently than
763
 *        other chunks (the preemption is strictly LRU) while a value
764
 *        of one means fully read chunks are always preempted before
765
 *        other chunks.
766
 *
767
 * Return:    Non-negative on success/Negative on failure
768
 *-------------------------------------------------------------------------
769
 */
770
herr_t
771
H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0)
772
0
{
773
0
    H5P_genplist_t *plist;               /* Property list pointer */
774
0
    herr_t          ret_value = SUCCEED; /* return value */
775
776
0
    FUNC_ENTER_API(FAIL)
777
778
    /* Check arguments.  Note that we allow negative values - they are
779
     * considered to "unset" the property. */
780
0
    if (rdcc_w0 > 1.0)
781
0
        HGOTO_ERROR(
782
0
            H5E_ARGS, H5E_BADVALUE, FAIL,
783
0
            "raw data cache w0 value must be between 0.0 and 1.0 inclusive, or H5D_CHUNK_CACHE_W0_DEFAULT");
784
785
    /* Get the plist structure */
786
0
    if (NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS, false)))
787
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
788
789
    /* Set sizes */
790
0
    if (H5P_set(plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc_nslots) < 0)
791
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of chunks");
792
0
    if (H5P_set(plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc_nbytes) < 0)
793
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size");
794
0
    if (H5P_set(plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc_w0) < 0)
795
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks");
796
797
0
done:
798
0
    FUNC_LEAVE_API(ret_value)
799
0
} /* end H5Pset_chunk_cache() */
800
801
/*-------------------------------------------------------------------------
802
 * Function: H5Pget_chunk_cache
803
 *
804
 * Purpose:  Retrieves the maximum possible number of elements in the meta
805
 *        data cache and the maximum possible number of elements and
806
 *        bytes and the RDCC_W0 value in the raw data chunk cache.  Any
807
 *        (or all) arguments may be null pointers in which case the
808
 *        corresponding datum is not returned.  If these properties have
809
 *        not been set on this property list, the default values for a
810
 *        file access property list are returned.
811
 *
812
 * Return:  Non-negative on success/Negative on failure
813
 *-------------------------------------------------------------------------
814
 */
815
herr_t
816
H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots /*out*/, size_t *rdcc_nbytes /*out*/,
817
                   double *rdcc_w0 /*out*/)
818
0
{
819
0
    H5P_genplist_t *plist;               /* Property list pointer */
820
0
    H5P_genplist_t *def_plist;           /* Default file access property list */
821
0
    herr_t          ret_value = SUCCEED; /* return value */
822
823
0
    FUNC_ENTER_API(FAIL)
824
825
    /* Get the plist structure */
826
0
    if (NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS, true)))
827
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
828
829
    /* Get default file access plist */
830
0
    if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
831
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for default fapl ID");
832
833
    /* Get the properties.  If a property is set to the default value, the value
834
     * from the default fapl is used. */
835
0
    if (rdcc_nslots) {
836
0
        if (H5P_get(plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
837
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get data cache number of slots");
838
0
        if (*rdcc_nslots == H5D_CHUNK_CACHE_NSLOTS_DEFAULT)
839
0
            if (H5P_get(def_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
840
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get default data cache number of slots");
841
0
    } /* end if */
842
0
    if (rdcc_nbytes) {
843
0
        if (H5P_get(plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
844
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get data cache byte size");
845
0
        if (*rdcc_nbytes == H5D_CHUNK_CACHE_NBYTES_DEFAULT)
846
0
            if (H5P_get(def_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
847
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get default data cache byte size");
848
0
    } /* end if */
849
0
    if (rdcc_w0) {
850
0
        if (H5P_get(plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, rdcc_w0) < 0)
851
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get preempt read chunks");
852
0
        if (*rdcc_w0 < 0)
853
0
            if (H5P_get(def_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, rdcc_w0) < 0)
854
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get default preempt read chunks");
855
0
    } /* end if */
856
857
0
done:
858
0
    FUNC_LEAVE_API(ret_value)
859
0
} /* end H5Pget_chunk_cache() */
860
861
/*-------------------------------------------------------------------------
862
 * Function:       H5P__encode_chunk_cache_nslots
863
 *
864
 * Purpose:        Encode the rdcc_nslots parameter to a serialized
865
 *                 property list.  Similar to H5P__encode_size_t except
866
 *                 the value of 255 for the enc_size field is reserved to
867
 *                 indicate H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF, in which
868
 *                 nothing further is encoded.
869
 *
870
 * Return:         Success:     Non-negative
871
 *                 Failure:     Negative
872
 *-------------------------------------------------------------------------
873
 */
874
static herr_t
875
H5P__encode_chunk_cache_nslots(const void *value, void **_pp, size_t *size)
876
0
{
877
0
    uint64_t  enc_value = 0; /* Property value to encode */
878
0
    uint8_t **pp        = (uint8_t **)_pp;
879
0
    unsigned  enc_size; /* Size of encoded property */
880
881
0
    FUNC_ENTER_PACKAGE_NOERR
882
883
    /* Sanity checks */
884
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
885
0
    assert(size);
886
887
    /* Determine if this is the default value, in which case only encode
888
     * enc_size (as 255).  Also set size needed for encoding. */
889
0
    if (*(const size_t *)value == H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF) {
890
0
        enc_size = 0;
891
0
        *size += 1;
892
0
    } /* end if */
893
0
    else {
894
0
        enc_value = (uint64_t) * (const size_t *)value;
895
0
        enc_size  = H5VM_limit_enc_size(enc_value);
896
0
        assert(enc_size > 0);
897
0
        *size += (1 + enc_size);
898
0
    } /* end else */
899
900
0
    assert(enc_size < 256);
901
902
0
    if (NULL != *pp) {
903
        /* Encode the size */
904
0
        *(*pp)++ = (uint8_t)enc_size;
905
906
        /* Encode the value if necessary */
907
0
        if (enc_size != 0) {
908
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
909
0
        } /* end if */
910
0
    }     /* end if */
911
912
0
    FUNC_LEAVE_NOAPI(SUCCEED)
913
0
} /* end H5P__encode_chunk_cache_nslots() */
914
915
/*-------------------------------------------------------------------------
916
 * Function:       H5P__decode_chunk_cache_nslots
917
 *
918
 * Purpose:        Decode the rdcc_nslots parameter from a serialized
919
 *                 property list.  Similar to H5P__decode_size_t except
920
 *                 the value of 255 for the enc_size field is reserved to
921
 *                 indicate H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF, in which
922
 *                 nothing further needs to be decoded.
923
 *
924
 * Return:         Success:     Non-negative
925
 *                 Failure:     Negative
926
 *-------------------------------------------------------------------------
927
 */
928
static herr_t
929
H5P__decode_chunk_cache_nslots(const void **_pp, void *_value)
930
0
{
931
0
    size_t         *value = (size_t *)_value; /* Property value to return */
932
0
    const uint8_t **pp    = (const uint8_t **)_pp;
933
0
    uint64_t        enc_value; /* Decoded property value */
934
0
    unsigned        enc_size;  /* Size of encoded property */
935
936
0
    FUNC_ENTER_PACKAGE_NOERR
937
938
    /* Sanity check */
939
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
940
0
    assert(pp);
941
0
    assert(*pp);
942
0
    assert(value);
943
944
    /* Decode the size */
945
0
    enc_size = *(*pp)++;
946
0
    assert(enc_size < 256);
947
948
    /* Determine if enc_size indicates that this is the default value, in which
949
     * case set value to H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF and return */
950
0
    if (enc_size == 0)
951
0
        *value = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF;
952
0
    else {
953
        /* Decode the value */
954
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
955
0
        H5_CHECKED_ASSIGN(*value, uint64_t, enc_value, size_t);
956
0
    } /* end else */
957
958
0
    FUNC_LEAVE_NOAPI(SUCCEED)
959
0
} /* end H5P__decode_chunk_cache_nslots() */
960
961
/*-------------------------------------------------------------------------
962
 * Function:       H5P__encode_chunk_cache_nbytes
963
 *
964
 * Purpose:        Encode the rdcc_nbytes parameter to a serialized
965
 *                 property list.  Similar to H5P__encode_size_t except
966
 *                 the value of 0 for the enc_size field is reserved to
967
 *                 indicate H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF, in which
968
 *                 nothing further is encoded.
969
 *
970
 * Return:         Success:     Non-negative
971
 *                 Failure:     Negative
972
 *-------------------------------------------------------------------------
973
 */
974
static herr_t
975
H5P__encode_chunk_cache_nbytes(const void *value, void **_pp, size_t *size)
976
0
{
977
0
    uint64_t  enc_value = 0; /* Property value to encode */
978
0
    uint8_t **pp        = (uint8_t **)_pp;
979
0
    unsigned  enc_size; /* Size of encoded property */
980
981
0
    FUNC_ENTER_PACKAGE_NOERR
982
983
    /* Sanity checks */
984
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
985
0
    assert(size);
986
987
    /* Determine if this is the default value, in which case only encode
988
     * enc_size (as 0).  Also set size needed for encoding. */
989
0
    if (*(const size_t *)value == H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF) {
990
0
        enc_size = 0;
991
0
        *size += 1;
992
0
    } /* end if */
993
0
    else {
994
0
        enc_value = (uint64_t) * (const size_t *)value;
995
0
        enc_size  = H5VM_limit_enc_size(enc_value);
996
0
        assert(enc_size > 0);
997
0
        *size += (1 + enc_size);
998
0
    } /* end else */
999
1000
0
    assert(enc_size < 256);
1001
1002
0
    if (NULL != *pp) {
1003
        /* Encode the size */
1004
0
        *(*pp)++ = (uint8_t)enc_size;
1005
1006
        /* Encode the value if necessary */
1007
0
        if (enc_size != 0) {
1008
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1009
0
        } /* end if */
1010
0
    }     /* end if */
1011
1012
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1013
0
} /* end H5P__encode_chunk_cache_nbytes() */
1014
1015
/*-------------------------------------------------------------------------
1016
 * Function:       H5P__decode_chunk_cache_nbytes
1017
 *
1018
 * Purpose:        Decode the rdcc_nbytes parameter from a serialized
1019
 *                 property list.  Similar to H5P__decode_size_t except
1020
 *                 the value of 0 for the enc_size field is reserved to
1021
 *                 indicate H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF, in which
1022
 *                 nothing further needs to be decoded.
1023
 *
1024
 * Return:         Success:     Non-negative
1025
 *                 Failure:     Negative
1026
 *-------------------------------------------------------------------------
1027
 */
1028
static herr_t
1029
H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value)
1030
0
{
1031
0
    size_t         *value = (size_t *)_value; /* Property value to return */
1032
0
    const uint8_t **pp    = (const uint8_t **)_pp;
1033
0
    uint64_t        enc_value; /* Decoded property value */
1034
0
    unsigned        enc_size;  /* Size of encoded property */
1035
1036
0
    FUNC_ENTER_PACKAGE_NOERR
1037
1038
    /* Sanity check */
1039
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1040
0
    assert(pp);
1041
0
    assert(*pp);
1042
0
    assert(value);
1043
1044
    /* Decode the size */
1045
0
    enc_size = *(*pp)++;
1046
0
    assert(enc_size < 256);
1047
1048
    /* Determine if enc_size indicates that this is the default value, in which
1049
     * case set value to H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF and return */
1050
0
    if (enc_size == 0)
1051
0
        *value = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF;
1052
0
    else {
1053
        /* Decode the value */
1054
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
1055
0
        H5_CHECKED_ASSIGN(*value, uint64_t, enc_value, size_t);
1056
0
    } /* end else */
1057
1058
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1059
0
} /* end H5P__decode_chunk_cache_nbytes() */
1060
1061
/*-------------------------------------------------------------------------
1062
 * Function:    H5Pset_virtual_view
1063
 *
1064
 * Purpose:     Takes the access property list for the virtual dataset,
1065
 *              dapl_id, and the flag, view, and sets the VDS view
1066
 *              according to the flag value.  The view will include all
1067
 *              data before the first missing mapped data found if the
1068
 *              flag is set to H5D_VDS_FIRST_MISSING or to include all
1069
 *              available mapped data if the flag is set to
1070
 *              H5D_VDS_LAST_AVAIALBLE.  Missing mapped data will be
1071
 *              filled with the fill value according to the VDS creation
1072
 *              property settings.  For VDS with unlimited mappings, the
1073
 *              view defines the extent.
1074
 *
1075
 * Return:      Non-negative on success/Negative on failure
1076
 *-------------------------------------------------------------------------
1077
 */
1078
herr_t
1079
H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view)
1080
0
{
1081
0
    H5P_genplist_t *plist;               /* Property list pointer */
1082
0
    herr_t          ret_value = SUCCEED; /* return value */
1083
1084
0
    FUNC_ENTER_API(FAIL)
1085
1086
    /* Check argument */
1087
0
    if ((view != H5D_VDS_FIRST_MISSING) && (view != H5D_VDS_LAST_AVAILABLE))
1088
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid bounds option");
1089
1090
    /* Get the plist structure */
1091
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, false)))
1092
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1093
1094
    /* Update property list */
1095
0
    if (H5P_set(plist, H5D_ACS_VDS_VIEW_NAME, &view) < 0)
1096
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value");
1097
1098
0
done:
1099
0
    FUNC_LEAVE_API(ret_value)
1100
0
} /* end H5Pset_virtual_view() */
1101
1102
/*-------------------------------------------------------------------------
1103
 * Function:    H5Pget_virtual_view
1104
 *
1105
 * Purpose:     Takes the access property list for the virtual dataset,
1106
 *              dapl_id, and gets the flag, view, set by the
1107
 *              H5Pset_virtual_view call.  The possible values of view are
1108
 *              H5D_VDS_FIRST_MISSING or H5D_VDS_LAST_AVAIALBLE.
1109
 *
1110
 * Return:      Non-negative on success/Negative on failure
1111
 *-------------------------------------------------------------------------
1112
 */
1113
herr_t
1114
H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view /*out*/)
1115
0
{
1116
0
    H5P_genplist_t *plist;               /* Property list pointer */
1117
0
    herr_t          ret_value = SUCCEED; /* Return value */
1118
1119
0
    FUNC_ENTER_API(FAIL)
1120
1121
    /* Get the plist structure */
1122
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, true)))
1123
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1124
1125
    /* Get value from property list */
1126
0
    if (view)
1127
0
        if (H5P_get(plist, H5D_ACS_VDS_VIEW_NAME, view) < 0)
1128
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
1129
1130
0
done:
1131
0
    FUNC_LEAVE_API(ret_value)
1132
0
} /* end H5Pget_virtual_view() */
1133
1134
/*-------------------------------------------------------------------------
1135
 * Function:    H5P__dacc_vds_view_enc
1136
 *
1137
 * Purpose:     Callback routine which is called whenever the vds view
1138
 *              property in the dataset access property list is encoded.
1139
 *
1140
 * Return:      Success:        Non-negative
1141
 *              Failure:        Negative
1142
 *-------------------------------------------------------------------------
1143
 */
1144
static herr_t
1145
H5P__dacc_vds_view_enc(const void *value, void **_pp, size_t *size)
1146
0
{
1147
0
    const H5D_vds_view_t *view = (const H5D_vds_view_t *)value; /* Create local alias for values */
1148
0
    uint8_t             **pp   = (uint8_t **)_pp;
1149
1150
0
    FUNC_ENTER_PACKAGE_NOERR
1151
1152
    /* Sanity check */
1153
0
    assert(view);
1154
0
    assert(size);
1155
1156
0
    if (NULL != *pp)
1157
        /* Encode EDC property */
1158
0
        *(*pp)++ = (uint8_t)*view;
1159
1160
    /* Size of EDC property */
1161
0
    (*size)++;
1162
1163
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1164
0
} /* end H5P__dacc_vds_view_enc() */
1165
1166
/*-------------------------------------------------------------------------
1167
 * Function:    H5P__dacc_vds_view_dec
1168
 *
1169
 * Purpose:     Callback routine which is called whenever the vds view
1170
 *              property in the dataset access property list is encoded.
1171
 *
1172
 * Return:      Success:        Non-negative
1173
 *              Failure:        Negative
1174
 *-------------------------------------------------------------------------
1175
 */
1176
static herr_t
1177
H5P__dacc_vds_view_dec(const void **_pp, void *_value)
1178
0
{
1179
0
    H5D_vds_view_t *view = (H5D_vds_view_t *)_value;
1180
0
    const uint8_t **pp   = (const uint8_t **)_pp;
1181
1182
0
    FUNC_ENTER_PACKAGE_NOERR
1183
1184
    /* Sanity checks */
1185
0
    assert(pp);
1186
0
    assert(*pp);
1187
0
    assert(view);
1188
1189
    /* Decode EDC property */
1190
0
    *view = (H5D_vds_view_t) * (*pp)++;
1191
1192
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1193
0
} /* end H5P__dacc_vds_view_dec() */
1194
1195
/*-------------------------------------------------------------------------
1196
 * Function:    H5Pset_virtual_printf_gap
1197
 *
1198
 * Purpose:     Sets the access property list for the virtual dataset,
1199
 *              dapl_id, to instruct the library to stop looking for the
1200
 *              mapped data stored in the files and/or datasets with the
1201
 *              printf-style names after not finding gap_size files and/or
1202
 *              datasets.  The found source files and datasets will
1203
 *              determine the extent of the unlimited VDS with the printf
1204
 *              -style mappings.
1205
 *
1206
 *              For example, if regularly spaced blocks of VDS are mapped
1207
 *              to datasets with the names d-1, d-2, d-3, ..., d-N, ...,
1208
 *              and d-2 dataset is missing and gap_size is set to 0, then
1209
 *              VDS will contain only data found in d-1.  If d-2 and d-3
1210
 *              are missing and gap_size is set to 2, then VDS will
1211
 *              contain the data from d-1, d-3, ..., d-N, ....  The blocks
1212
 *              that are mapped to d-2 and d-3 will be filled according to
1213
 *              the VDS fill value setting.
1214
 *
1215
 * Return:      Non-negative on success/Negative on failure
1216
 *-------------------------------------------------------------------------
1217
 */
1218
herr_t
1219
H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size)
1220
0
{
1221
0
    H5P_genplist_t *plist;               /* Property list pointer */
1222
0
    herr_t          ret_value = SUCCEED; /* Return value */
1223
1224
0
    FUNC_ENTER_API(FAIL)
1225
1226
    /* Check argument */
1227
0
    if (gap_size == HSIZE_UNDEF)
1228
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid printf gap size");
1229
1230
    /* Get the plist structure */
1231
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, false)))
1232
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1233
1234
    /* Update property list */
1235
0
    if (H5P_set(plist, H5D_ACS_VDS_PRINTF_GAP_NAME, &gap_size) < 0)
1236
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value");
1237
1238
0
done:
1239
0
    FUNC_LEAVE_API(ret_value)
1240
0
} /* end H5Pset_virtual_printf_gap() */
1241
1242
/*-------------------------------------------------------------------------
1243
 * Function:    H5Pget_virtual_printf_gap
1244
 *
1245
 * Purpose:     Gets the maximum number of missing printf-style files
1246
 *              and/or datasets for determining the extent of the
1247
 *              unlimited VDS, gap_size, using the access property list
1248
 *              for the virtual dataset, dapl_id.  The default library
1249
 *              value for gap_size is 0.
1250
 *
1251
 * Return:      Non-negative on success/Negative on failure
1252
 *-------------------------------------------------------------------------
1253
 */
1254
herr_t
1255
H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size /*out*/)
1256
0
{
1257
0
    H5P_genplist_t *plist;               /* Property list pointer */
1258
0
    herr_t          ret_value = SUCCEED; /* Return value */
1259
1260
0
    FUNC_ENTER_API(FAIL)
1261
1262
    /* Get the plist structure */
1263
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, true)))
1264
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1265
1266
    /* Get value from property list */
1267
0
    if (gap_size)
1268
0
        if (H5P_get(plist, H5D_ACS_VDS_PRINTF_GAP_NAME, gap_size) < 0)
1269
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
1270
1271
0
done:
1272
0
    FUNC_LEAVE_API(ret_value)
1273
0
} /* end H5Pget_virtual_printf_gap() */
1274
1275
/*-------------------------------------------------------------------------
1276
 * Function: H5Pset_append_flush
1277
 *
1278
 * Purpose:  Sets the boundary, callback function, and user data in the
1279
 *           property list.
1280
 *           "ndims": number of array elements for boundary
1281
 *           "boundary": used to determine whether the current dimension hits
1282
 *              a boundary; if so, invoke the callback function and
1283
 *              flush the dataset.
1284
 *           "func": the callback function to invoke when the boundary is hit
1285
 *           "udata": the user data to pass as parameter with the callback function
1286
 *
1287
 * Return:   Non-negative on success/Negative on failure
1288
 *-------------------------------------------------------------------------
1289
 */
1290
herr_t
1291
H5Pset_append_flush(hid_t plist_id, unsigned ndims, const hsize_t *boundary, H5D_append_cb_t func,
1292
                    void *udata)
1293
0
{
1294
0
    H5P_genplist_t    *plist;               /* Property list pointer */
1295
0
    H5D_append_flush_t info;                /* Property for append flush parameters */
1296
0
    unsigned           u;                   /* Local index variable */
1297
0
    herr_t             ret_value = SUCCEED; /* Return value */
1298
1299
0
    FUNC_ENTER_API(FAIL)
1300
1301
    /* Check arguments */
1302
0
    if (0 == ndims)
1303
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality cannot be zero");
1304
0
    if (ndims > H5S_MAX_RANK)
1305
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality is too large");
1306
0
    if (!boundary)
1307
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no boundary dimensions specified");
1308
1309
    /* Check if the callback function is NULL and the user data is non-NULL.
1310
     * This is almost certainly an error as the user data will not be used. */
1311
0
    if (!func && udata)
1312
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not");
1313
1314
    /* Get the plist structure */
1315
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, false)))
1316
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1317
1318
    /* Set up values */
1319
0
    info.ndims = ndims;
1320
0
    info.func  = func;
1321
0
    info.udata = udata;
1322
1323
0
    memset(info.boundary, 0, sizeof(info.boundary));
1324
    /* boundary can be 0 to indicate no boundary is set */
1325
0
    for (u = 0; u < ndims; u++) {
1326
0
        if (boundary[u] != (boundary[u] & 0xffffffff)) /* negative value (including H5S_UNLIMITED) */
1327
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "all boundary dimensions must be less than 2^32");
1328
0
        info.boundary[u] = boundary[u]; /* Store user's boundary dimensions */
1329
0
    }                                   /* end for */
1330
1331
    /* Set values */
1332
0
    if (H5P_set(plist, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
1333
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set append flush");
1334
1335
0
done:
1336
0
    FUNC_LEAVE_API(ret_value)
1337
0
} /* H5Pset_append_flush() */
1338
1339
/*-------------------------------------------------------------------------
1340
 * Function: H5Pget_append_flush()
1341
 *
1342
 * Purpose:  Retrieves the boundary, callback function and user data set in
1343
 *           property list.
1344
 *           Note that the # of boundary sizes to retrieve will not exceed
1345
 *           the parameter "ndims" and the ndims set previously via
1346
 *           H5Pset_append_flush().
1347
 *
1348
 * Return:   Non-negative on success/Negative on failure
1349
 *-------------------------------------------------------------------------
1350
 */
1351
herr_t
1352
H5Pget_append_flush(hid_t plist_id, unsigned ndims, hsize_t boundary[], H5D_append_cb_t *func /*out*/,
1353
                    void **udata /*out*/)
1354
0
{
1355
0
    H5P_genplist_t    *plist; /* property list pointer */
1356
0
    H5D_append_flush_t info;
1357
0
    unsigned           u;                   /* local index variable */
1358
0
    herr_t             ret_value = SUCCEED; /* return value */
1359
1360
0
    FUNC_ENTER_API(FAIL)
1361
1362
    /* Get the plist structure */
1363
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, true)))
1364
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1365
1366
    /* Retrieve info for append flush */
1367
0
    if (H5P_get(plist, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
1368
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object flush callback");
1369
1370
    /* Assign return values */
1371
0
    if (boundary) {
1372
0
        memset(boundary, 0, ndims * sizeof(hsize_t));
1373
0
        if (info.ndims > 0)
1374
0
            for (u = 0; u < info.ndims && u < ndims; u++)
1375
0
                boundary[u] = info.boundary[u];
1376
0
    } /* end if */
1377
0
    if (func)
1378
0
        *func = info.func;
1379
0
    if (udata)
1380
0
        *udata = info.udata;
1381
1382
0
done:
1383
0
    FUNC_LEAVE_API(ret_value)
1384
0
} /* H5Pget_append_flush() */
1385
1386
/*-------------------------------------------------------------------------
1387
 * Function:    H5Pset_efile_prefix
1388
 *
1389
 * Purpose:     Set a prefix to be used for any external files.
1390
 *
1391
 *              If the prefix starts with ${ORIGIN}, this will be replaced by
1392
 *              the absolute path of the directory of the HDF5 file containing
1393
 *              the dataset.
1394
 *
1395
 *              If the prefix is ".", no prefix will be applied.
1396
 *
1397
 *              This property can be overwritten by the environment variable
1398
 *              HDF5_EXTFILE_PREFIX.
1399
 *
1400
 * Return:      Non-negative on success/Negative on failure
1401
 *-------------------------------------------------------------------------
1402
 */
1403
herr_t
1404
H5Pset_efile_prefix(hid_t plist_id, const char *prefix)
1405
0
{
1406
0
    H5P_genplist_t *plist;               /* Property list pointer */
1407
0
    herr_t          ret_value = SUCCEED; /* Return value */
1408
1409
0
    FUNC_ENTER_API(FAIL)
1410
1411
    /* Get the plist structure */
1412
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, false)))
1413
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1414
1415
    /* Set prefix */
1416
0
    if (H5P_set(plist, H5D_ACS_EFILE_PREFIX_NAME, &prefix) < 0)
1417
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set prefix info");
1418
1419
0
done:
1420
0
    FUNC_LEAVE_API(ret_value)
1421
0
} /* end H5Pset_efile_prefix() */
1422
1423
/*-------------------------------------------------------------------------
1424
 * Function: H5Pget_efile_prefix
1425
 *
1426
 * Purpose:  Gets the prefix to be used for any external files.
1427
 *           If the pointer is not NULL, it points to a user-allocated
1428
 *           buffer.
1429
 *
1430
 * Return:   Non-negative on success/Negative on failure
1431
 *-------------------------------------------------------------------------
1432
 */
1433
ssize_t
1434
H5Pget_efile_prefix(hid_t plist_id, char *prefix /*out*/, size_t size)
1435
0
{
1436
0
    H5P_genplist_t *plist;     /* Property list pointer */
1437
0
    char           *my_prefix; /* Library's copy of the prefix */
1438
0
    size_t          len;       /* Length of prefix string */
1439
0
    ssize_t         ret_value; /* Return value */
1440
1441
0
    FUNC_ENTER_API(FAIL)
1442
1443
    /* Get the plist structure */
1444
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, true)))
1445
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1446
1447
    /* Get the current prefix */
1448
0
    if (H5P_peek(plist, H5D_ACS_EFILE_PREFIX_NAME, &my_prefix) < 0)
1449
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file prefix");
1450
1451
    /* Check for prefix being set */
1452
0
    if (my_prefix) {
1453
        /* Copy to user's buffer, if given */
1454
0
        len = strlen(my_prefix);
1455
0
        if (prefix) {
1456
0
            strncpy(prefix, my_prefix, size);
1457
0
            if (len >= size)
1458
0
                prefix[size - 1] = '\0';
1459
0
        } /* end if */
1460
0
    }     /* end if */
1461
0
    else
1462
0
        len = 0;
1463
1464
    /* Set return value */
1465
0
    ret_value = (ssize_t)len;
1466
1467
0
done:
1468
0
    FUNC_LEAVE_API(ret_value)
1469
0
} /* end H5Pget_efile_prefix() */
1470
1471
/*-------------------------------------------------------------------------
1472
 * Function:    H5Pset_virtual_prefix
1473
 *
1474
 * Purpose:     Set a prefix to be applied to the path of any vds files
1475
 *              traversed.
1476
 *
1477
 *              If the prefix starts with ${ORIGIN}, this will be replaced by
1478
 *              the absolute path of the directory of the HDF5 file containing
1479
 *              the dataset.
1480
 *
1481
 *              If the prefix is ".", no prefix will be applied.
1482
 *
1483
 *              This property can be overwritten by the environment variable
1484
 *              HDF5_VDS_PREFIX.
1485
 *
1486
 * Return:    Non-negative on success/Negative on failure
1487
 *-------------------------------------------------------------------------
1488
 */
1489
herr_t
1490
H5Pset_virtual_prefix(hid_t plist_id, const char *prefix)
1491
0
{
1492
0
    H5P_genplist_t *plist;               /* Property list pointer */
1493
0
    herr_t          ret_value = SUCCEED; /* Return value */
1494
1495
0
    FUNC_ENTER_API(FAIL)
1496
1497
    /* Get the plist structure */
1498
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, false)))
1499
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1500
1501
    /* Set prefix */
1502
0
    if (H5P_set(plist, H5D_ACS_VDS_PREFIX_NAME, &prefix) < 0)
1503
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set prefix info");
1504
1505
0
done:
1506
0
    FUNC_LEAVE_API(ret_value)
1507
0
} /* end H5Pset_virtual_prefix() */
1508
1509
/*-------------------------------------------------------------------------
1510
 * Function:    H5Pget_virtual_prefix
1511
 *
1512
 * Purpose:    Gets the prefix to be applied to any vds file
1513
 *              traversals made using this property list.
1514
 *
1515
 *              If the pointer is not NULL, it points to a user-allocated
1516
 *              buffer.
1517
 *
1518
 * Return:    Non-negative on success/Negative on failure
1519
 *-------------------------------------------------------------------------
1520
 */
1521
ssize_t
1522
H5Pget_virtual_prefix(hid_t plist_id, char *prefix /*out*/, size_t size)
1523
0
{
1524
0
    H5P_genplist_t *plist;     /* Property list pointer */
1525
0
    char           *my_prefix; /* Library's copy of the prefix */
1526
0
    size_t          len;       /* Length of prefix string */
1527
0
    ssize_t         ret_value; /* Return value */
1528
1529
0
    FUNC_ENTER_API(FAIL)
1530
1531
    /* Get the plist structure */
1532
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS, true)))
1533
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1534
1535
    /* Get the current prefix */
1536
0
    if (H5P_peek(plist, H5D_ACS_VDS_PREFIX_NAME, &my_prefix) < 0)
1537
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vds file prefix");
1538
1539
    /* Check for prefix being set */
1540
0
    if (my_prefix) {
1541
        /* Copy to user's buffer, if given */
1542
0
        len = strlen(my_prefix);
1543
0
        if (prefix) {
1544
0
            strncpy(prefix, my_prefix, size);
1545
0
            if (len >= size)
1546
0
                prefix[size - 1] = '\0';
1547
0
        } /* end if */
1548
0
    }     /* end if */
1549
0
    else
1550
0
        len = 0;
1551
1552
    /* Set return value */
1553
0
    ret_value = (ssize_t)len;
1554
1555
0
done:
1556
0
    FUNC_LEAVE_API(ret_value)
1557
0
} /* end H5Pget_virtual_prefix() */
1558
1559
/*-----------------------------------------------------------------------------
1560
 * Function: H5Pget_virtual_spatial_tree
1561
 *
1562
 * Purpose:
1563
 *
1564
 *     Access the flag for whether or not datasets created by the given dcpl
1565
 *     construct a spatial tree and use it when searching over VDS mappings
1566
 *
1567
 *     Use of a spatial tree will accelerate the process of searching through mappings
1568
 *     to determine which contain intersections with the user's selection region.
1569
 *     With the tree disabled, all mappings will simply be iterated through and
1570
 *     checked directly.
1571
 *
1572
 *     Certain workflows may find that tree creation overhead outweighs the time saved
1573
 *     on reads. In this case, disabling this property will lead to a performance improvement,
1574
 *     though it is expected that almost all cases will benefit from the tree on net.
1575
 *
1576
 * Return:
1577
 *
1578
 *     Failure: Negative value (FAIL)
1579
 *     Success: Non-negative value (SUCCEED)
1580
 *
1581
 *-----------------------------------------------------------------------------
1582
 */
1583
herr_t
1584
H5Pget_virtual_spatial_tree(hid_t dcpl_id, bool *use_tree)
1585
0
{
1586
0
    bool            setting   = false;
1587
0
    H5P_genplist_t *plist     = NULL;
1588
0
    herr_t          ret_value = SUCCEED;
1589
1590
0
    FUNC_ENTER_API(FAIL)
1591
1592
0
    if (NULL == use_tree)
1593
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "receiving pointer cannot be NULL");
1594
1595
0
    plist = H5P_object_verify(dcpl_id, H5P_DATASET_ACCESS, true);
1596
0
    if (NULL == plist)
1597
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1598
1599
0
    if (H5P_peek(plist, H5D_ACS_USE_TREE_NAME, &setting) < 0)
1600
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dset use spatial tree flag value");
1601
1602
0
    *use_tree = setting;
1603
1604
0
done:
1605
0
    FUNC_LEAVE_API(ret_value)
1606
0
} /* H5Pget_virtual_spatial_tree() */
1607
1608
/*-----------------------------------------------------------------------------
1609
 * Function: H5Pset_virtual_spatial_tree
1610
 *
1611
 * Purpose:
1612
 *
1613
 *     Set the DAPL to construct a spatial tree and use it when searching over
1614
 *     VDS mappings
1615
 *
1616
 *     Use of a spatial tree will accelerate the process of searching through mappings
1617
 *     to determine which contain intersections with the user's selection region.
1618
 *     With the tree disabled, all mappings will simply be iterated through and
1619
 *     checked directly.
1620
 *
1621
 *     Certain workflows may find that tree creation overhead outweighs the time saved
1622
 *     on reads. In this case, disabling this property will lead to a performance improvement,
1623
 *     though it is expected that almost all cases will benefit from the tree on net.
1624
 *
1625
 * Return:
1626
 *
1627
 *     Failure: Negative value (FAIL)
1628
 *     Success: Non-negative value (SUCCEED)
1629
 *
1630
 *-----------------------------------------------------------------------------
1631
 */
1632
herr_t
1633
H5Pset_virtual_spatial_tree(hid_t dapl_id, bool use_tree)
1634
0
{
1635
0
    H5P_genplist_t *plist     = NULL;
1636
0
    bool            prev_set  = false;
1637
0
    herr_t          ret_value = SUCCEED;
1638
1639
0
    FUNC_ENTER_API(FAIL)
1640
1641
0
    plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS, false);
1642
0
    if (NULL == plist)
1643
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1644
1645
0
    if (H5P_peek(plist, H5D_ACS_USE_TREE_NAME, &prev_set) < 0)
1646
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get extant dset use spatial tree flag value");
1647
1648
0
    if (H5P_poke(plist, H5D_ACS_USE_TREE_NAME, &use_tree) < 0)
1649
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set dset use spatial tree flag value");
1650
1651
0
done:
1652
    FUNC_LEAVE_API(ret_value)
1653
0
} /* H5Pset_virtual_spatial_tree() */