Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5M.c
Line
Count
Source (jump to first uncovered line)
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 COPYING 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
/* Module Setup */
15
/****************/
16
17
#include "H5Mmodule.h" /* This source code file is part of the H5M module */
18
19
/***********/
20
/* Headers */
21
/***********/
22
#include "H5private.h"   /* Generic Functions                        */
23
#include "H5CXprivate.h" /* API Contexts                             */
24
#include "H5Mpkg.h"      /* Maps                                     */
25
#include "H5Eprivate.h"  /* Error handling                           */
26
#include "H5ESprivate.h" /* Event Sets                               */
27
#include "H5Iprivate.h"  /* IDs                                      */
28
#include "H5VLprivate.h" /* Virtual Object Layer                     */
29
30
/****************/
31
/* Local Macros */
32
/****************/
33
34
/******************/
35
/* Local Typedefs */
36
/******************/
37
38
/********************/
39
/* Local Prototypes */
40
/********************/
41
static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request);
42
43
#ifdef H5_HAVE_MAP_API
44
static hid_t  H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id,
45
                                     hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, void **token_ptr,
46
                                     H5VL_object_t **_vol_obj_ptr);
47
static hid_t  H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr,
48
                                   H5VL_object_t **_vol_obj_ptr);
49
static herr_t H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
50
                                  const void *value, hid_t dxpl_id, void **token_ptr,
51
                                  H5VL_object_t **_vol_obj_ptr);
52
static herr_t H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
53
                                  void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
54
#endif /*  H5_HAVE_MAP_API */
55
56
/*********************/
57
/* Package Variables */
58
/*********************/
59
60
/*****************************/
61
/* Library Private Variables */
62
/*****************************/
63
64
/*******************/
65
/* Local Variables */
66
/*******************/
67
68
/* Map ID class */
69
static const H5I_class_t H5I_MAP_CLS[1] = {{
70
    H5I_MAP,                  /* ID class value */
71
    0,                        /* Class flags */
72
    0,                        /* # of reserved IDs for class */
73
    (H5I_free_t)H5M__close_cb /* Callback routine for closing objects of this class */
74
}};
75
76
/*-------------------------------------------------------------------------
77
 * Function: H5M_init
78
 *
79
 * Purpose:  Initialize the interface from some other layer.
80
 *
81
 * Return:   Success:    non-negative
82
 *
83
 *           Failure:    negative
84
 *-------------------------------------------------------------------------
85
 */
86
herr_t
87
H5M_init(void)
88
1
{
89
1
    herr_t ret_value = SUCCEED; /* Return value */
90
91
1
    FUNC_ENTER_NOAPI(FAIL)
92
93
    /* Initialize the ID group for the map IDs */
94
1
    if (H5I_register_type(H5I_MAP_CLS) < 0)
95
0
        HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, FAIL, "unable to initialize interface");
96
97
1
done:
98
1
    FUNC_LEAVE_NOAPI(ret_value)
99
1
} /* end H5M_init() */
100
101
/*-------------------------------------------------------------------------
102
 * Function: H5M_top_term_package
103
 *
104
 * Purpose:  Close the "top" of the interface, releasing IDs, etc.
105
 *
106
 * Return:   Success:    Positive if anything was done that might
107
 *                affect other interfaces; zero otherwise.
108
 *           Failure:    Negative.
109
 *-------------------------------------------------------------------------
110
 */
111
int
112
H5M_top_term_package(void)
113
1
{
114
1
    int n = 0;
115
116
1
    FUNC_ENTER_NOAPI_NOINIT_NOERR
117
118
1
    if (H5I_nmembers(H5I_MAP) > 0) {
119
0
        (void)H5I_clear_type(H5I_MAP, false, false);
120
0
        n++;
121
0
    }
122
123
1
    FUNC_LEAVE_NOAPI(n)
124
1
} /* end H5M_top_term_package() */
125
126
/*-------------------------------------------------------------------------
127
 * Function: H5M_term_package
128
 *
129
 * Purpose:  Terminate this interface.
130
 *
131
 * Note:     Finishes shutting down the interface, after
132
 *           H5M_top_term_package() is called
133
 *
134
 * Return:   Success:    Positive if anything was done that might
135
 *                affect other interfaces; zero otherwise.
136
 *            Failure:    Negative.
137
 *-------------------------------------------------------------------------
138
 */
139
int
140
H5M_term_package(void)
141
1
{
142
1
    int n = 0;
143
144
1
    FUNC_ENTER_NOAPI_NOINIT_NOERR
145
146
    /* Sanity checks */
147
1
    assert(0 == H5I_nmembers(H5I_MAP));
148
149
    /* Destroy the dataset object id group */
150
1
    n += (H5I_dec_type_ref(H5I_MAP) > 0);
151
152
1
    FUNC_LEAVE_NOAPI(n)
153
1
} /* end H5M_term_package() */
154
155
/*-------------------------------------------------------------------------
156
 * Function:    H5M__close_cb
157
 *
158
 * Purpose:     Called when the ref count reaches zero on the map's ID
159
 *
160
 * Return:      SUCCEED/FAIL
161
 *
162
 *-------------------------------------------------------------------------
163
 */
164
static herr_t
165
H5M__close_cb(H5VL_object_t *map_vol_obj, void **request)
166
0
{
167
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
168
0
    herr_t               ret_value = SUCCEED; /* Return value */
169
170
0
    FUNC_ENTER_PACKAGE
171
172
    /* Sanity check */
173
0
    assert(map_vol_obj);
174
175
    /* Set up VOL callback arguments */
176
0
    vol_cb_args.op_type = H5VL_MAP_CLOSE;
177
0
    vol_cb_args.args    = NULL;
178
179
    /* Close the map */
180
0
    if (H5VL_optional(map_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, request) < 0)
181
0
        HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map");
182
183
    /* Free the VOL object */
184
0
    if (H5VL_free_object(map_vol_obj) < 0)
185
0
        HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "unable to free VOL object");
186
187
0
done:
188
0
    FUNC_LEAVE_NOAPI(ret_value)
