summaryrefslogtreecommitdiffstats
path: root/src/H5Spoint.c
Commit message (Expand)AuthorAgeFilesLines
* H5S adjust callbacks now return an herr_t instead of void.Dana Robinson2018-09-241-6/+6
* Fixed HDFFV-10404Binh-Minh Ribler2018-07-131-1/+1
* Revert "Merge pull request #1116 in HDFFV/hdf5 from ~HDFTEST/hdf5_hft:hdf5_1_...hdftest2018-06-241-167/+30
* Merge branch 'develop' into hdf5_1_10.syncM. Scot Breitenfeld2018-05-081-14/+15
|\
| * Merge branch 'develop' of https://bitbucket.hdfgroup.org/scm/hdffv/hdf5 into ...Quincey Koziol2018-04-291-6/+4
| |\
| | * Merge pull request #426 in HDFFV/hdf5 from ~LRKNOX/hdf5_lrk:hdf5_1_10 to hdf5...Larry Knox2017-04-251-6/+4
| * | Checkpoint normalization against incoming hyperslab / selection / dataspaceQuincey Koziol2017-03-281-15/+16
| |/
* | Fix for daily test failures.Vailin Choi2017-12-071-9/+9
* | Fix for HDFFV-9947 H5SencodeVailin Choi2017-11-281-21/+158
* | Change copyright headers to replace url referring to file to be removedlrknox2017-04-141-6/+4
|/
* [svn-r30219] Description:Quincey Koziol2016-07-221-5/+5
* [svn-r27916] Re-merge of r27884-27891 from the trunk + bugfix for a fewDana Robinson2015-09-301-20/+31
|\
* | [svn-r27912] Revert of r27887, which caused failures in the vds test. TheseDana Robinson2015-09-291-31/+20
* | [svn-r27887] Description:Quincey Koziol2015-09-271-20/+31
|\ \ | |/
| * [svn-r27884] Description:Quincey Koziol2015-09-261-20/+31
* | [svn-r27835] Description:Quincey Koziol2015-09-211-12/+12
|\ \ | |/
| * [svn-r27768] Description:Quincey Koziol2015-09-141-5/+5
* | [svn-r27632] Description:Quincey Koziol2015-08-311-14/+8
* | [svn-r27479] Add checking for invalid inputs to H5Dset_virtual: point selecti...Neil Fortner2015-08-071-0/+1
* | [svn-r27450] Add descriptions for all non-public functions.Neil Fortner2015-07-311-2/+6
* | [svn-r27191] Merged r26781 to r27185 from trunkDana Robinson2015-06-111-8/+15
|\ \ | |/
| * [svn-r27133] - Add a new attribute function characterstic for format:Mohamad Chaarawi2015-06-011-2/+2
* | [svn-r26962] Add support for unlimited selections to VDS code.Neil Fortner2015-04-291-0/+27
* | [svn-r26878] Fix errors in unlimited selection serialize/deserializeNeil Fortner2015-04-211-2/+2
* | [svn-r26828] Implement support for unlimited selections (not supported by VDS...Neil Fortner2015-04-161-4/+7
|/
* [svn-r26302] Description:Quincey Koziol2015-02-251-26/+30
* [svn-r25766] Description:Quincey Koziol2014-11-031-86/+64
* [svn-r25273] Description:Quincey Koziol2014-06-131-64/+86
* [svn-r24709] rename H5V to H5VM since H5V is needed in the fastforward projec...Mohamad Chaarawi2014-02-131-3/+3
* [svn-r22646] Description:Quincey Koziol2012-08-081-1/+1
* [svn-r22608] Description:Quincey Koziol2012-07-261-3/+3
* [svn-r21919] Description:Quincey Koziol2012-02-091-29/+29
* [svn-r20440] Bug 1386 - allow dimension size to be zero even though it isn't ...Raymond Lu2011-04-071-2/+2
* [svn-r19092] Description:Quincey Koziol2010-07-191-5/+176
* [svn-r18702] Description:Quincey Koziol2010-05-051-1/+1
* [svn-r18346] Description:Quincey Koziol2010-02-271-21/+37
* [svn-r18109] Description:Quincey Koziol2010-01-151-88/+106
* [svn-r16279] Description:Quincey Koziol2009-01-081-27/+25
* [svn-r15800] Description:Quincey Koziol2008-10-071-2/+2
* [svn-r15510] Description:Quincey Koziol2008-08-211-45/+45
* [svn-r14448] Maintenance: Released version hdf5-1.8.0-rc1 to the public fTP s...Elena Pourmal2008-01-211-1/+1
* [svn-r14421] Description:Quincey Koziol2008-01-151-2/+3
* [svn-r14420] Description:Quincey Koziol2008-01-151-75/+72
* [svn-r14307] Description:Quincey Koziol2007-11-291-21/+89
* [svn-r14278] Description:Quincey Koziol2007-11-201-0/+54
* [svn-r13253] Updated all C and C++ style source code files with the THG copyr...Albert Cheng2007-02-071-2/+3
* [svn-r13068] Ran bin/reconfigure. Some of the scripts have been changed or h...James Laird2006-12-181-3/+3
* [svn-r11245] Purpose:Quincey Koziol2005-08-131-7/+7
* [svn-r9857] Purpose: MaintenanceElena Pourmal2005-01-221-3/+0
* [svn-r9727] Purpose:Quincey Koziol2004-12-291-33/+39
728'>728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * Copyright by the Board of Trustees of the University of Illinois.         *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the COPYING file, which can be found at the root of the source code       *
 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/****************/
/* Module Setup */
/****************/

#include "H5Mmodule.h" /* This source code file is part of the H5M module */

/***********/
/* Headers */
/***********/
#include "H5private.h"   /* Generic Functions                        */
#include "H5CXprivate.h" /* API Contexts                             */
#include "H5Mpkg.h"      /* Maps                                     */
#include "H5Eprivate.h"  /* Error handling                           */
#include "H5ESprivate.h" /* Event Sets                               */
#include "H5Iprivate.h"  /* IDs                                      */
#include "H5VLprivate.h" /* Virtual Object Layer                     */

/****************/
/* Local Macros */
/****************/

/******************/
/* Local Typedefs */
/******************/

/********************/
/* Local Prototypes */
/********************/
static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request);

