diff options
Diffstat (limited to 'src/H5I.c')
-rw-r--r-- | src/H5I.c | 196 |
1 files changed, 107 insertions, 89 deletions
@@ -33,9 +33,9 @@ #include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Dprivate.h" /* Datasets */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FLprivate.h" /* Free Lists */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5Gprivate.h" /* Groups */ #include "H5Ipkg.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ @@ -48,25 +48,26 @@ /* Local Macros */ /* Combine a Type number and an atom index into an atom */ -#define H5I_MAKE(g,i) ((((hid_t)(g) & TYPE_MASK) << ID_BITS) | \ - ((hid_t)(i) & ID_MASK)) +#define H5I_MAKE(g,i) ((((hid_t)(g) & TYPE_MASK) << ID_BITS) | \ + ((hid_t)(i) & ID_MASK)) /* Local typedefs */ /* Atom information structure used */ typedef struct H5I_id_info_t { - hid_t id; /* ID for this info */ - unsigned count; /* ref. count for this atom */ + hid_t id; /* ID for this info */ + unsigned count; /* ref. count for this atom */ unsigned app_count; /* ref. count of application visible atoms */ - const void *obj_ptr; /* pointer associated with the atom */ + const void *obj_ptr; /* pointer associated with the atom */ } H5I_id_info_t; /* ID type structure used */ typedef struct { const H5I_class_t *cls; /* Pointer to ID class */ - unsigned init_count; /* # of times this type has been initialized*/ - uint64_t id_count; /* Current number of IDs held */ - uint64_t nextid; /* ID to use for the next atom */ + unsigned init_count; /* # of times this type has been initialized*/ + uint64_t id_count; /* Current number of IDs held */ + uint64_t nextid; /* ID to use for the next atom */ + H5I_id_info_t *last_info; /* Info for most recent ID looked up */ H5SL_t *ids; /* Pointer to skip list that stores IDs */ } H5I_id_type_t; @@ -155,14 +156,14 @@ static int H5I__id_dump_cb(void *_item, void *_key, void *_udata); * Return: Success: Positive if any action was taken that might * affect some other interface; zero otherwise. * - * Failure: Negative + * Failure: Negative * *------------------------------------------------------------------------- */ int H5I_term_package(void) { - int n = 0; + int n = 0; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -292,7 +293,7 @@ done: herr_t H5I_register_type(const H5I_class_t *cls) { - H5I_id_type_t *type_ptr = NULL; /* Ptr to the atomic type*/ + H5I_id_type_t *type_ptr = NULL; /* Ptr to the atomic type*/ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -318,6 +319,7 @@ H5I_register_type(const H5I_class_t *cls) type_ptr->cls = cls; type_ptr->id_count = 0; type_ptr->nextid = cls->reserved; + type_ptr->last_info = NULL; if(NULL == (type_ptr->ids = H5SL_create(H5SL_TYPE_HID, NULL))) HGOTO_ERROR(H5E_ATOM, H5E_CANTCREATE, FAIL, "skip list creation failed") } /* end if */ @@ -326,7 +328,7 @@ H5I_register_type(const H5I_class_t *cls) type_ptr->init_count++; done: - if(ret_value < 0) { /* Clean up on error */ + if(ret_value < 0) { /* Clean up on error */ if(type_ptr) { if(type_ptr->ids) H5SL_close(type_ptr->ids); @@ -380,8 +382,8 @@ done: * * Return: SUCCEED/FAIL * - * Programmer: James Laird - * Nathaniel Furrer + * Programmer: James Laird + * Nathaniel Furrer * Friday, April 23, 2004 * *------------------------------------------------------------------------- @@ -430,7 +432,7 @@ done: * * Failure: Negative * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Wednesday, March 24, 1999 * *------------------------------------------------------------------------- @@ -510,8 +512,8 @@ H5I__unwrap(void *obj_ptr, H5I_type_t type) * * Return: SUCCEED/FAIL * - * Programmer: James Laird - * Nathaniel Furrer + * Programmer: James Laird + * Nathaniel Furrer * Friday, April 23, 2004 * *------------------------------------------------------------------------- @@ -542,7 +544,7 @@ done: * * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Wednesday, March 24, 1999 * *------------------------------------------------------------------------- @@ -653,8 +655,8 @@ H5I__clear_type_cb(void *_id, void H5_ATTR_UNUSED *key, void *_udata) * * Return: SUCCEED/FAIL * - * Programmer: Nathaniel Furrer - * James Laird + * Programmer: Nathaniel Furrer + * James Laird * *------------------------------------------------------------------------- */ @@ -686,15 +688,15 @@ done: * * Return: SUCCEED/FAIL * - * Programmer: Nathaniel Furrer - * James Laird + * Programmer: Nathaniel Furrer + * James Laird * *------------------------------------------------------------------------- */ static herr_t H5I__destroy_type(H5I_type_t type) { - H5I_id_type_t *type_ptr; /* ptr to the atomic type */ + H5I_id_type_t *type_ptr; /* ptr to the atomic type */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -807,6 +809,9 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref) /* Sanity check for the 'nextid' getting too large and wrapping around */ HDassert(type_ptr->nextid <= ID_MASK); + /* Set the most recent ID to this object */ + type_ptr->last_info = id_ptr; + /* Set return value */ ret_value = new_id; @@ -820,7 +825,7 @@ done: * * Purpose: Registers an OBJECT in a TYPE with the supplied ID for it. * This routine will check to ensure the supplied ID is not already - * in use, and ensure that it is a valid ID for the given type, + * in use, and ensure that it is a valid ID for the given type, * but will NOT check to ensure the OBJECT is not already * registered (thus, it is possible to register one object under * multiple IDs). @@ -878,6 +883,9 @@ H5I_register_using_existing_id(H5I_type_t type, void *object, hbool_t app_ref, h HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, FAIL, "can't insert ID node into skip list") type_ptr->id_count++; + /* Set the most recent ID to this object */ + type_ptr->last_info = id_ptr; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_register_using_existing_id() */ @@ -892,8 +900,8 @@ done: * with the specified ID. * Failure: NULL * - * Programmer: Quincey Koziol - * Saturday, February 27, 2010 + * Programmer: Quincey Koziol + * Saturday, February 27, 2010 * *------------------------------------------------------------------------- */ @@ -901,7 +909,7 @@ void * H5I_subst(hid_t id, const void *new_object) { H5I_id_info_t *id_ptr; /* Pointer to the atom */ - void *ret_value = NULL; /* Return value */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(NULL) @@ -935,8 +943,8 @@ done: void * H5I_object(hid_t id) { - H5I_id_info_t *id_ptr; /* Pointer to the new atom */ - void *ret_value = NULL; /* Return value */ + H5I_id_info_t *id_ptr; /* Pointer to the new atom */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOERR @@ -994,8 +1002,8 @@ done: * specified ID. * Failure: NULL * - * Programmer: Quincey Koziol - * Wednesday, July 31, 2002 + * Programmer: Quincey Koziol + * Wednesday, July 31, 2002 * *------------------------------------------------------------------------- */ @@ -1032,8 +1040,8 @@ H5I_object_verify(hid_t id, H5I_type_t id_type) * ID types). * Failure: H5I_BADID * - * Programmer: Robb Matzke - * Friday, February 19, 1999 + * Programmer: Robb Matzke + * Friday, February 19, 1999 * *------------------------------------------------------------------------- */ @@ -1079,7 +1087,7 @@ H5Iget_type(hid_t id) ret_value = H5I_get_type(id); if(ret_value <= H5I_BADID || (int)ret_value >= H5I_next_type || NULL == H5I_object(id)) - HGOTO_DONE(H5I_BADID); + HGOTO_DONE(H5I_BADID); done: FUNC_LEAVE_API(ret_value) @@ -1116,9 +1124,8 @@ H5I_is_file_object(hid_t id) /* Return TRUE if the ID is a file object (dataset, group, map, or committed * datatype), FALSE otherwise. */ - if (H5I_DATASET == id_type || H5I_GROUP == id_type || H5I_MAP == id_type) { + if (H5I_DATASET == id_type || H5I_GROUP == id_type || H5I_MAP == id_type) ret_value = TRUE; - } else if (H5I_DATATYPE == id_type) { H5T_t *dt = NULL; @@ -1128,9 +1135,8 @@ H5I_is_file_object(hid_t id) ret_value = H5T_is_named(dt); } - else { + else ret_value = FALSE; - } done: FUNC_LEAVE_NOAPI(ret_value); @@ -1149,8 +1155,8 @@ done: * calling H5I_object(). * Failure: NULL * - * Programmer: James Laird - * Nathaniel Furrer + * Programmer: James Laird + * Nathaniel Furrer * *------------------------------------------------------------------------- */ @@ -1184,15 +1190,15 @@ done: * calling H5I_object(). * Failure: NULL * - * Programmer: James Laird - * Nat Furrer + * Programmer: James Laird + * Nat Furrer * *------------------------------------------------------------------------- */ static void * H5I__remove_verify(hid_t id, H5I_type_t id_type) { - void * ret_value = NULL; /*return value */ + void * ret_value = NULL; /*return value */ FUNC_ENTER_STATIC_NOERR @@ -1224,8 +1230,8 @@ H5I__remove_verify(hid_t id, H5I_type_t id_type) static void * H5I__remove_common(H5I_id_type_t *type_ptr, hid_t id) { - H5I_id_info_t *curr_id; /* Pointer to the current atom */ - void *ret_value = NULL; /* Return value */ + H5I_id_info_t *curr_id; /* Pointer to the current atom */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -1236,6 +1242,10 @@ H5I__remove_common(H5I_id_type_t *type_ptr, hid_t id) if(NULL == (curr_id = (H5I_id_info_t *)H5SL_remove(type_ptr->ids, &id))) HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, NULL, "can't remove ID node from skip list") + /* Check if this ID was the last one accessed */ + if(type_ptr->last_info == curr_id) + type_ptr->last_info = NULL; + ret_value = (void *)curr_id->obj_ptr; /* (Casting away const OK -QAK) */ curr_id = H5FL_FREE(H5I_id_info_t, curr_id); @@ -1257,16 +1267,16 @@ done: * calling H5I_object(). * Failure: NULL * - * Programmer: Unknown + * Programmer: Unknown * *------------------------------------------------------------------------- */ void * H5I_remove(hid_t id) { - H5I_id_type_t *type_ptr; /* Pointer to the atomic type */ - H5I_type_t type; /* Atom's atomic type */ - void * ret_value = NULL; /* Return value */ + H5I_id_type_t *type_ptr; /* Pointer to the atomic type */ + H5I_type_t type; /* Atom's atomic type */ + void * ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(NULL) @@ -1361,14 +1371,14 @@ H5I_dec_ref(hid_t id) * reference count without calling the free method. * * Beware: the free method may call other H5I functions. - * - * If an object is closing, we can remove the ID even though the free + * + * If an object is closing, we can remove the ID even though the free * method might fail. This can happen when a mandatory filter fails to - * write when a dataset is closed and the chunk cache is flushed to the + * write when a dataset is closed and the chunk cache is flushed to the * file. We have to close the dataset anyway. (SLU - 2010/9/7) */ if(1 == id_ptr->count) { - H5I_id_type_t *type_ptr; /*ptr to the type */ + H5I_id_type_t *type_ptr; /*ptr to the type */ /* Get the ID's type */ type_ptr = H5I_id_type_list_g[H5I_TYPE(id)]; @@ -1468,9 +1478,9 @@ H5I_dec_app_ref_always_close(hid_t id) /* Check for failure */ if (ret_value < 0) { /* - * If an object is closing, we can remove the ID even though the free + * If an object is closing, we can remove the ID even though the free * method might fail. This can happen when a mandatory filter fails to - * write when a dataset is closed and the chunk cache is flushed to the + * write when a dataset is closed and the chunk cache is flushed to the * file. We have to close the dataset anyway. (SLU - 2010/9/7) */ H5I_remove(id); @@ -1689,7 +1699,7 @@ done: * Purpose: Decrements the reference count on an entire type of IDs. * If the type reference count becomes zero then the type is * destroyed along with all atoms in that type regardless of - * their reference counts. Destroying IDs involves calling + * their reference counts. Destroying IDs involves calling * the free-func for each ID's object and then adding the ID * struct to the ID free list. Public interface to * H5I_dec_type_ref. @@ -1731,7 +1741,7 @@ done: * Purpose: Decrements the reference count on an entire type of IDs. * If the type reference count becomes zero then the type is * destroyed along with all atoms in that type regardless of - * their reference counts. Destroying IDs involves calling + * their reference counts. Destroying IDs involves calling * the free-func for each ID's object and then adding the ID * struct to the ID free list. * Returns the number of references to the type on success; a @@ -1901,7 +1911,7 @@ H5I__search_cb(void *obj, hid_t id, void *_udata) /* Set the return value based on the callback's return value */ if(cb_ret_val > 0) { - ret_value = H5_ITER_STOP; /* terminate iteration early */ + ret_value = H5_ITER_STOP; /* terminate iteration early */ udata->ret_obj = obj; /* also set out parameter */ } else if(cb_ret_val < 0) @@ -1949,7 +1959,7 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) udata.app_key = key; udata.ret_obj = NULL; - /* Note that H5I_iterate returns an error code. We ignore it + /* Note that H5I_iterate returns an error code. We ignore it * here, as we can't do anything with it without revising the API. */ (void)H5I_iterate(type, H5I__search_cb, &udata, TRUE); @@ -1992,7 +2002,7 @@ H5I__iterate_pub_cb(void H5_ATTR_UNUSED *obj, hid_t id, void *_udata) /* Set the return value based on the callback's return value */ if(cb_ret_val > 0) - ret_value = H5_ITER_STOP; /* terminate iteration early */ + ret_value = H5_ITER_STOP; /* terminate iteration early */ else if(cb_ret_val < 0) ret_value = H5_ITER_ERROR; /* indicate failure (which terminates iteration) */ else @@ -2088,7 +2098,7 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /* Set the return value based on the callback's return value */ if(cb_ret_val > 0) - ret_value = H5_ITER_STOP; /* terminate iteration early */ + ret_value = H5_ITER_STOP; /* terminate iteration early */ else if(cb_ret_val < 0) ret_value = H5_ITER_ERROR; /* indicate failure (which terminates iteration) */ } /* end if */ @@ -2098,24 +2108,24 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /*------------------------------------------------------------------------- - * Function: H5I_iterate + * Function: H5I_iterate * - * Purpose: Apply function FUNC to each member of type TYPE (with - * non-zero application reference count if app_ref is TRUE). - * Stop if FUNC returns a non zero value (i.e. anything - * other than H5_ITER_CONT). + * Purpose: Apply function FUNC to each member of type TYPE (with + * non-zero application reference count if app_ref is TRUE). + * Stop if FUNC returns a non zero value (i.e. anything + * other than H5_ITER_CONT). * - * If FUNC returns a positive value (i.e. H5_ITER_STOP), + * If FUNC returns a positive value (i.e. H5_ITER_STOP), * return SUCCEED. * - * If FUNC returns a negative value (i.e. H5_ITER_ERROR), + * If FUNC returns a negative value (i.e. H5_ITER_ERROR), * return FAIL. - * - * The FUNC should take a pointer to the object and the - * udata as arguments and return non-zero to terminate + * + * The FUNC should take a pointer to the object and the + * udata as arguments and return non-zero to terminate * siteration, and zero to continue. * - * Limitation: Currently there is no way to start the iteration from + * Limitation: Currently there is no way to start the iteration from * where a previous iteration left off. * * Return: SUCCEED/FAIL @@ -2126,7 +2136,7 @@ herr_t H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref) { H5I_id_type_t *type_ptr; /* Pointer to the type */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -2171,9 +2181,9 @@ done: static H5I_id_info_t * H5I__find_id(hid_t id) { - H5I_type_t type; /*ID's type */ - H5I_id_type_t *type_ptr; /*ptr to the type */ - H5I_id_info_t *ret_value = NULL; /* Return value */ + H5I_type_t type; /*ID's type */ + H5I_id_type_t *type_ptr; /*ptr to the type */ + H5I_id_info_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC_NOERR @@ -2185,8 +2195,16 @@ H5I__find_id(hid_t id) if(!type_ptr || type_ptr->init_count <= 0) HGOTO_DONE(NULL) - /* Locate the ID node for the ID */ - ret_value = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id); + /* Check for same ID as we have looked up last time */ + if(type_ptr->last_info && type_ptr->last_info->id == id) + ret_value = type_ptr->last_info; + else { + /* Locate the ID node for the ID */ + ret_value = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id); + + /* Remember this ID */ + type_ptr->last_info = ret_value; + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -2394,9 +2412,9 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) FUNC_ENTER_STATIC_NOERR - HDfprintf(stderr, " id = %lu\n", (unsigned long)(item->id)); - HDfprintf(stderr, " count = %u\n", item->count); - HDfprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(item->obj_ptr)); + HDfprintf(stderr, " id = %lu\n", (unsigned long)(item->id)); + HDfprintf(stderr, " count = %u\n", item->count); + HDfprintf(stderr, " obj = 0x%08p\n", item->obj_ptr); /* Get the group location, so we get get the name */ switch (type) { @@ -2485,14 +2503,14 @@ H5I_dump_ids_for_type(H5I_type_t type) if(type_ptr) { /* Header */ - HDfprintf(stderr, " init_count = %u\n", type_ptr->init_count); - HDfprintf(stderr, " reserved = %u\n", type_ptr->cls->reserved); - HDfprintf(stderr, " id_count = %llu\n", (unsigned long long)type_ptr->id_count); - HDfprintf(stderr, " nextid = %llu\n", (unsigned long long)type_ptr->nextid); + HDfprintf(stderr, " init_count = %u\n", type_ptr->init_count); + HDfprintf(stderr, " reserved = %u\n", type_ptr->cls->reserved); + HDfprintf(stderr, " id_count = %llu\n", (unsigned long long)type_ptr->id_count); + HDfprintf(stderr, " nextid = %llu\n", (unsigned long long)type_ptr->nextid); /* List */ if(type_ptr->id_count > 0) { - HDfprintf(stderr, " List:\n"); + HDfprintf(stderr, " List:\n"); H5SL_iterate(type_ptr->ids, H5I__id_dump_cb, &type); } } |