189
0
} /* end H5M__close_cb() */
190
191
#ifdef H5_HAVE_MAP_API
192
193
/*-------------------------------------------------------------------------
194
 * Function:    H5M__create_api_common
195
 *
196
 * Purpose:     This is the common function for creating the HDF5 map.
197
 *
198
 * Return:      Success:    The object ID of the new map.
199
 *
200
 *              Failure:    H5I_INVALID_HID
201
 *
202
 *-------------------------------------------------------------------------
203
 */
204
static hid_t
205
H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id,
206
                       hid_t mcpl_id, hid_t mapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
207
{
208
    void           *map         = NULL; /* New map's info */
209
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
210
    H5VL_object_t **vol_obj_ptr =
211
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
212
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
213
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
214
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
215
216
    FUNC_ENTER_PACKAGE
217
218
    /* Check arguments */
219
    if (!name)
220
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL");
221
    if (!*name)
222
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string");
223
224
    /* Get link creation property list */
225
    if (H5P_DEFAULT == lcpl_id)
226
        lcpl_id = H5P_LINK_CREATE_DEFAULT;
227
    else if (true != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
228
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "lcpl_id is not a link creation property list");
229
230
    /* Get map creation property list */
231
    if (H5P_DEFAULT == mcpl_id)
232
        mcpl_id = H5P_MAP_CREATE_DEFAULT;
233
    else if (true != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
234
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID");
235
236
    /* Set up VOL callback arguments */
237
    if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, true, &mapl_id, vol_obj_ptr, &map_args.create.loc_params) <
238
        0)
239
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
240
    map_args.create.name        = name;
241
    map_args.create.lcpl_id     = lcpl_id;
242
    map_args.create.key_type_id = key_type_id;
243
    map_args.create.val_type_id = val_type_id;
244
    map_args.create.mcpl_id     = mcpl_id;
245
    map_args.create.mapl_id     = mapl_id;
246
    map_args.create.map         = NULL;
247
    vol_cb_args.op_type         = H5VL_MAP_CREATE;
248
    vol_cb_args.args            = &map_args;
249
250
    /* Create the map */
251
    if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
252
        HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map");
253
    map = map_args.create.map;
254
255
    /* Get an ID for the map */
256
    if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, true)) < 0)
257
        HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map handle");
258
259
done:
260
    /* Cleanup on failure */
261
    if (H5I_INVALID_HID == ret_value) {
262
        /* Set up VOL callback arguments */
263
        vol_cb_args.op_type = H5VL_MAP_CLOSE;
264
        vol_cb_args.args    = NULL;
265
266
        if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
267
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map");
268
    } /* end if */
269
270
    FUNC_LEAVE_NOAPI(ret_value)
271
} /* end H5M__create_api_common() */
272
273
/*-------------------------------------------------------------------------
274
 * Function:    H5Mcreate
275
 *
276
 * Purpose:     Creates a new map object for storing key-value pairs.  The
277
 *              in-file datatype for keys is defined by KEY_TYPE_ID and
278
 *              the in-file datatype for values is defined by VAL_TYPE_ID.
279
 *              LOC_ID specifies the location to create the map object and
280
 *              NAME specifies the name of the link to the object
281
 *              (relative to LOC_ID).  Other options can be specified
282
 *              through the property lists LCPL_ID, MCPL_ID, and MAPL_ID.
283
 *
284
 * Return:      Success:    The object ID of the new map.
285
 *
286
 *              Failure:    H5I_INVALID_HID
287
 *
288
 *-------------------------------------------------------------------------
289
 */
290
hid_t
291
H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id,
292
          hid_t mapl_id)
293
{
294
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
295
296
    FUNC_ENTER_API(H5I_INVALID_HID)
297
298
    /* Create the map synchronously */
299
    if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id,
300
                                            NULL, NULL)) < 0)
301
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map synchronously");
302
303
done:
304
    FUNC_LEAVE_API(ret_value)
305
} /* end H5Mcreate() */
306
307
/*-------------------------------------------------------------------------
308
 * Function:    H5Mcreate_async
309
 *
310
 * Purpose:     Asynchronous version of H5Mcreate
311
 *
312
 * Return:      Success:    The object ID of the new map.
313
 *
314
 *              Failure:    H5I_INVALID_HID
315
 *
316
 *-------------------------------------------------------------------------
317
 */
318
hid_t
319
H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
320
                hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id,
321
                hid_t es_id)
322
{
323
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
324
    void          *token     = NULL;            /* Request token for async operation        */
325
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
326
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
327
328
    FUNC_ENTER_API(H5I_INVALID_HID)
329
330
    /* Set up request token pointer for asynchronous operation */
331
    if (H5ES_NONE != es_id)
332
        token_ptr = &token;
333
334
    /* Create the map asynchronously */
335
    if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id,
336
                                            token_ptr, &vol_obj)) < 0)
337
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map asynchronously");
338
339
    /* If a token was created, add the token to the event set */
340
    if (NULL != token)
341
        /* clang-format off */
342
        if (H5ES_insert(es_id, vol_obj->connector, token,
343
                        H5ARG_TRACE11(__func__, "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, es_id)) < 0) {
344
            /* clang-format on */
345
            if (H5I_dec_app_ref_always_close(ret_value) < 0)
346
                HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID");
347
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
348
        } /* end if */
349
350
done:
351
    FUNC_LEAVE_API(ret_value)
352
} /* end H5Mcreate_async() */
353
354
/*-------------------------------------------------------------------------
355
 * Function:    H5Mcreate_anon
356
 *
357
 * Purpose:     Creates a new map object for storing key-value pairs.  The
358
 *              in-file datatype for keys is defined by KEY_TYPE_ID and
359
 *              the in-file datatype for values is defined by VAL_TYPE_ID.
360
 *              LOC_ID specifies the file to create the map object, but no
361
 *              link to the object is created.  Other options can be
362
 *              specified through the property lists LCPL_ID, MCPL_ID, and
363
 *              MAPL_ID.
364
 *
365
 *              The resulting ID should be linked into the file with
366
 *              H5Olink or it will be deleted when closed.
367
 *
368
 * Return:      Success:    The object ID of the new map. The map should
369
 *                          be linked into the group hierarchy before being closed or
370
 *                          it will be deleted. The dataset should be
371
 *                          closed when the caller is no longer interested
372
 *                          in it.
373
 *
374
 *              Failure:    H5I_INVALID_HID
375
 *
376
 *-------------------------------------------------------------------------
377
 */
378
hid_t
379
H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id)
380
{
381
    void                *map     = NULL;              /* map object from VOL connector */
382
    H5VL_object_t       *vol_obj = NULL;              /* object of loc_id */
383
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
384
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
385
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
386
387
    FUNC_ENTER_API(H5I_INVALID_HID)
388
389
    /* Check arguments */
390
    if (H5P_DEFAULT == mcpl_id)
391
        mcpl_id = H5P_MAP_CREATE_DEFAULT;
392
    else if (true != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
393
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not map create property list ID");
394
395
    /* Verify access property list and set up collective metadata if appropriate */
396
    if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, true) < 0)