#ifdef H5_HAVE_MAP_API
static hid_t  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, hid_t mcpl_id, hid_t mapl_id, void **token_ptr,
                                     H5VL_object_t **_vol_obj_ptr);
static hid_t  H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr,
                                   H5VL_object_t **_vol_obj_ptr);
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,
                                  const void *value, hid_t dxpl_id, void **token_ptr,
                                  H5VL_object_t **_vol_obj_ptr);
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,
                                  void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
#endif /*  H5_HAVE_MAP_API */

/*********************/
/* Package Variables */
/*********************/

/* Package initialization variable */
hbool_t H5_PKG_INIT_VAR = FALSE;

/*****************************/
/* Library Private Variables */
/*****************************/

/*******************/
/* Local Variables */
/*******************/

/* Map ID class */
static const H5I_class_t H5I_MAP_CLS[1] = {{
    H5I_MAP,                  /* ID class value */
    0,                        /* Class flags */
    0,                        /* # of reserved IDs for class */
    (H5I_free_t)H5M__close_cb /* Callback routine for closing objects of this class */
}};

/* Flag indicating "top" of interface has been initialized */
static hbool_t H5M_top_package_initialize_s = FALSE;

/*-------------------------------------------------------------------------
 * Function: H5M_init
 *
 * Purpose:  Initialize the interface from some other layer.
 *
 * Return:   Success:    non-negative
 *
 *           Failure:    negative
 *-------------------------------------------------------------------------
 */