397
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info");
398
399
    /* get the location object */
400
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
401
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier");
402
403
    /* Set location parameters */
404
405
    /* Set up VOL callback arguments */
406
    map_args.create.loc_params.type     = H5VL_OBJECT_BY_SELF;
407
    map_args.create.loc_params.obj_type = H5I_get_type(loc_id);
408
    map_args.create.name                = NULL;
409
    map_args.create.lcpl_id             = H5P_LINK_CREATE_DEFAULT;
410
    map_args.create.key_type_id         = key_type_id;
411
    map_args.create.val_type_id         = val_type_id;
412
    map_args.create.mcpl_id             = mcpl_id;
413
    map_args.create.mapl_id             = mapl_id;
414
    map_args.create.map                 = NULL;
415
    vol_cb_args.op_type                 = H5VL_MAP_CREATE;
416
    vol_cb_args.args                    = &map_args;
417
418
    /* Create the map */
419
    if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
420
        HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map");
421
    map = map_args.create.map;
422
423
    /* Get an ID for the map */
424
    if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, true)) < 0)
425
        HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map");
426
427
done:
428
    /* Cleanup on failure */
429
    if (H5I_INVALID_HID == ret_value) {
430
        /* Set up VOL callback arguments */
431
        vol_cb_args.op_type = H5VL_MAP_CLOSE;
432
        vol_cb_args.args    = NULL;
433
434
        if (map && H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
435
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map");
436
    } /* end if */
437
438
    FUNC_LEAVE_API(ret_value)
439
} /* end H5Mcreate_anon() */
440
441
/*------------------------------------------------------------------------
442
 * Function:    H5M__open_api_common
443
 *
444
 * Purpose:     This is the common function for opening the HDF5 map.
445
 *
446
 * Return:      Success:    Object ID of the map
447
 *
448
 *              Failure:    H5I_INVALID_HID
449
 *
450
 *-------------------------------------------------------------------------
451
 */
452
static hid_t
453
H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr,
454
                     H5VL_object_t **_vol_obj_ptr)
455
{
456
    void           *map         = NULL; /* map object from VOL connector */
457
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
458
    H5VL_object_t **vol_obj_ptr =
459
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
460
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
461
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
462
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
463
464
    FUNC_ENTER_PACKAGE
465
466
    /* Check args */
467
    if (!name)
468
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL");
469
    if (!*name)
470
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string");
471
472
    /* Set up VOL callback arguments */
473
    if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, false, &mapl_id, vol_obj_ptr, &map_args.open.loc_params) <
474
        0)
475
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
476
    map_args.open.name    = name;
477
    map_args.open.mapl_id = mapl_id;
478
    map_args.open.map     = NULL;
479
    vol_cb_args.op_type   = H5VL_MAP_OPEN;
480
    vol_cb_args.args      = &map_args;
481
482
    /* Open the map */
483
    if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
484
        HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map");
485
    map = map_args.open.map;
486
487
    /* Register an ID for the map */
488
    if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, true)) < 0)
489
        HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map ID");
490
491
done:
492
    /* Cleanup on failure */
493
    if (H5I_INVALID_HID == ret_value) {
494
        /* Set up VOL callback arguments */
495
        vol_cb_args.op_type = H5VL_MAP_CLOSE;
496
        vol_cb_args.args    = NULL;
497
498
        if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
499
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map");
500
    } /* end if */
501
502
    FUNC_LEAVE_NOAPI(ret_value)
503
} /* end H5M__open_api_common() */
504
505
/*------------------------------------------------------------------------
506
 * Function:    H5Mopen
507
 *
508
 * Purpose:     Finds a map named NAME at LOC_ID, opens it, and returns
509
 *              its ID. The map should be close when the caller is no
510
 *              longer interested in it.
511
 *
512
 *              Takes a map access property list
513
 *
514
 * Return:      Success:    Object ID of the map
515
 *
516
 *              Failure:    H5I_INVALID_HID
517
 *
518
 *-------------------------------------------------------------------------
519
 */
520
hid_t
521
H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
522
{
523
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
524
525
    FUNC_ENTER_API(H5I_INVALID_HID)
526
527
    /* Open the map synchronously */
528
    if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, NULL, NULL)) < 0)
529
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously");
530
531
done:
532
    FUNC_LEAVE_API(ret_value)
533
} /* end H5Mopen() */
534
535
/*------------------------------------------------------------------------
536
 * Function:    H5Mopen_async
537
 *
538
 * Purpose:     Asynchronous version of H5Mopen
539
 *
540
 * Return:      Success:    Object ID of the map
541
 *
542
 *              Failure:    H5I_INVALID_HID
543
 *
544
 *-------------------------------------------------------------------------
545
 */
546
hid_t
547
H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
548
              hid_t mapl_id, hid_t es_id)
549
{
550
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
551
    void          *token     = NULL;            /* Request token for async operation        */
552
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
553
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
554
555
    FUNC_ENTER_API(H5I_INVALID_HID)
556
557
    /* Set up request token pointer for asynchronous operation */
558
    if (H5ES_NONE != es_id)
559
        token_ptr = &token;
560
561
    /* Open the map asynchronously */
562
    if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, token_ptr, &vol_obj)) < 0)
563
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map asynchronously");
564
565
    /* If a token was created, add the token to the event set */
566
    if (NULL != token)
567
        /* clang-format off */
568
        if (H5ES_insert(es_id, vol_obj->connector, token,
569
                        H5ARG_TRACE7(__func__, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id)) < 0) {
570
            /* clang-format on */
571
            if (H5I_dec_app_ref_always_close(ret_value) < 0)
572
                HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID");
573
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
574
        } /* end if */