herr_t
H5M_init(void)
{
    herr_t ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_NOAPI(FAIL)
    /* FUNC_ENTER() does all the work */

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M_init() */

/*-------------------------------------------------------------------------
NAME
    H5M__init_package -- Initialize interface-specific information
USAGE
    herr_t H5M__init_package()

RETURNS
    Non-negative on success/Negative on failure
DESCRIPTION
    Initializes any interface-specific data or routines.
---------------------------------------------------------------------------
*/
herr_t
H5M__init_package(void)
{
    herr_t ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_PACKAGE

    /* Initialize the ID group for the map IDs */
    if (H5I_register_type(H5I_MAP_CLS) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, FAIL, "unable to initialize interface")

    /* Mark "top" of interface as initialized, too */
    H5M_top_package_initialize_s = TRUE;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M__init_package() */

/*-------------------------------------------------------------------------
 * Function: H5M_top_term_package
 *
 * Purpose:  Close the "top" of the interface, releasing IDs, etc.
 *
 * Return:   Success:    Positive if anything was done that might
 *                affect other interfaces; zero otherwise.
 *           Failure:    Negative.
 *-------------------------------------------------------------------------
 */
int
H5M_top_term_package(void)
{
    int n = 0;

    FUNC_ENTER_NOAPI_NOINIT_NOERR

    if (H5M_top_package_initialize_s) {
        if (H5I_nmembers(H5I_MAP) > 0) {
            (void)H5I_clear_type(H5I_MAP, FALSE, FALSE);
            n++; /*H5I*/
        }        /* end if */

        /* Mark closed */
        if (0 == n)
            H5M_top_package_initialize_s = FALSE;
    } /* end if */

    FUNC_LEAVE_NOAPI(n)
} /* end H5M_top_term_package() */

/*-------------------------------------------------------------------------
 * Function: H5M_term_package
 *
 * Purpose:  Terminate this interface.
 *
 * Note:     Finishes shutting down the interface, after
 *           H5M_top_term_package() is called
 *
 * Return:   Success:    Positive if anything was done that might
 *                affect other interfaces; zero otherwise.
 *            Failure:    Negative.
 *-------------------------------------------------------------------------
 */
int
H5M_term_package(void)
{
    int n = 0;

    FUNC_ENTER_NOAPI_NOINIT_NOERR

    if (H5_PKG_INIT_VAR) {
        /* Sanity checks */
        HDassert(0 == H5I_nmembers(H5I_MAP));
        HDassert(FALSE == H5M_top_package_initialize_s);

        /* Destroy the dataset object id group */
        n += (H5I_dec_type_ref(H5I_MAP) > 0);

        /* Mark closed */
        if (0 == n)
            H5_PKG_INIT_VAR = FALSE;
    } /* end if */

    FUNC_LEAVE_NOAPI(n)
} /* end H5M_term_package() */

/*-------------------------------------------------------------------------
 * Function:    H5M__close_cb
 *
 * Purpose:     Called when the ref count reaches zero on the map's ID
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5M__close_cb(H5VL_object_t *map_vol_obj, void **request)
{
    herr_t ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_STATIC

    /* Sanity check */
    HDassert(map_vol_obj);

    /* Close the map */
    if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, request) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map");

    /* Free the VOL object */
    if (H5VL_free_object(map_vol_obj) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "unable to free VOL object");

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M__close_cb() */

#ifdef H5_HAVE_MAP_API

/*-------------------------------------------------------------------------
 * Function:    H5M__create_api_common
 *
 * Purpose:     This is the common function for creating the HDF5 map.
 *
 * Return:      Success:    The object ID of the new map.
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
static hid_t
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,
                       hid_t mcpl_id, hid_t mapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
    void *          map         = NULL; /* New map's info */
    H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
    H5VL_object_t **vol_obj_ptr =
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
    H5VL_loc_params_t loc_params;                     /* Location parameters */
    hid_t             ret_value = H5I_INVALID_HID;    /* Return value */

    FUNC_ENTER_STATIC

    /* Check arguments */
    if (!name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
    if (!*name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")

    /* Get link creation property list */
    if (H5P_DEFAULT == lcpl_id)
        lcpl_id = H5P_LINK_CREATE_DEFAULT;
    else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "lcpl_id is not a link creation property list")

    /* Get map creation property list */
    if (H5P_DEFAULT == mcpl_id)
        mcpl_id = H5P_MAP_CREATE_DEFAULT;
    else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID")

    /* Set up object access arguments */
    if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &loc_params) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")

    /* Create the map */
    if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name,
                      lcpl_id, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map")

    /* Get an ID for the map */
    if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map handle")

done:
    /* Cleanup on failure */
    if (H5I_INVALID_HID == ret_value)
        if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M__create_api_common() */

/*-------------------------------------------------------------------------
 * Function:    H5Mcreate
 *
 * Purpose:     Creates a new map object for storing key-value pairs.  The
 *              in-file datatype for keys is defined by KEY_TYPE_ID and
 *              the in-file datatype for values is defined by VAL_TYPE_ID.
 *              LOC_ID specifies the location to create the map object and
 *              NAME specifies the name of the link to the object
 *              (relative to LOC_ID).  Other options can be specified
 *              through the property lists LCPL_ID, MCPL_ID, and MAPL_ID.
 *
 * Return:      Success:    The object ID of the new map.
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
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,
          hid_t mapl_id)
{
    hid_t ret_value = H5I_INVALID_HID; /* Return value */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE7("i", "i*siiiii", loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id);

    /* Create the map synchronously */
    if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id,
                                            NULL, NULL)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map synchronously")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mcreate() */