575
576
done:
577
    FUNC_LEAVE_API(ret_value)
578
} /* end H5Mopen_async() */
579
580
/*-------------------------------------------------------------------------
581
 * Function:    H5Mclose
582
 *
583
 * Purpose:     Closes access to a map and releases resources used by it.
584
 *              It is illegal to subsequently use that same map ID in
585
 *              calls to other map functions.
586
 *
587
 * Return:      SUCCEED/FAIL
588
 *
589
 *-------------------------------------------------------------------------
590
 */
591
herr_t
592
H5Mclose(hid_t map_id)
593
{
594
    herr_t ret_value = SUCCEED; /* Return value                     */
595
596
    FUNC_ENTER_API(FAIL)
597
598
    /* Check args */
599
    if (H5I_MAP != H5I_get_type(map_id))
600
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID");
601
602
    /* Decrement the counter on the map.  It will be freed if the count
603
     * reaches zero.
604
     */
605
    if (H5I_dec_app_ref_always_close(map_id) < 0)
606
        HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on map ID");
607
608
done:
609
    FUNC_LEAVE_API(ret_value)
610
} /* end H5Mclose() */
611
612
/*-------------------------------------------------------------------------
613
 * Function:    H5Mclose_async
614
 *
615
 * Purpose:     Asynchronous version of H5Mclose
616
 *
617
 * Return:      SUCCEED/FAIL
618
 *
619
 *-------------------------------------------------------------------------
620
 */
621
herr_t
622
H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t es_id)
623
{
624
    void          *token     = NULL;            /* Request token for async operation            */
625
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
626
    H5VL_object_t *vol_obj   = NULL;            /* VOL object of dset_id */
627
    H5VL_t        *connector = NULL;            /* VOL connector */
628
    herr_t         ret_value = SUCCEED;         /* Return value */
629
630
    FUNC_ENTER_API(FAIL)
631
632
    /* Check args */
633
    if (H5I_MAP != H5I_get_type(map_id))
634
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID");
635
636
    /* Get map object's connector */
637
    if (NULL == (vol_obj = H5VL_vol_object(map_id)))
638
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get VOL object for map");
639
640
    /* Prepare for possible asynchronous operation */
641
    if (H5ES_NONE != es_id) {
642
        /* Increase connector's refcount, so it doesn't get closed if closing
643
         * the dataset closes the file */
644
        connector = vol_obj->connector;
645
        H5VL_conn_inc_rc(connector);
646
647
        /* Point at token for operation to set up */
648
        token_ptr = &token;
649
    } /* end if */
650
651
    /* Decrement the counter on the map.  It will be freed if the count
652
     * reaches zero.
653
     */
654
    if (H5I_dec_app_ref_always_close_async(map_id, token_ptr) < 0)
655
        HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID");
656
657
    /* If a token was created, add the token to the event set */
658
    if (NULL != token)
659
        /* clang-format off */
660
        if (H5ES_insert(es_id, vol_obj->connector, token,
661
                        H5ARG_TRACE5(__func__, "*s*sIuii", app_file, app_func, app_line, map_id, es_id)) < 0)
662
            /* clang-format on */
663
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set");
664
665
done:
666
    if (connector && H5VL_conn_dec_rc(connector) < 0)
667
        HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement ref count on connector");
668
669
    FUNC_LEAVE_API(ret_value)
670
} /* end H5Mclose_async() */
671
672
/*-------------------------------------------------------------------------
673
 * Function:    H5Mget_key_type
674
 *
675
 * Purpose:     Returns a copy of the key datatype for a map.
676
 *
677
 * Return:      Success:    ID for a copy of the datatype. The data
678
 *                          type should be released by calling
679
 *                          H5Tclose().
680
 *
681
 *              Failure:    H5I_INVALID_HID
682
 *
683
 *-------------------------------------------------------------------------
684
 */
685
hid_t
686
H5Mget_key_type(hid_t map_id)
687
{
688
    H5VL_object_t       *vol_obj;                     /* Map structure    */
689
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
690
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
691
    hid_t                ret_value = H5I_INVALID_HID; /* Return value         */
692
693
    FUNC_ENTER_API(H5I_INVALID_HID)
694
695
    /* Check args */
696
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
697
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier");
698
699
    /* Set up VOL callback arguments */
700
    map_args.get.get_type                  = H5VL_MAP_GET_KEY_TYPE;
701
    map_args.get.args.get_key_type.type_id = H5I_INVALID_HID;
702
    vol_cb_args.op_type                    = H5VL_MAP_GET;
703
    vol_cb_args.args                       = &map_args;
704
705
    /* Get the key datatype */
706
    if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
707
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get key datatype");
708
709
    /* Set return value */
710
    ret_value = map_args.get.args.get_key_type.type_id;
711
712
done:
713
    FUNC_LEAVE_API(ret_value)
714
} /* end H5Mget_key_type() */
715
716
/*-------------------------------------------------------------------------
717
 * Function:    H5Mget_val_type
718
 *
719
 * Purpose:     Returns a copy of the value datatype for a map.
720
 *
721
 * Return:      Success:    ID for a copy of the datatype. The data
722
 *                          type should be released by calling
723
 *                          H5Tclose().
724
 *
725
 *              Failure:    H5I_INVALID_HID
726
 *
727
 *-------------------------------------------------------------------------
728
 */
729
hid_t
730
H5Mget_val_type(hid_t map_id)
731
{
732
    H5VL_object_t       *vol_obj;                     /* Map structure    */
733
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
734
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
735
    hid_t                ret_value = H5I_INVALID_HID; /* Return value         */
736
737
    FUNC_ENTER_API(H5I_INVALID_HID)
738
739
    /* Check args */
740
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
741
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier");
742
743
    /* Set up VOL callback arguments */
744
    map_args.get.get_type                  = H5VL_MAP_GET_VAL_TYPE;
745
    map_args.get.args.get_val_type.type_id = H5I_INVALID_HID;
746
    vol_cb_args.op_type                    = H5VL_MAP_GET;
747
    vol_cb_args.args                       = &map_args;
748
749
    /* Get the value datatype */
750
    if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
751
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get value datatype");
752
753
    /* Set return value */
754
    ret_value = map_args.get.args.get_val_type.type_id;
755
756
done:
757
    FUNC_LEAVE_API(ret_value)
758
} /* end H5Mget_val_type() */
759
760
/*-------------------------------------------------------------------------
761
 * Function:    H5Mget_create_plist
762
 *
763
 * Purpose:     Returns a copy of the map creation property list.
764
 *
765
 * Return:      Success:    ID for a copy of the map creation
766
 *                          property list.  The template should be
767
 *                          released by calling H5P_close().
768
 *
769
 *              Failure:    H5I_INVALID_HID
770
 *
771
 *-------------------------------------------------------------------------
772
 */
773
hid_t
774
H5Mget_create_plist(hid_t map_id)
775
{
776
    H5VL_object_t       *vol_obj;                     /* Map structure    */
777
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
778
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
779
    hid_t                ret_value = H5I_INVALID_HID; /* Return value         */
780
781
    FUNC_ENTER_API(H5I_INVALID_HID)
782
783
    /* Check args */
784
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
785
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier");
786
787
    /* Set up VOL callback arguments */
788
    map_args.get.get_type              = H5VL_MAP_GET_MCPL;
789
    map_args.get.args.get_mcpl.mcpl_id = H5I_INVALID_HID;
790
    vol_cb_args.op_type                = H5VL_MAP_GET;
791
    vol_cb_args.args                   = &map_args;
792
793
    /* Get the map creation property list */
794
    if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
795
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map creation properties");
796
797
    /* Set return value */
798
    ret_value = map_args.get.args.get_mcpl.mcpl_id;
799
800
done:
801
    FUNC_LEAVE_API(ret_value)
802
} /* end H5Mget_create_plist() */
803
804
/*-------------------------------------------------------------------------
805
 * Function:    H5Mget_access_plist
806
 *
807
 * Purpose:     Returns a copy of the map access property list.
808
 *
809
 * Description: H5Mget_access_plist returns the map access property
810
 *              list identifier of the specified map.
811
 *
812
 * Return:      Success:    ID for a copy of the map access
813
 *                          property list.  The template should be
814
 *                          released by calling H5Pclose().
815
 *
816
 *              Failure:    H5I_INVALID_HID
817
 *
818
 *-------------------------------------------------------------------------
819
 */
820
hid_t
821
H5Mget_access_plist(hid_t map_id)
822
{
823
    H5VL_object_t       *vol_obj;                     /* Map structure    */
824
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
825
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
826
    hid_t                ret_value = H5I_INVALID_HID; /* Return value         */
827
828
    FUNC_ENTER_API(H5I_INVALID_HID)
829
830
    /* Check args */
831
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
832
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier");
833
834
    /* Set up VOL callback arguments */
835
    map_args.get.get_type              = H5VL_MAP_GET_MAPL;
836
    map_args.get.args.get_mapl.mapl_id = H5I_INVALID_HID;
837
    vol_cb_args.op_type                = H5VL_MAP_GET;
838
    vol_cb_args.args                   = &map_args;
839
840
    /* Get the map access property list */
841
    if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
842
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties");
843
844
    /* Set return value */
845
    ret_value = map_args.get.args.get_mapl.mapl_id;
846
847
done:
848
    FUNC_LEAVE_API(ret_value)
849
} /* end H5Mget_access_plist() */
850
851
/*-------------------------------------------------------------------------
852
 * Function:    H5Mget_count
853
 *
854
 * Purpose:     Returns the number of key-value pairs stored in the map.
855
 *
856
 * Description: H5Mget_count returns the number of key-value pairs stored
857
 *              in the specified map.
858
 *
859
 * Return:      SUCCEED/FAIL
860
 *
861
 *-------------------------------------------------------------------------
862
 */
863
herr_t
864
H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id)
865
{
866
    H5VL_object_t       *vol_obj;             /* Map structure    */
867
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
868
    H5VL_map_args_t      map_args;            /* Arguments for map operations */
869
    herr_t               ret_value = SUCCEED; /* Return value         */
870
871
    FUNC_ENTER_API(H5I_INVALID_HID)
872
873
    /* Check args */
874
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
875
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier");
876
877
    /* Get the default dataset transfer property list if the user didn't provide one */
878
    if (H5P_DEFAULT == dxpl_id)
879
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
880
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
881
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
882
883
    /* Set up VOL callback arguments */
884
    map_args.get.get_type             = H5VL_MAP_GET_COUNT;
885
    map_args.get.args.get_count.count = 0;
886
    vol_cb_args.op_type               = H5VL_MAP_GET;
887
    vol_cb_args.args                  = &map_args;
888
889
    /* Get the number of key-value pairs stored in the map */
890
    if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0)
891
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get KV pair count for map");
892
893
    /* Set value to return */
894
    if (count)
895
        *count = map_args.get.args.get_count.count;
896
897
done:
898
    FUNC_LEAVE_API(ret_value)
899
} /* end H5Mget_count() */
900
901
/*-------------------------------------------------------------------------
902
 * Function:    H5M__put_api_common
903
 *
904
 * Purpose:     This is the common function for putting value to map.
905
 *
906
 * Return:      SUCCEED/FAIL
907
 *
908
 *-------------------------------------------------------------------------
909
 */
910
static herr_t
911
H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
912
                    const void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
913
{
914
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
915
    H5VL_object_t **vol_obj_ptr =
916
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
917
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
918
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
919
    herr_t               ret_value = SUCCEED;         /* Return value */
920
921
    FUNC_ENTER_PACKAGE
922
923
    /* Check arguments */
924
    if (key_mem_type_id < 0)
925
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID");
926
    if (val_mem_type_id < 0)
927
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID");
928
929
    /* Get map pointer */
930
    if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
931
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID");
932
933
    /* Get the default dataset transfer property list if the user didn't provide one */
934
    if (H5P_DEFAULT == dxpl_id)
935
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
936
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
937
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
938
939
    /* Set up VOL callback arguments */
940
    map_args.put.key_mem_type_id   = key_mem_type_id;
941
    map_args.put.key               = key;
942
    map_args.put.value_mem_type_id = val_mem_type_id;
943
    map_args.put.value             = value;
944
    vol_cb_args.op_type            = H5VL_MAP_PUT;
945
    vol_cb_args.args               = &map_args;
946
947
    /* Set the key/value pair */
948
    if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0)