/*-------------------------------------------------------------------------
 * Function:    H5Mcreate_async
 *
 * Purpose:     Asynchronous version of H5Mcreate
 *
 * Return:      Success:    The object ID of the new map.
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, 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, hid_t mapl_id,
                hid_t es_id)
{
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
    void *         token     = NULL;            /* Request token for async operation        */
    void **        token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE11("i", "*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);

    /* Set up request token pointer for asynchronous operation */
    if (H5ES_NONE != es_id)
        token_ptr = &token;

    /* Create the map asynchronously */
    if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id,
                                            token_ptr, &vol_obj)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map asynchronously")

    /* If a token was created, add the token to the event set */
    if (NULL != token)
        /* clang-format off */
        if (H5ES_insert(es_id, vol_obj->connector, token,
                        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) {
        /* clang-format on */
            if (H5I_dec_app_ref_always_close(ret_value) < 0)
                HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID")
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
        } /* end if */

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mcreate_async() */

/*-------------------------------------------------------------------------
 * Function:    H5Mcreate_anon
 *
 * Purpose:     Creates a new map object for storing key-value pairs.  The
 *              in-file datatype for keys is defined by KEY_TYPE_ID and
 *              the in-file datatype for values is defined by VAL_TYPE_ID.
 *              LOC_ID specifies the file to create the map object, but no
 *              link to the object is created.  Other options can be
 *              specified through the property lists LCPL_ID, MCPL_ID, and
 *              MAPL_ID.
 *
 *              The resulting ID should be linked into the file with
 *              H5Olink or it will be deleted when closed.
 *
 * Return:      Success:    The object ID of the new map. The map should
 *                          be linked into the group hierarchy before being closed or
 *                          it will be deleted. The dataset should be
 *                          closed when the caller is no longer interested
 *                          in it.
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id)
{
    void *            map     = NULL; /* map object from VOL connector */
    H5VL_object_t *   vol_obj = NULL; /* object of loc_id */
    H5VL_loc_params_t loc_params;
    hid_t             ret_value = H5I_INVALID_HID; /* Return value */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE5("i", "iiiii", loc_id, key_type_id, val_type_id, mcpl_id, mapl_id);

    /* Check arguments */
    if (H5P_DEFAULT == mcpl_id)
        mcpl_id = H5P_MAP_CREATE_DEFAULT;
    else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not map create property list ID")

    /* Verify access property list and set up collective metadata if appropriate */
    if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, TRUE) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")

    /* get the location object */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")

    /* Set location parameters */
    loc_params.type     = H5VL_OBJECT_BY_SELF;
    loc_params.obj_type = H5I_get_type(loc_id);

    /* Create the map */
    if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, NULL,
                      H5P_LINK_CREATE_DEFAULT, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map")

    /* Get an ID for the map */
    if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map")

done:
    /* Cleanup on failure */
    if (H5I_INVALID_HID == ret_value)
        if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")

    FUNC_LEAVE_API(ret_value)
} /* end H5Mcreate_anon() */

/*------------------------------------------------------------------------
 * Function:    H5M__open_api_common
 *
 * Purpose:     This is the common function for opening the HDF5 map.
 *
 * Return:      Success:    Object ID of the map
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
static hid_t
H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr,
                     H5VL_object_t **_vol_obj_ptr)
{
    void *          map         = NULL; /* map object from VOL connector */
    H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
    H5VL_object_t **vol_obj_ptr =
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
    H5VL_loc_params_t loc_params;                     /* Location parameters */
    hid_t             ret_value = H5I_INVALID_HID;    /* Return value */

    FUNC_ENTER_STATIC

    /* Check args */
    if (!name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
    if (!*name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")

    /* Set up object access arguments */
    if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &loc_params) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")

    /* Open the map */
    if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name,
                      mapl_id, &map) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map")

    /* Register an ID for the map */
    if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map ID")

done:
    /* Cleanup on failure */
    if (H5I_INVALID_HID == ret_value)
        if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M__open_api_common() */