949
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair");
950
951
done:
952
    FUNC_LEAVE_NOAPI(ret_value)
953
} /* end H5M__put_api_common() */
954
955
/*-------------------------------------------------------------------------
956
 * Function:    H5Mput
957
 *
958
 * Purpose:     H5Mput adds a key-value pair to the Map specified by
959
 *              MAP_ID, or updates the value for the specified key if one
960
 *              was set previously. KEY_MEM_TYPE_ID and VAL_MEM_TYPE_ID
961
 *              specify the datatypes for the provided KEY and VALUE
962
 *              buffers, and if different from those used to create the
963
 *              map object, the key and value will be internally converted
964
 *              to the datatypes for the map object. Any further options
965
 *              can be specified through the property list DXPL_ID.
966
 *
967
 * Return:      SUCCEED/FAIL
968
 *
969
 *-------------------------------------------------------------------------
970
 */
971
herr_t
972
H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value,
973
       hid_t dxpl_id)
974
{
975
    herr_t ret_value = SUCCEED; /* Return value */
976
977
    FUNC_ENTER_API(FAIL)
978
979
    /* Add key-value pair to the map synchronously */
980
    if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL,
981
                                         NULL)) < 0)
982
        HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map synchronously");
983
984
done:
985
    FUNC_LEAVE_API(ret_value)
986
} /* end H5Mput() */
987
988
/*-------------------------------------------------------------------------
989
 * Function:    H5Mput_async
990
 *
991
 * Purpose:     Asynchronous version of H5Mput
992
 *
993
 * Return:      SUCCEED/FAIL
994
 *
995
 *-------------------------------------------------------------------------
996
 */
997
herr_t
998
H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
999
             hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id,
1000
             hid_t es_id)
1001
{
1002
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
1003
    void          *token     = NULL;            /* Request token for async operation        */
1004
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1005
    herr_t         ret_value = SUCCEED;         /* Return value */
1006
1007
    FUNC_ENTER_API(FAIL)
1008
1009
    /* Set up request token pointer for asynchronous operation */
1010
    if (H5ES_NONE != es_id)
1011
        token_ptr = &token;
1012
1013
    /* Add key-value pair to the map asynchronously */
1014
    if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id,
1015
                                         token_ptr, &vol_obj)) < 0)
1016
        HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map asynchronously");
1017
1018
    /* If a token was created, add the token to the event set */
1019
    if (NULL != token)
1020
        /* clang-format off */
1021
        if (H5ES_insert(es_id, vol_obj->connector, token,
1022
                        H5ARG_TRACE10(__func__, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0)
1023
            /* clang-format on */
1024
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1025
1026
done:
1027
    FUNC_LEAVE_API(ret_value)
1028
} /* end H5Mput_async() */
1029
1030
/*-------------------------------------------------------------------------
1031
 * Function:    H5M__get_api_common
1032
 *
1033
 * Purpose:     This is common function for getting value from the map.
1034
 *
1035
 * Return:      SUCCEED/FAIL
1036
 *
1037
 *-------------------------------------------------------------------------
1038
 */
1039
static herr_t
1040
H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
1041
                    hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
1042
{
1043
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
1044
    H5VL_object_t **vol_obj_ptr =
1045
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
1046
    H5VL_optional_args_t vol_cb_args;                 /* Arguments to VOL callback */
1047
    H5VL_map_args_t      map_args;                    /* Arguments for map operations */
1048
    herr_t               ret_value = SUCCEED;         /* Return value */
1049
1050
    FUNC_ENTER_PACKAGE
1051
1052
    /* Check arguments */
1053
    if (key_mem_type_id < 0)
1054
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID");
1055
    if (val_mem_type_id < 0)
1056
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID");
1057
1058
    /* Get map pointer */
1059
    if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
1060
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID");
1061
1062
    /* Get the default dataset transfer property list if the user didn't provide one */
1063
    if (H5P_DEFAULT == dxpl_id)
1064
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
1065
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1066
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
1067
1068
    /* Set up VOL callback arguments */
1069
    map_args.get_val.key_mem_type_id   = key_mem_type_id;
1070
    map_args.get_val.key               = key;
1071
    map_args.get_val.value_mem_type_id = val_mem_type_id;
1072
    map_args.get_val.value             = value;
1073
    vol_cb_args.op_type                = H5VL_MAP_GET_VAL;
1074
    vol_cb_args.args                   = &map_args;
1075
1076
    /* Get the value for the key */
1077
    if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0)
1078
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map");
1079
1080
done:
1081
    FUNC_LEAVE_NOAPI(ret_value)
1082
} /* end H5M__get_api_common() */
1083
1084
/*-------------------------------------------------------------------------
1085
 * Function:    H5Mget
1086
 *
1087
 * Purpose:     H5Mget retrieves, from the Map specified by MAP_ID, the
1088
 *              value associated with the provided key.  KEY_MEM_TYPE_ID
1089
 *              and VAL_MEM_TYPE_ID specify the datatypes for the provided
1090
 *              KEY and VALUE buffers. If KEY_MEM_TYPE_ID is different
1091
 *              from that used to create the map object, the key will be
1092
 *              internally converted to the datatype for the map object
1093
 *              for the query, and if VAL_MEM_TYPE_ID is different from
1094
 *              that used to create the map object, the returned value
1095
 *              will be converted to VAL_MEM_TYPE_ID before the function
1096
 *              returns. Any further options can be specified through the
1097
 *              property list DXPL_ID.
1098
 *
1099
 * Return:      SUCCEED/FAIL
1100
 *
1101
 *-------------------------------------------------------------------------
1102
 */
1103
herr_t
1104
H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
1105
       hid_t dxpl_id)
1106
{
1107
    herr_t ret_value = SUCCEED; /* Return value */
1108
1109
    FUNC_ENTER_API(FAIL)
1110
1111
    /* Get key-value pair from the map synchronously */
1112
    if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL,
1113
                                         NULL)) < 0)
1114
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map synchronously");
1115
1116
done:
1117
    FUNC_LEAVE_API(ret_value)
1118
} /* end H5Mget() */
1119
1120
/*-------------------------------------------------------------------------
1121
 * Function:    H5Mget_async
1122
 *
1123
 * Purpose:     Asynchronous version of H5Mget
1124
 *
1125
 * Return:      SUCCEED/FAIL
1126
 *
1127
 *-------------------------------------------------------------------------
1128
 */