/*------------------------------------------------------------------------
 * Function:    H5Mopen
 *
 * Purpose:     Finds a map named NAME at LOC_ID, opens it, and returns
 *              its ID. The map should be close when the caller is no
 *              longer interested in it.
 *
 *              Takes a map access property list
 *
 * Return:      Success:    Object ID of the map
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
{
    void *         map       = NULL;            /* map object from VOL connector */
    H5VL_object_t *vol_obj   = NULL;            /* object of loc_id */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE3("i", "i*si", loc_id, name, mapl_id);

    /* Open the map synchronously */
    if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, NULL, NULL)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously")

done:
    /* Cleanup on failure */
    if (H5I_INVALID_HID == ret_value)
        if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")

    FUNC_LEAVE_API(ret_value)
} /* end H5Mopen() */

/*------------------------------------------------------------------------
 * Function:    H5Mopen_async
 *
 * Purpose:     Asynchronous version of H5Mopen
 *
 * Return:      Success:    Object ID of the map
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
              hid_t mapl_id, hid_t es_id)
{
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
    void *         token     = NULL;            /* Request token for async operation        */
    void **        token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id);

    /* Set up request token pointer for asynchronous operation */
    if (H5ES_NONE != es_id)
        token_ptr = &token;

    /* Open the map asynchronously */
    if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, token_ptr, &vol_obj)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map asynchronously")

    /* If a token was created, add the token to the event set */
    if (NULL != token)
        /* clang-format off */
        if (H5ES_insert(es_id, vol_obj->connector, token,
                        H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id)) < 0) {
        /* clang-format on */
            if (H5I_dec_app_ref_always_close(ret_value) < 0)
                HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID")
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
        } /* end if */

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mopen_async() */

/*-------------------------------------------------------------------------
 * Function:    H5Mclose
 *
 * Purpose:     Closes access to a map and releases resources used by it.
 *              It is illegal to subsequently use that same map ID in
 *              calls to other map functions.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mclose(hid_t map_id)
{
    herr_t ret_value = SUCCEED; /* Return value                     */

    FUNC_ENTER_API(FAIL)
    H5TRACE1("e", "i", map_id);

    /* Check args */
    if (H5I_MAP != H5I_get_type(map_id))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID")

    /* Decrement the counter on the map.  It will be freed if the count
     * reaches zero.
     */
    if (H5I_dec_app_ref_always_close(map_id) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on map ID")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mclose() */

/*-------------------------------------------------------------------------
 * Function:    H5Mclose_async
 *
 * Purpose:     Asynchronous version of H5Mclose
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t es_id)
{
    void *         token     = NULL;            /* Request token for async operation            */
    void **        token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
    H5VL_object_t *vol_obj   = NULL;            /* VOL object of dset_id */
    H5VL_t *       connector = NULL;            /* VOL connector */
    herr_t         ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, map_id, es_id);

    /* Check args */
    if (H5I_MAP != H5I_get_type(map_id))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID")

    /* Get dataset object's connector */
    if (NULL == (vol_obj = H5VL_vol_object(map_id)))
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get VOL object for dataset")

    /* Prepare for possible asynchronous operation */
    if (H5ES_NONE != es_id) {
        /* Increase connector's refcount, so it doesn't get closed if closing
         * the dataset closes the file */
        connector = vol_obj->connector;
        H5VL_conn_inc_rc(connector);

        /* Point at token for operation to set up */
        token_ptr = &token;
    } /* end if */

    /* Decrement the counter on the map.  It will be freed if the count
     * reaches zero.
     */
    if (H5I_dec_app_ref_always_close_async(map_id, token_ptr) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID")

    /* If a token was created, add the token to the event set */
    if (NULL != token)
        /* clang-format off */
        if (H5ES_insert(es_id, vol_obj->connector, token,
                        H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, map_id, es_id)) < 0)
        /* clang-format on */
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set")

done:
    if (connector && H5VL_conn_dec_rc(connector) < 0)
        HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")

    FUNC_LEAVE_API(ret_value)
} /* end H5Mclose_async() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget_key_type
 *
 * Purpose:     Returns a copy of the key datatype for a map.
 *
 * Return:      Success:    ID for a copy of the datatype. The data
 *                          type should be released by calling
 *                          H5Tclose().
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mget_key_type(hid_t map_id)
{
    H5VL_object_t *vol_obj;                     /* Map structure    */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value         */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE1("i", "i", map_id);

    /* Check args */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")

    /* get the datatype */
    if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_KEY_TYPE,
                      &ret_value) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget_key_type() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget_val_type
 *
 * Purpose:     Returns a copy of the value datatype for a map.
 *
 * Return:      Success:    ID for a copy of the datatype. The data
 *                          type should be released by calling
 *                          H5Tclose().
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mget_val_type(hid_t map_id)
{
    H5VL_object_t *vol_obj;                     /* Map structure    */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value         */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE1("i", "i", map_id);

    /* Check args */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")

    /* get the datatype */
    if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_VAL_TYPE,
                      &ret_value) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget_val_type() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget_create_plist
 *
 * Purpose:     Returns a copy of the map creation property list.
 *
 * Return:      Success:    ID for a copy of the map creation
 *                          property list.  The template should be
 *                          released by calling H5P_close().
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mget_create_plist(hid_t map_id)
{
    H5VL_object_t *vol_obj;                     /* Map structure    */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value         */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE1("i", "i", map_id);

    /* Check args */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")

    /* Get the map creation property list */
    if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MCPL,
                      &ret_value) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map creation properties")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget_create_plist() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget_access_plist
 *
 * Purpose:     Returns a copy of the map access property list.
 *
 * Description: H5Mget_access_plist returns the map access property
 *              list identifier of the specified map.
 *
 * Return:      Success:    ID for a copy of the map access
 *                          property list.  The template should be
 *                          released by calling H5Pclose().
 *
 *              Failure:    H5I_INVALID_HID
 *
 *-------------------------------------------------------------------------
 */