1129
herr_t
1130
H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
1131
             hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id,
1132
             hid_t es_id)
1133
{
1134
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
1135
    void          *token     = NULL;            /* Request token for async operation        */
1136
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1137
    herr_t         ret_value = SUCCEED;         /* Return value */
1138
1139
    FUNC_ENTER_API(FAIL)
1140
1141
    /* Set up request token pointer for asynchronous operation */
1142
    if (H5ES_NONE != es_id)
1143
        token_ptr = &token;
1144
1145
    /* Get key-value pair from the map asynchronously */
1146
    if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id,
1147
                                         token_ptr, &vol_obj)) < 0)
1148
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map asynchronously");
1149
1150
    /* If a token was created, add the token to the event set */
1151
    if (NULL != token)
1152
        /* clang-format off */
1153
        if (H5ES_insert(es_id, vol_obj->connector, token,
1154
                        H5ARG_TRACE10(__func__, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0)
1155
            /* clang-format on */
1156
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1157
1158
done:
1159
    FUNC_LEAVE_API(ret_value)
1160
} /* end H5Mget_async() */
1161
1162
/*-------------------------------------------------------------------------
1163
 * Function:    H5Mexists
1164
 *
1165
 * Purpose:     H5Mexists checks if the provided key is stored in the map
1166
 *              specified by MAP_ID. If KEY_MEM_TYPE_ID is different from
1167
 *              that used to create the map object the key will be
1168
 *              internally converted to the datatype for the map object
1169
 *              for the query.
1170
 *
1171
 * Return:      SUCCEED/FAIL
1172
 *
1173
 *-------------------------------------------------------------------------
1174
 */
1175
herr_t
1176
H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id)
1177
{
1178
    H5VL_object_t       *vol_obj = NULL;
1179
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
1180
    H5VL_map_args_t      map_args;            /* Arguments for map operations */
1181
    herr_t               ret_value = SUCCEED; /* Return value */
1182
1183
    FUNC_ENTER_API(FAIL)
1184
1185
    /* Check arguments */
1186
    if (key_mem_type_id < 0)
1187
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID");
1188
1189
    /* Get map pointer */
1190
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
1191
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID");
1192
1193
    /* Get the default dataset transfer property list if the user didn't provide one */
1194
    if (H5P_DEFAULT == dxpl_id)
1195
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
1196
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1197
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
1198
1199
    /* Set up VOL callback arguments */
1200
    map_args.exists.key_mem_type_id = key_mem_type_id;
1201
    map_args.exists.key             = key;
1202
    map_args.exists.exists          = false;
1203
    vol_cb_args.op_type             = H5VL_MAP_EXISTS;
1204
    vol_cb_args.args                = &map_args;
1205
1206
    /* Check if key exists */
1207
    if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0)
1208
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, ret_value, "unable to check if key exists");
1209
1210
    /* Set value to return */
1211
    if (exists)
1212
        *exists = map_args.exists.exists;
1213
1214
done:
1215
    FUNC_LEAVE_API(ret_value)
1216
} /* end H5Mexists() */
1217
1218
/*-------------------------------------------------------------------------
1219
 * Function:    H5Miterate
1220
 *
1221
 * Purpose:     H5Miterate iterates over all key-value pairs stored in the
1222
 *              map specified by MAP_ID, making the callback specified by
1223
 *              OP for each. The IDX parameter is an in/out parameter that
1224
 *              may be used to restart a previously interrupted iteration.
1225
 *              At the start of iteration IDX should be set to 0, and to
1226
 *              restart iteration at the same location on a subsequent
1227
 *              call to H5Miterate, IDX should be the same value as
1228
 *              returned by the previous call.
1229
 *
1230
 *              H5M_iterate_t is defined as:
1231
 *              herr_t (*H5M_iterate_t)(hid_t map_id, const void *key,
1232
 *                      void *ctx)
1233
 *
1234
 *              The KEY parameter is the buffer for the key for this
1235
 *              iteration, converted to the datatype specified by
1236
 *              KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass
1237
 *              through of the value passed to H5Miterate, which can be
1238
 *              used to store application-defined data for iteration. A
1239
 *              negative return value from this function will cause
1240
 *              H5Miterate to issue an error, while a positive return
1241
 *              value will cause H5Miterate to stop iterating and return
1242
 *              this value without issuing an error. A return value of
1243
 *              zero allows iteration to continue.
1244
 *
1245
 * Return:      Last value returned by op
1246
 *
1247
 *-------------------------------------------------------------------------
1248
 */
1249
herr_t
1250
H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data, hid_t dxpl_id)
1251
{
1252
    H5VL_object_t       *vol_obj = NULL;
1253
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
1254
    H5VL_map_args_t      map_args;            /* Arguments for map operations */
1255
    herr_t               ret_value = SUCCEED; /* Return value */
1256
1257
    FUNC_ENTER_API(FAIL)
1258
1259
    /* Check arguments */
1260
    if (key_mem_type_id < 0)
1261
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID");
1262
    if (!op)
1263
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
1264
1265
    /* Get map pointer */
1266
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
1267
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID");
1268
1269
    /* Get the default dataset transfer property list if the user didn't provide one */
1270
    if (H5P_DEFAULT == dxpl_id)
1271
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
1272
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1273
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
1274
1275
    /* Set up VOL callback arguments */
1276
    map_args.specific.specific_type                    = H5VL_MAP_ITER;
1277
    map_args.specific.args.iterate.loc_params.type     = H5VL_OBJECT_BY_SELF;
1278
    map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(map_id);
1279
    map_args.specific.args.iterate.idx                 = (idx ? *idx : 0);
1280
    map_args.specific.args.iterate.key_mem_type_id     = key_mem_type_id;
1281
    map_args.specific.args.iterate.op                  = op;
1282
    map_args.specific.args.iterate.op_data             = op_data;
1283
    vol_cb_args.op_type                                = H5VL_MAP_SPECIFIC;
1284
    vol_cb_args.args                                   = &map_args;
1285
1286
    /* Iterate over keys */
1287
    if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0)
1288
        HERROR(H5E_MAP, H5E_BADITER, "unable to iterate over keys");