hid_t
H5Mget_access_plist(hid_t map_id)
{
    H5VL_object_t *vol_obj;                     /* Map structure    */
    hid_t          ret_value = H5I_INVALID_HID; /* Return value         */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE1("i", "i", map_id);

    /* Check args */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")

    /* Get the map access property list */
    if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MAPL,
                      &ret_value) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget_access_plist() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget_count
 *
 * Purpose:     Returns the number of key-value pairs stored in the map.
 *
 * Description: H5Mget_count returns the number of key-value pairs stored
 *              in the specified map.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id)
{
    H5VL_object_t *vol_obj;             /* Map structure    */
    herr_t         ret_value = SUCCEED; /* Return value         */

    FUNC_ENTER_API(H5I_INVALID_HID)
    H5TRACE3("e", "ixi", map_id, count, dxpl_id);

    /* Check args */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Get the number of key-value pairs stored in the map */
    if (H5VL_optional(vol_obj, H5VL_MAP_GET, dxpl_id, H5_REQUEST_NULL, H5VL_MAP_GET_COUNT, count) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget_count() */

/*-------------------------------------------------------------------------
 * Function:    H5M__put_api_common
 *
 * Purpose:     This is the common function for putting value to map.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
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,
                    const void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
    H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
    H5VL_object_t **vol_obj_ptr =
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
    herr_t ret_value = SUCCEED;                       /* Return value */

    FUNC_ENTER_STATIC

    /* Check arguments */
    if (key_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
    if (val_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")

    /* Get map pointer */
    if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Set the key/value pair */
    if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_PUT, dxpl_id, token_ptr, key_mem_type_id, key, val_mem_type_id,
                      value) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair")

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M__put_api_common() */

/*-------------------------------------------------------------------------
 * Function:    H5Mput
 *
 * Purpose:     H5Mput adds a key-value pair to the Map specified by
 *              MAP_ID, or updates the value for the specified key if one
 *              was set previously. KEY_MEM_TYPE_ID and VAL_MEM_TYPE_ID
 *              specify the datatypes for the provided KEY and VALUE
 *              buffers, and if different from those used to create the
 *              map object, the key and value will be internally converted
 *              to the datatypes for the map object. Any further options
 *              can be specified through the property list DXPL_ID.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value,
       hid_t dxpl_id)
{
    herr_t ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id);

    /* Add key-value pair to the map synchronously */
    if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL,
                                         NULL)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map synchronously")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mput() */

/*-------------------------------------------------------------------------
 * Function:    H5Mput_async
 *
 * Purpose:     Asynchronous version of H5Mput
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
             hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id,
             hid_t es_id)
{
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
    void *         token     = NULL;            /* Request token for async operation        */
    void **        token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
    herr_t         ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE10("e", "*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);

    /* Set up request token pointer for asynchronous operation */
    if (H5ES_NONE != es_id)
        token_ptr = &token;

    /* Add key-value pair to the map asynchronously */
    if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id,
                                         token_ptr, &vol_obj)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map asynchronously")

    /* If a token was created, add the token to the event set */
    if (NULL != token)
        /* clang-format off */
        if (H5ES_insert(es_id, vol_obj->connector, token,
                        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)
        /* clang-format on */
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mput_async() */

/*-------------------------------------------------------------------------
 * Function:    H5M__get_api_common
 *
 * Purpose:     This is common function for getting value from the map.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
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, void *value,
                    hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
    H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
    H5VL_object_t **vol_obj_ptr =
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
    herr_t ret_value = SUCCEED;                       /* Return value */

    FUNC_ENTER_STATIC

    /* Check arguments */
    if (key_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
    if (val_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")

    /* Get map pointer */
    if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Get the value for the key */
    if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_GET_VAL, dxpl_id, token_ptr, key_mem_type_id, key,
                      val_mem_type_id, value) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map")

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5M__get_api_common() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget
 *
 * Purpose:     H5Mget retrieves, from the Map specified by MAP_ID, the
 *              value associated with the provided key.  KEY_MEM_TYPE_ID
 *              and VAL_MEM_TYPE_ID specify the datatypes for the provided
 *              KEY and VALUE buffers. If KEY_MEM_TYPE_ID is different
 *              from that used to create the map object, the key will be
 *              internally converted to the datatype for the map object
 *              for the query, and if VAL_MEM_TYPE_ID is different from
 *              that used to create the map object, the returned value
 *              will be converted to VAL_MEM_TYPE_ID before the function
 *              returns. Any further options can be specified through the
 *              property list DXPL_ID.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
       hid_t dxpl_id)
{
    herr_t ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id);

    /* Get key-value pair from the map synchronously */
    if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL,
                                         NULL)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map synchronously")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget() */

/*-------------------------------------------------------------------------
 * Function:    H5Mget_async
 *
 * Purpose:     Asynchronous version of H5Mget
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
             hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id,
             hid_t es_id)
{
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
    void *         token     = NULL;            /* Request token for async operation        */
    void **        token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
    herr_t         ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE10("e", "*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);

    /* Set up request token pointer for asynchronous operation */
    if (H5ES_NONE != es_id)
        token_ptr = &token;

    /* Get key-value pair from the map asynchronously */
    if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id,
                                         token_ptr, &vol_obj)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map asynchronously")

    /* If a token was created, add the token to the event set */
    if (NULL != token)
        /* clang-format off */
        if (H5ES_insert(es_id, vol_obj->connector, token,
                        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)
        /* clang-format on */
            HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mget_async() */

/*-------------------------------------------------------------------------
 * Function:    H5Mexists
 *
 * Purpose:     H5Mexists checks if the provided key is stored in the map
 *              specified by MAP_ID. If KEY_MEM_TYPE_ID is different from
 *              that used to create the map object the key will be
 *              internally converted to the datatype for the map object
 *              for the query.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id)
{
    H5VL_object_t *vol_obj   = NULL;
    herr_t         ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE5("e", "ii*x*bi", map_id, key_mem_type_id, key, exists, dxpl_id);

    /* Check arguments */
    if (key_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")

    /* Get map pointer */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Check if key exists */
    if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_EXISTS, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key,
                                   exists)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTGET, ret_value, "unable to check if key exists")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mexists() */

/*-------------------------------------------------------------------------
 * Function:    H5Miterate
 *
 * Purpose:     H5Miterate iterates over all key-value pairs stored in the
 *              map specified by MAP_ID, making the callback specified by
 *              OP for each. The IDX parameter is an in/out parameter that
 *              may be used to restart a previously interrupted iteration.
 *              At the start of iteration IDX should be set to 0, and to
 *              restart iteration at the same location on a subsequent
 *              call to H5Miterate, IDX should be the same value as
 *              returned by the previous call.
 *
 *              H5M_iterate_t is defined as:
 *              herr_t (*H5M_iterate_t)(hid_t map_id, const void *key,
 *                      void *ctx)
 *
 *              The KEY parameter is the buffer for the key for this
 *              iteration, converted to the datatype specified by
 *              KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass
 *              through of the value passed to H5Miterate, which can be
 *              used to store application-defined data for iteration. A
 *              negative return value from this function will cause
 *              H5Miterate to issue an error, while a positive return
 *              value will cause H5Miterate to stop iterating and return
 *              this value without issuing an error. A return value of
 *              zero allows iteration to continue.
 *
 * Return:      Last value returned by op
 *
 *-------------------------------------------------------------------------
 */
herr_t
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)
{
    H5VL_object_t *   vol_obj = NULL;
    H5VL_loc_params_t loc_params;
    herr_t            ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE6("e", "i*hiMI*xi", map_id, idx, key_mem_type_id, op, op_data, dxpl_id);

    /* Check arguments */
    if (key_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
    if (!op)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")

    /* Get map pointer */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Set location struct fields */
    loc_params.type     = H5VL_OBJECT_BY_SELF;
    loc_params.obj_type = H5I_get_type(map_id);

    /* Iterate over keys */
    if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params,
                                   H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to iterate over keys")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Miterate() */

/*-------------------------------------------------------------------------
 * Function:    H5Miterate_by_name
 *
 * Purpose:     H5Miterate_by_name iterates over all key-value pairs
 *              stored in the map specified by MAP_ID, making the callback
 *              specified by OP for each. The IDX parameter is an in/out
 *              parameter that may be used to restart a previously
 *              interrupted iteration.  At the start of iteration IDX
 *              should be set to 0, and to restart iteration at the same
 *              location on a subsequent call to H5Miterate, IDX should be
 *              the same value as returned by the previous call.
 *
 *              H5M_iterate_t is defined as:
 *              herr_t (*H5M_iterate_t)(hid_t map_id, const void *key,
 *                      void *ctx)
 *
 *              The KEY parameter is the buffer for the key for this
 *              iteration, converted to the datatype specified by
 *              KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass
 *              through of the value passed to H5Miterate, which can be
 *              used to store application-defined data for iteration. A
 *              negative return value from this function will cause
 *              H5Miterate to issue an error, while a positive return
 *              value will cause H5Miterate to stop iterating and return
 *              this value without issuing an error. A return value of
 *              zero allows iteration to continue.
 *
 * Return:      Last value returned by op
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op,
                   void *op_data, hid_t dxpl_id, hid_t lapl_id)
{
    H5VL_object_t *   vol_obj = NULL;
    H5VL_loc_params_t loc_params;
    herr_t            ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE8("e", "i*s*hiMI*xii", loc_id, map_name, idx, key_mem_type_id, op, op_data, dxpl_id, lapl_id);

    /* Check arguments */
    if (!map_name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be NULL")
    if (!*map_name)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be an empty string")
    if (key_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
    if (!op)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")

    /* Get the location object */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Set location struct fields */
    loc_params.type                         = H5VL_OBJECT_BY_NAME;
    loc_params.obj_type                     = H5I_get_type(loc_id);
    loc_params.loc_data.loc_by_name.name    = map_name;
    loc_params.loc_data.loc_by_name.lapl_id = lapl_id;

    /* Iterate over keys */
    if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params,
                                   H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to ierate over keys")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Miterate_by_name() */

/*-------------------------------------------------------------------------
 * Function:    H5Mdelete
 *
 * Purpose:     H5Mdelete deletes a key-value pair from the Map
 *              specified by MAP_ID. KEY_MEM_TYPE_ID specifies the
 *              datatype for the provided key buffers, and if different
 *              from that used to create the Map object, the key will be
 *              internally converted to the datatype for the map object.
 *              Any further options can be specified through the property
 *              list DXPL_ID.
 *
 * Return:      SUCCEED/FAIL
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id)
{
    H5VL_object_t *   vol_obj = NULL;
    H5VL_loc_params_t loc_params;
    herr_t            ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_API(FAIL)
    H5TRACE4("e", "ii*xi", map_id, key_mem_type_id, key, dxpl_id);

    /* Check arguments */
    if (key_mem_type_id < 0)
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")

    /* Get map pointer */
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")

    /* Get the default dataset transfer property list if the user didn't provide one */
    if (H5P_DEFAULT == dxpl_id)
        dxpl_id = H5P_DATASET_XFER_DEFAULT;
    else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")

    /* Set DXPL for operation */
    H5CX_set_dxpl(dxpl_id);

    /* Set location struct fields */
    loc_params.type     = H5VL_OBJECT_BY_SELF;
    loc_params.obj_type = H5I_get_type(map_id);

    /* Delete the key/value pair */
    if (H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, H5VL_MAP_DELETE,
                      key_mem_type_id, key) < 0)
        HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to delete key/value pair")

done:
    FUNC_LEAVE_API(ret_value)
} /* end H5Mdelete() */

#endif /*  H5_HAVE_MAP_API */