1289
1290
    /* Set value to return */
1291
    if (idx)
1292
        *idx = map_args.specific.args.iterate.idx;
1293
1294
done:
1295
    FUNC_LEAVE_API(ret_value)
1296
} /* end H5Miterate() */
1297
1298
/*-------------------------------------------------------------------------
1299
 * Function:    H5Miterate_by_name
1300
 *
1301
 * Purpose:     H5Miterate_by_name iterates over all key-value pairs
1302
 *              stored in the map specified by MAP_ID, making the callback
1303
 *              specified by OP for each. The IDX parameter is an in/out
1304
 *              parameter that may be used to restart a previously
1305
 *              interrupted iteration.  At the start of iteration IDX
1306
 *              should be set to 0, and to restart iteration at the same
1307
 *              location on a subsequent call to H5Miterate, IDX should be
1308
 *              the same value as returned by the previous call.
1309
 *
1310
 *              H5M_iterate_t is defined as:
1311
 *              herr_t (*H5M_iterate_t)(hid_t map_id, const void *key,
1312
 *                      void *ctx)
1313
 *
1314
 *              The KEY parameter is the buffer for the key for this
1315
 *              iteration, converted to the datatype specified by
1316
 *              KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass
1317
 *              through of the value passed to H5Miterate, which can be
1318
 *              used to store application-defined data for iteration. A
1319
 *              negative return value from this function will cause
1320
 *              H5Miterate to issue an error, while a positive return
1321
 *              value will cause H5Miterate to stop iterating and return
1322
 *              this value without issuing an error. A return value of
1323
 *              zero allows iteration to continue.
1324
 *
1325
 * Return:      Last value returned by op
1326
 *
1327
 *-------------------------------------------------------------------------
1328
 */
1329
herr_t
1330
H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op,
1331
                   void *op_data, hid_t dxpl_id, hid_t lapl_id)
1332
{
1333
    H5VL_object_t       *vol_obj = NULL;
1334
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
1335
    H5VL_map_args_t      map_args;            /* Arguments for map operations */
1336
    herr_t               ret_value = SUCCEED; /* Return value */
1337
1338
    FUNC_ENTER_API(FAIL)
1339
1340
    /* Check arguments */
1341
    if (!map_name)
1342
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be NULL");
1343
    if (!*map_name)
1344
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be an empty string");
1345
    if (key_mem_type_id < 0)
1346
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID");
1347
    if (!op)
1348
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
1349
1350
    /* Get the location object */
1351
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
1352
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier");
1353
1354
    /* Get the default dataset transfer property list if the user didn't provide one */
1355
    if (H5P_DEFAULT == dxpl_id)
1356
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
1357
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1358
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
1359
1360
    /* Set up VOL callback arguments */
1361
    map_args.specific.specific_type                                        = H5VL_MAP_ITER;
1362
    map_args.specific.args.iterate.loc_params.type                         = H5VL_OBJECT_BY_NAME;
1363
    map_args.specific.args.iterate.loc_params.obj_type                     = H5I_get_type(loc_id);
1364
    map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.name    = map_name;
1365
    map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
1366
    map_args.specific.args.iterate.idx                                     = (idx ? *idx : 0);
1367
    map_args.specific.args.iterate.key_mem_type_id                         = key_mem_type_id;
1368
    map_args.specific.args.iterate.op                                      = op;
1369
    map_args.specific.args.iterate.op_data                                 = op_data;
1370
    vol_cb_args.op_type                                                    = H5VL_MAP_SPECIFIC;
1371
    vol_cb_args.args                                                       = &map_args;
1372
1373
    /* Iterate over keys */
1374
    if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0)
1375
        HERROR(H5E_MAP, H5E_BADITER, "unable to ierate over keys");
1376
1377
    /* Set value to return */
1378
    if (idx)
1379
        *idx = map_args.specific.args.iterate.idx;
1380
1381
done:
1382
    FUNC_LEAVE_API(ret_value)
1383
} /* end H5Miterate_by_name() */
1384
1385
/*-------------------------------------------------------------------------
1386
 * Function:    H5Mdelete
1387
 *
1388
 * Purpose:     H5Mdelete deletes a key-value pair from the Map
1389
 *              specified by MAP_ID. KEY_MEM_TYPE_ID specifies the
1390
 *              datatype for the provided key buffers, and if different
1391
 *              from that used to create the Map object, the key will be
1392
 *              internally converted to the datatype for the map object.
1393
 *              Any further options can be specified through the property
1394
 *              list DXPL_ID.
1395
 *
1396
 * Return:      SUCCEED/FAIL
1397
 *
1398
 *-------------------------------------------------------------------------
1399
 */
1400
herr_t
1401
H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id)
1402
{
1403
    H5VL_object_t       *vol_obj = NULL;
1404
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
1405
    H5VL_map_args_t      map_args;            /* Arguments for map operations */
1406
    herr_t               ret_value = SUCCEED; /* Return value */
1407
1408
    FUNC_ENTER_API(FAIL)
1409
1410
    /* Check arguments */
1411
    if (key_mem_type_id < 0)
1412
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID");
1413
1414
    /* Get map pointer */
1415
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
1416
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID");
1417
1418
    /* Get the default dataset transfer property list if the user didn't provide one */
1419
    if (H5P_DEFAULT == dxpl_id)
1420
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
1421
    else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1422
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
1423
1424
    /* Set up VOL callback arguments */
1425
    map_args.specific.specific_type                = H5VL_MAP_DELETE;
1426
    map_args.specific.args.del.loc_params.type     = H5VL_OBJECT_BY_SELF;
1427
    map_args.specific.args.del.loc_params.obj_type = H5I_get_type(map_id);
1428
    map_args.specific.args.del.key_mem_type_id     = key_mem_type_id;
1429
    map_args.specific.args.del.key                 = key;
1430
    vol_cb_args.op_type                            = H5VL_MAP_SPECIFIC;
1431
    vol_cb_args.args                               = &map_args;
1432
1433
    /* Delete the key/value pair */
1434
    if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0)
1435
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to delete key/value pair");
1436
1437
done:
1438
    FUNC_LEAVE_API(ret_value)
1439
} /* end H5Mdelete() */
1440
1441
#endif /*  H5_HAVE_MAP_API */