summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2013-10-07 22:04:27 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2013-10-07 22:04:27 (GMT)
commit3a96de8b17df2964f4ad7da5c9742b3bd71b3c38 (patch)
tree93e44fbe16b9b6227fb28f7f415939a1e1602237
parent307f88870c18d050912cb7bb614480420a794a9c (diff)
downloadhdf5-3a96de8b17df2964f4ad7da5c9742b3bd71b3c38.zip
hdf5-3a96de8b17df2964f4ad7da5c9742b3bd71b3c38.tar.gz
hdf5-3a96de8b17df2964f4ad7da5c9742b3bd71b3c38.tar.bz2
[svn-r24262] Description:
Bring r24256 & r24261 from trunk to 1.8 branch: Switch H5I internal data structure from using hash table to skip lists. Also, a few misc. cleanups. Tested on: FreeBSD/32 8.2 (loyalty) w/gcc4.6, w/C++ & FORTRAN, in debug mode FreeBSD/64 8.2 (freedom) w/gcc4.6, w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (koala) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.11 (emu) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (ostrich) w/C++ & FORTRAN, w/threadsafe, in debug mode
-rwxr-xr-xconfigure60
-rw-r--r--configure.ac6
-rw-r--r--src/H5A.c3
-rw-r--r--src/H5ACprivate.h3
-rw-r--r--src/H5B2cache.c8
-rw-r--r--src/H5Dint.c3
-rw-r--r--src/H5E.c9
-rw-r--r--src/H5F.c3
-rw-r--r--src/H5FD.c3
-rw-r--r--src/H5Fprivate.h1
-rw-r--r--src/H5G.c3
-rw-r--r--src/H5I.c889
-rw-r--r--src/H5Iprivate.h6
-rw-r--r--src/H5Pint.c4
-rw-r--r--src/H5R.c3
-rw-r--r--src/H5S.c3
-rw-r--r--src/H5SL.c43
-rw-r--r--src/H5SLprivate.h1
-rw-r--r--src/H5T.c1
-rw-r--r--src/H5private.h36
20 files changed, 549 insertions, 539 deletions
diff --git a/configure b/configure
index d14cee2..76e84f6 100755
--- a/configure
+++ b/configure
@@ -28775,9 +28775,9 @@ else
unset MPE
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CLOG_Init in -llmpe" >&5
-$as_echo_n "checking for CLOG_Init in -llmpe... " >&6; }
-if ${ac_cv_lib_lmpe_CLOG_Init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPE_Init_mpi_io in -llmpe" >&5
+$as_echo_n "checking for MPE_Init_mpi_io in -llmpe... " >&6; }
+if ${ac_cv_lib_lmpe_MPE_Init_mpi_io+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -28791,7 +28791,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char CLOG_Init ();
+char MPE_Init_mpi_io ();
#ifdef FC_DUMMY_MAIN
#ifndef FC_DUMMY_MAIN_EQ_F77
# ifdef __cplusplus
@@ -28803,23 +28803,23 @@ char CLOG_Init ();
int
main ()
{
-return CLOG_Init ();
+return MPE_Init_mpi_io ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_lmpe_CLOG_Init=yes
+ ac_cv_lib_lmpe_MPE_Init_mpi_io=yes
else
- ac_cv_lib_lmpe_CLOG_Init=no
+ ac_cv_lib_lmpe_MPE_Init_mpi_io=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmpe_CLOG_Init" >&5
-$as_echo "$ac_cv_lib_lmpe_CLOG_Init" >&6; }
-if test "x$ac_cv_lib_lmpe_CLOG_Init" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmpe_MPE_Init_mpi_io" >&5
+$as_echo "$ac_cv_lib_lmpe_MPE_Init_mpi_io" >&6; }
+if test "x$ac_cv_lib_lmpe_MPE_Init_mpi_io" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBLMPE 1
_ACEOF
@@ -28950,9 +28950,9 @@ else
LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset MPE
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CLOG_Init in -llmpe" >&5
-$as_echo_n "checking for CLOG_Init in -llmpe... " >&6; }
-if ${ac_cv_lib_lmpe_CLOG_Init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPE_Init_mpi_io in -llmpe" >&5
+$as_echo_n "checking for MPE_Init_mpi_io in -llmpe... " >&6; }
+if ${ac_cv_lib_lmpe_MPE_Init_mpi_io+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -28966,7 +28966,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char CLOG_Init ();
+char MPE_Init_mpi_io ();
#ifdef FC_DUMMY_MAIN
#ifndef FC_DUMMY_MAIN_EQ_F77
# ifdef __cplusplus
@@ -28978,23 +28978,23 @@ char CLOG_Init ();
int
main ()
{
-return CLOG_Init ();
+return MPE_Init_mpi_io ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_lmpe_CLOG_Init=yes
+ ac_cv_lib_lmpe_MPE_Init_mpi_io=yes
else
- ac_cv_lib_lmpe_CLOG_Init=no
+ ac_cv_lib_lmpe_MPE_Init_mpi_io=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmpe_CLOG_Init" >&5
-$as_echo "$ac_cv_lib_lmpe_CLOG_Init" >&6; }
-if test "x$ac_cv_lib_lmpe_CLOG_Init" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmpe_MPE_Init_mpi_io" >&5
+$as_echo "$ac_cv_lib_lmpe_MPE_Init_mpi_io" >&6; }
+if test "x$ac_cv_lib_lmpe_MPE_Init_mpi_io" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBLMPE 1
_ACEOF
@@ -29062,9 +29062,9 @@ else
unset MPE
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CLOG_Init in -llmpe" >&5
-$as_echo_n "checking for CLOG_Init in -llmpe... " >&6; }
-if ${ac_cv_lib_lmpe_CLOG_Init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPE_Init_mpi_io in -llmpe" >&5
+$as_echo_n "checking for MPE_Init_mpi_io in -llmpe... " >&6; }
+if ${ac_cv_lib_lmpe_MPE_Init_mpi_io+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -29078,7 +29078,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char CLOG_Init ();
+char MPE_Init_mpi_io ();
#ifdef FC_DUMMY_MAIN
#ifndef FC_DUMMY_MAIN_EQ_F77
# ifdef __cplusplus
@@ -29090,23 +29090,23 @@ char CLOG_Init ();
int
main ()
{
-return CLOG_Init ();
+return MPE_Init_mpi_io ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_lmpe_CLOG_Init=yes
+ ac_cv_lib_lmpe_MPE_Init_mpi_io=yes
else
- ac_cv_lib_lmpe_CLOG_Init=no
+ ac_cv_lib_lmpe_MPE_Init_mpi_io=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmpe_CLOG_Init" >&5
-$as_echo "$ac_cv_lib_lmpe_CLOG_Init" >&6; }
-if test "x$ac_cv_lib_lmpe_CLOG_Init" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmpe_MPE_Init_mpi_io" >&5
+$as_echo "$ac_cv_lib_lmpe_MPE_Init_mpi_io" >&6; }
+if test "x$ac_cv_lib_lmpe_MPE_Init_mpi_io" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBLMPE 1
_ACEOF
diff --git a/configure.ac b/configure.ac
index 78108ec..3291bfc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2864,7 +2864,7 @@ if test -n "$PARALLEL"; then
X-yes)
AC_CHECK_HEADERS([mpe.h],, [unset MPE])
AC_CHECK_LIB([mpe], [MPE_Init_log],, [unset MPE])
- AC_CHECK_LIB([lmpe], [CLOG_Init],, [unset MPE])
+ AC_CHECK_LIB([lmpe], [MPE_Init_mpi_io],, [unset MPE])
;;
*)
case "$withval" in
@@ -2906,12 +2906,12 @@ if test -n "$PARALLEL"; then
AM_LDFLAGS="$AM_LDFLAGS -L$mpe_lib"
AC_CHECK_LIB([mpe], [MPE_Init_log],,
[LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset MPE])
- AC_CHECK_LIB([lmpe], [CLOG_Init],,
+ AC_CHECK_LIB([lmpe], [MPE_Init_mpi_io],,
[LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset MPE])
else
AC_CHECK_LIB([mpe], [MPE_Init_log],, [unset MPE])
- AC_CHECK_LIB([lmpe], [CLOG_Init],, [unset MPE])
+ AC_CHECK_LIB([lmpe], [MPE_Init_mpi_io],, [unset MPE])
fi
;;
esac
diff --git a/src/H5A.c b/src/H5A.c
index a423fb6..f0c0580 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -94,8 +94,7 @@ H5FL_BLK_DEFINE(attr_buf);
/* Attribute ID class */
static const H5I_class_t H5I_ATTR_CLS[1] = {{
H5I_ATTR, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5A_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index 68412a0..2e7bcd7 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -319,8 +319,7 @@ H5_DLL herr_t H5AC_insert_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *typ
haddr_t addr, void *thing, unsigned int flags);
H5_DLL herr_t H5AC_pin_protected_entry(void *thing);
H5_DLL void * H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
- haddr_t addr, void *udata,
- H5AC_protect_t rw);
+ haddr_t addr, void *udata, H5AC_protect_t rw);
H5_DLL herr_t H5AC_resize_entry(void *thing, size_t new_size);
H5_DLL herr_t H5AC_unpin_entry(void *thing);
H5_DLL herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id,
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index 87684f0..4d4b69f 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -190,12 +190,12 @@ H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Magic number */
if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header signature")
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree header signature")
p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5B2_HDR_VERSION)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header version")
+ HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree header version")
/* B-tree class */
id = (H5B2_subid_t)*p++;
@@ -529,12 +529,12 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Magic number */
if(HDmemcmp(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree internal node signature")
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree internal node signature")
p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5B2_INT_VERSION)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree internal node version")
+ HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree internal node version")
/* B-tree type */
if(*p++ != (uint8_t)udata->hdr->cls->id)
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 8ce842b..1704c0f 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -109,8 +109,7 @@ static H5D_shared_t H5D_def_dset;
/* Dataset ID class */
static const H5I_class_t H5I_DATASET_CLS[1] = {{
H5I_DATASET, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5D_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5E.c b/src/H5E.c
index 6f13b1a..9f89c93 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -122,8 +122,7 @@ H5FL_DEFINE_STATIC(H5E_msg_t);
/* Error class ID class */
static const H5I_class_t H5I_ERRCLS_CLS[1] = {{
H5I_ERROR_CLASS, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5E_unregister_class /* Callback routine for closing objects of this class */
}};
@@ -131,8 +130,7 @@ static const H5I_class_t H5I_ERRCLS_CLS[1] = {{
/* Error message ID class */
static const H5I_class_t H5I_ERRMSG_CLS[1] = {{
H5I_ERROR_MSG, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5E_close_msg /* Callback routine for closing objects of this class */
}};
@@ -140,8 +138,7 @@ static const H5I_class_t H5I_ERRMSG_CLS[1] = {{
/* Error stack ID class */
static const H5I_class_t H5I_ERRSTK_CLS[1] = {{
H5I_ERROR_STACK, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5E_close_stack /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5F.c b/src/H5F.c
index 127df3c..8f71a84 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -122,8 +122,7 @@ H5FL_DEFINE(H5F_file_t);
/* File ID class */
static const H5I_class_t H5I_FILE_CLS[1] = {{
H5I_FILE, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5F_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5FD.c b/src/H5FD.c
index 85d9266..5408706 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -116,8 +116,7 @@ static unsigned long file_serial_no;
/* File driver ID class */
static const H5I_class_t H5I_VFL_CLS[1] = {{
H5I_VFL, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5FD_free_cls /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 770d868..1c6913c 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -501,7 +501,6 @@ H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f);
H5_DLL hid_t H5F_get_file_id(const H5F_t *f);
H5_DLL H5F_t *H5F_get_parent(const H5F_t *f);
H5_DLL unsigned H5F_get_nmounts(const H5F_t *f);
-H5_DLL herr_t H5F_flush_mounts(H5F_t *f, hid_t dxpl_id);
H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref);
H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref);
H5_DLL herr_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr);
diff --git a/src/H5G.c b/src/H5G.c
index 1bd98a6..0cfa06b 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -133,8 +133,7 @@
/* Group ID class */
static const H5I_class_t H5I_GROUP_CLS[1] = {{
H5I_GROUP, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5G_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5I.c b/src/H5I.c
index dbbc679..d4654da 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -48,6 +48,7 @@
#include "H5Ipkg.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
+#include "H5SLprivate.h" /* Skip Lists */
/* Define this to compile in support for dumping ID information */
/* #define H5I_DEBUG_OUTPUT */
@@ -66,25 +67,6 @@
for re-use. */
#define MAX_FREE_ID_STRUCTS 1000
-/*
- * Define the following macro for fast hash calculations (but limited
- * hash sizes)
- */
-#define HASH_SIZE_POWER_2
-
-#ifdef HASH_SIZE_POWER_2
-/*
- * Map an ID to a hash location (assumes s is a power of 2 and smaller
- * than the ID_MASK constant).
- */
-# define H5I_LOC(a,s) ((hid_t)((size_t)(a)&((s)-1)))
-#else
-/*
- * Map an ID to a hash location.
- */
-# define H5I_LOC(a,s) (((hid_t)(a)&ID_MASK)%(s))
-#endif
-
/* 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))
@@ -97,20 +79,20 @@ typedef struct H5I_id_info_t {
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 */
- struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/
} H5I_id_info_t;
/* ID type structure used */
typedef struct {
const H5I_class_t *cls; /* Pointer to ID class */
- unsigned count; /*# of times this type has been initialized*/
- unsigned free_count; /* # of available ID structures awaiting recycling */
- unsigned wrapped; /*whether the id count has wrapped around */
- unsigned ids; /*current number of IDs held */
- unsigned nextid; /*ID to use for the next atom */
- unsigned reuse_ids; /* whether to reuse returned IDs for this type */
- H5I_id_info_t * next_id_ptr; /* pointer to head of available ID list */
- H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */
+ unsigned init_count; /* # of times this type has been initialized*/
+ hbool_t wrapped; /* Whether the id count has wrapped around */
+ unsigned id_count; /* Current number of IDs held */
+ hid_t nextid; /* ID to use for the next atom */
+ H5SL_t *ids; /* Pointer to skip list that stores IDs */
+
+ /* Fields for holding available IDs */
+ unsigned avail_count; /* # of available ID structures awaiting recycling */
+ H5SL_t *avail_ids; /* pointer to skip list of available IDs */
} H5I_id_type_t;
typedef struct {
@@ -119,6 +101,18 @@ typedef struct {
void *ret_obj; /* Object to return */
} H5I_search_ud_t;
+/* User data for iterator callback when IDs have wrapped */
+typedef struct {
+ hid_t nextid; /* Next ID to expect */
+} H5I_wrap_ud_t;
+
+/* User data for iterator callback for ID iteration */
+typedef struct {
+ H5I_search_func_t user_func; /* 'User' function to invoke */
+ void *user_udata; /* User data to pass to 'user' function */
+ hbool_t app_ref; /* Whether this is an appl. ref. call */
+} H5I_iterate_ud_t;
+
/*-------------------- Locally scoped variables -----------------------------*/
/* Array of pointers to atomic types */
@@ -142,10 +136,15 @@ H5FL_DEFINE_STATIC(H5I_id_type_t);
H5FL_DEFINE_STATIC(H5I_class_t);
/*--------------------- Local function prototypes ---------------------------*/
-static H5I_id_info_t *H5I_find_id(hid_t id);
-static int H5I_search_cb(void *obj, hid_t id, void *udata);
+static herr_t H5I__free_cb(void *_item, void *_key, void *_udata);
+static int H5I__destroy_type(H5I_type_t type);
+static void *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);
+static int H5I__inc_type_ref(H5I_type_t type);
+static int H5I__get_type_ref(H5I_type_t type);
+static H5I_id_info_t *H5I__find_id(hid_t id);
#ifdef H5I_DEBUG_OUTPUT
-static herr_t H5I_debug(H5I_type_t type);
+static herr_t H5I__debug(H5I_type_t type);
#endif /* H5I_DEBUG_OUTPUT */
@@ -198,7 +197,7 @@ H5I_term_interface(void)
if(H5_interface_initialize_g) {
/* How many types are still being used? */
for(type = (H5I_type_t)0; type < H5I_next_type; H5_INC_ENUM(H5I_type_t, type)) {
- if((type_ptr = H5I_id_type_list_g[type]) && type_ptr->id_list)
+ if((type_ptr = H5I_id_type_list_g[type]) && type_ptr->ids)
n++;
} /* end for */
@@ -207,7 +206,7 @@ H5I_term_interface(void)
for(type = (H5I_type_t)0; type < H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
type_ptr = H5I_id_type_list_g[type];
if(type_ptr) {
- HDassert(NULL == type_ptr->id_list);
+ HDassert(NULL == type_ptr->ids);
type_ptr = H5FL_FREE(H5I_id_type_t, type_ptr);
H5I_id_type_list_g[type] = NULL;
} /* end if */
@@ -286,7 +285,6 @@ H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func)
/* Initialize class fields */
cls->type_id = new_type;
cls->flags = H5I_CLASS_IS_APPLICATION;
- cls->hash_size = hash_size;
cls->reserved = reserved;
cls->free_func = free_func;
@@ -337,13 +335,6 @@ H5I_register_type(const H5I_class_t *cls)
HDassert(cls->type_id > 0 && cls->type_id < H5I_MAX_NUM_TYPES);
/* Initialize the type */
-
- /* Check arguments */
-#ifdef HASH_SIZE_POWER_2
- if(!POWER_OF_TWO(cls->hash_size) || cls->hash_size == 1)
- HGOTO_ERROR(H5E_ATOM, H5E_BADRANGE, FAIL, "invalid hash size")
-#endif /* HASH_SIZE_POWER_2 */
-
if(NULL == H5I_id_type_list_g[cls->type_id]) {
/* Allocate the type information for new type */
if(NULL == (type_ptr = (H5I_id_type_t *)H5FL_CALLOC(H5I_id_type_t)))
@@ -356,35 +347,28 @@ H5I_register_type(const H5I_class_t *cls)
} /* end else */
/* Initialize the ID type structure for new types */
- if(type_ptr->count == 0) {
+ if(type_ptr->init_count == 0) {
type_ptr->cls = cls;
- type_ptr->wrapped = 0;
- type_ptr->ids = 0;
- type_ptr->nextid = cls->reserved;
- type_ptr->next_id_ptr = NULL;
- type_ptr->id_list = (H5I_id_info_t **)H5MM_calloc(cls->hash_size * sizeof(H5I_id_info_t *));
- if(NULL == type_ptr->id_list)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed")
-
- /* Don't re-use IDs for property lists, as this causes problems
- * with some virtual file drivers. Also, open datatypes are not
- * getting reduced to zero before file close in some situations,
- * resulting in memory leak, so skip them for now as well. */
- if(cls->type_id == H5I_GENPROP_LST || cls->type_id == H5I_DATATYPE)
- type_ptr->reuse_ids = FALSE;
- else
- type_ptr->reuse_ids = TRUE;
-
+ type_ptr->wrapped = FALSE;
+ type_ptr->id_count = 0;
+ type_ptr->nextid = (hid_t)cls->reserved;
+ if(NULL == (type_ptr->ids = H5SL_create(H5SL_TYPE_HID, NULL)))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTCREATE, FAIL, "skip list creation failed")
+ type_ptr->avail_count = 0;
+ if(NULL == (type_ptr->avail_ids = H5SL_create(H5SL_TYPE_HID, NULL)))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTCREATE, FAIL, "skip list creation failed")
} /* end if */
/* Increment the count of the times this type has been initialized */
- type_ptr->count++;
+ type_ptr->init_count++;
done:
if(ret_value < 0) { /* Clean up on error */
if(type_ptr) {
- if(type_ptr->id_list)
- H5MM_xfree(type_ptr->id_list);
+ if(type_ptr->ids)
+ H5SL_close(type_ptr->ids);
+ if(type_ptr->avail_ids)
+ H5SL_close(type_ptr->avail_ids);
(void)H5FL_FREE(H5I_id_type_t, type_ptr);
} /* end if */
} /* end if */
@@ -503,11 +487,11 @@ H5I_nmembers(H5I_type_t type)
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
- if(NULL == (type_ptr = H5I_id_type_list_g[type]) || type_ptr->count <= 0)
+ if(NULL == (type_ptr = H5I_id_type_list_g[type]) || type_ptr->init_count <= 0)
HGOTO_DONE(0);
/* Set return value */
- H5_ASSIGN_OVERFLOW(ret_value, type_ptr->ids, unsigned, int);
+ H5_ASSIGN_OVERFLOW(ret_value, type_ptr->id_count, unsigned, int);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -549,6 +533,35 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5I__free_cb
+ *
+ * Purpose: Callback for freeing ID nodes in H5I__remove_common
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, October 4, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5I__free_cb(void *_item, void UNUSED *_key, void UNUSED *_udata)
+{
+ H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity check */
+ HDassert(item);
+
+ item = H5FL_FREE(H5I_id_info_t, item);
+
+ FUNC_LEAVE_NOAPI(H5_ITER_CONT)
+} /* end H5I__free_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5I_clear_type
*
* Purpose: Removes all objects from the type, calling the free
@@ -560,32 +573,14 @@ done:
* Programmer: Robb Matzke
* Wednesday, March 24, 1999
*
- * Modifications:
- * Robb Matzke, 1999-04-27
- * If FORCE is zero then any item for which the free callback
- * failed is not removed. This function returns failure if
- * items could not be removed.
- *
- * Robb Matzke, 1999-08-17
- * If the object reference count is larger than one then it must
- * be because the library is using the object internally. This
- * happens for instance for file driver ID's which are stored in
- * things like property lists, files, etc. Objects that have a
- * reference count larger than one are not affected unless FORCE
- * is non-zero.
- *
- * Neil Fortner, 2008-08-08
- * Added app_ref parameter. If app_ref is FALSE, then the
- * application reference count is ignored (i.e. subtracted from
- * the total reference count) when determining which id's to
- * close.
*-------------------------------------------------------------------------
*/
herr_t
H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref)
{
H5I_id_type_t *type_ptr; /* ptr to the atomic type */
- unsigned i; /* Local index variable */
+ H5SL_node_t *curr_node; /* Current skip list node ptr */
+ H5SL_node_t *next_node; /* Next skip list node ptr */
int ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -594,7 +589,7 @@ H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(type_ptr == NULL || type_ptr->count <= 0)
+ if(type_ptr == NULL || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/*
@@ -602,22 +597,21 @@ H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref)
* counts. Ignore the return value from from the free method and remove
* object from type regardless if FORCE is non-zero.
*/
- for(i = 0; i < type_ptr->cls->hash_size; i++) {
- H5I_id_info_t *cur; /* Current node being worked with */
- H5I_id_info_t *next; /* Next node in list */
-
- for(cur = type_ptr->id_list[i]; cur; cur = next) {
- hbool_t delete_node; /* Flag to indicate node should be removed from linked list */
-
- /*
- * Do nothing to the object if the reference count is larger than
- * one and forcing is off.
- */
- if(!force && (cur->count - (!app_ref * cur->app_count)) > 1) {
- next = cur->next;
- continue;
- } /* end if */
+ for(curr_node = H5SL_first(type_ptr->ids); curr_node; curr_node = next_node) {
+ H5I_id_info_t *cur; /* Current ID being worked with */
+ hbool_t delete_node; /* Flag to indicate node should be removed from linked list */
+
+ /* Get ID for this node */
+ if(NULL == (cur = (H5I_id_info_t *)H5SL_item(curr_node)))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID info for node")
+ /*
+ * Do nothing to the object if the reference count is larger than
+ * one and forcing is off.
+ */
+ if(!force && (cur->count - (!app_ref * cur->app_count)) > 1)
+ delete_node = FALSE;
+ else {
/* Check for a 'free' function and call it, if it exists */
/* (Casting away const OK -QAK) */
if(type_ptr->cls->free_func && (type_ptr->cls->free_func)((void *)cur->obj_ptr) < 0) {
@@ -642,62 +636,31 @@ H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref)
/* Indicate node should be removed from list */
delete_node = TRUE;
} /* end else */
+ } /* end else */
- /* Check if we should delete this node or not */
- if(delete_node) {
- H5I_id_info_t *last; /* Last node seen */
- H5I_id_info_t *tmp; /* Temporary node ptr */
-
- /* Decrement the number of IDs in the type */
- (type_ptr->ids)--;
-
- /* Advance to next node */
- next = cur->next;
-
- /* Re-scan the list of nodes and remove the node from the list */
- /* (can't maintain static pointers to the previous node in the */
- /* list, because the node's 'free' callback could have */
- /* make an H5I call, which could potentially change the */
- /* order of the nodes on the list - QAK) */
- last = NULL;
- tmp = type_ptr->id_list[i];
- while(tmp != cur) {
- HDassert(tmp != NULL);
- last = tmp;
- tmp = tmp->next;
- } /* end while */
-
- /* Delete the node from the list */
- if(NULL == last) {
- /* Node at head of list, just advance the list head to next node */
- HDassert(type_ptr->id_list[i] == cur);
- type_ptr->id_list[i] = next;
- } /* end if */
- else {
- /* Node in middle of list, jump over it */
- HDassert(last->next == cur);
- last->next = next;
- } /* end else */
+ /* Get the next node in the list */
+ next_node = H5SL_next(curr_node);
- /* Free the node */
- cur = H5FL_FREE(H5I_id_info_t, cur);
- } /* end if */
- else {
- /* Advance to next node */
- next = cur->next;
- } /* end else */
- } /* end for */
+ /* Check if we should delete this node or not */
+ if(delete_node) {
+ /* Decrement the number of IDs in the type */
+ (type_ptr->id_count)--;
+
+ /* Remove the node from the list */
+ if(NULL == H5SL_remove(type_ptr->ids, &cur->id))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, FAIL, "can't remove ID node from skip list")
+
+ /* Free the node */
+ cur = H5FL_FREE(H5I_id_info_t, cur);
+ } /* end if */
} /* end for */
/* Also free any ID structures being retained for potential re-use */
- while(type_ptr->next_id_ptr) {
- H5I_id_info_t *tmp_id_ptr; /* temp ptr to next atom */
-
- tmp_id_ptr = type_ptr->next_id_ptr->next;
- (void)H5FL_FREE(H5I_id_info_t, type_ptr->next_id_ptr);
- type_ptr->next_id_ptr = tmp_id_ptr;
- } /* end while */
- type_ptr->free_count = 0;
+ if(type_ptr->avail_count > 0) {
+ if(H5SL_free(type_ptr->avail_ids, H5I__free_cb, NULL) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREMOVE, FAIL, "can't release available ID nodes")
+ type_ptr->avail_count = 0;
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -711,7 +674,7 @@ done:
* regardless of 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_destroy_type.
+ * interface to H5I__destroy_type.
*
* Return: Zero on success/Negative on failure
*
@@ -731,7 +694,7 @@ H5Idestroy_type(H5I_type_t type)
if(H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
- ret_value = H5I_destroy_type(type);
+ ret_value = H5I__destroy_type(type);
done:
FUNC_LEAVE_API(ret_value)
@@ -739,7 +702,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_destroy_type
+ * Function: H5I__destroy_type
*
* Purpose: Destroys a type along with all atoms in that type
* regardless of their reference counts. Destroying IDs
@@ -753,19 +716,19 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5I_destroy_type(H5I_type_t type)
+static herr_t
+H5I__destroy_type(H5I_type_t type)
{
H5I_id_type_t *type_ptr; /* ptr to the atomic type */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(type_ptr == NULL || type_ptr->count <= 0)
+ if(type_ptr == NULL || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Close/clear/destroy all IDs for this type */
@@ -777,14 +740,20 @@ H5I_destroy_type(H5I_type_t type)
if(type_ptr->cls->flags & H5I_CLASS_IS_APPLICATION)
type_ptr->cls = H5FL_FREE(H5I_class_t, (void *)type_ptr->cls);
- type_ptr->id_list = H5MM_xfree(type_ptr->id_list);
+ if(H5SL_close(type_ptr->avail_ids) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "can't close skip list")
+ type_ptr->avail_ids = NULL;
+
+ if(H5SL_close(type_ptr->ids) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "can't close skip list")
+ type_ptr->ids = NULL;
type_ptr = H5FL_FREE(H5I_id_type_t, type_ptr);
H5I_id_type_list_g[type] = NULL;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_destroy_type() */
+} /* end H5I__destroy_type() */
/*-------------------------------------------------------------------------
@@ -819,6 +788,47 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5I__wrapped_cb
+ *
+ * Purpose: Callback for searching for next free ID, when IDs have wrapped
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, October 3, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5I__wrapped_cb(void *_item, void UNUSED *_key, void *_udata)
+{
+ H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */
+ H5I_wrap_ud_t *udata = (H5I_wrap_ud_t *)_udata; /* Pointer to user data */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity check */
+ HDassert(item);
+ HDassert(udata);
+
+ /* Break out if we see a free ID */
+ if(udata->nextid != item->id) {
+ /* Sanity check */
+ HDassert(item->id > udata->nextid);
+
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+ else
+ /* Increment to expect the next ID */
+ udata->nextid++;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I__wrapped_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5I_register
*
* Purpose: Registers an OBJECT in a TYPE and returns an ID for it.
@@ -834,13 +844,6 @@ done:
*
* Programmer: Unknown
*
- * Modifications:
- *
- * Neil Fortner, 7 Aug 2008
- * Added app_ref parameter and support for the app_count field, to
- * distiguish between reference count from the library and from the
- * application.
- *
*-------------------------------------------------------------------------
*/
hid_t
@@ -848,10 +851,6 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
{
H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the new ID information */
- unsigned hash_loc; /*new item's hash table location*/
- hid_t next_id; /*next ID to check */
- H5I_id_info_t *curr_id; /*ptr to the current atom */
- unsigned i; /*counter */
hid_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -860,19 +859,17 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(NULL == type_ptr || type_ptr->count <= 0)
+ if(NULL == type_ptr || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* If there is an available ID structure, use it. */
- if(type_ptr->next_id_ptr) {
+ if(type_ptr->avail_count > 0) {
/* Use existing available ID struct */
- id_ptr = type_ptr->next_id_ptr;
+ if(NULL == (id_ptr = (H5I_id_info_t *)H5SL_remove_first(type_ptr->avail_ids)))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREMOVE, FAIL, "can't remove ID from available ID list")
- /* Remove struct from list of available ones */
- type_ptr->next_id_ptr = type_ptr->next_id_ptr->next;
-
/* Decrease count of available ID structures */
- type_ptr->free_count--;
+ type_ptr->avail_count--;
} /* end if */
/* If no available ID structure, then create a new id for use, and
* allocate a new struct to house it. */
@@ -892,63 +889,44 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
id_ptr->count = 1; /*initial reference count*/
id_ptr->app_count = !!app_ref;
id_ptr->obj_ptr = object;
- id_ptr->next = NULL;
-
- /* hash bucket already full, prepend to front of chain */
- hash_loc = id_ptr->id % (unsigned)type_ptr->cls->hash_size;
- if(type_ptr->id_list[hash_loc] != NULL)
- id_ptr->next = type_ptr->id_list[hash_loc];
/* Insert into the type */
- type_ptr->id_list[hash_loc] = id_ptr;
- type_ptr->ids++;
+ if(H5SL_insert(type_ptr->ids, id_ptr, &id_ptr->id) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, FAIL, "can't insert ID node into skip list")
+ type_ptr->id_count++;
/*
* This next section of code checks for the 'nextid' getting too large and
* wrapping around, thus necessitating checking for duplicate IDs being
* handed out.
*/
- if(type_ptr->nextid > (unsigned)ID_MASK) {
- type_ptr->wrapped = 1;
- type_ptr->nextid = type_ptr->cls->reserved;
- } /* end if */
+ if(type_ptr->nextid > (hid_t)ID_MASK)
+ type_ptr->wrapped = TRUE;
/*
* If we've wrapped around then we need to check for duplicate id's being
* handed out.
*/
if(type_ptr->wrapped) {
- /*
- * Make sure we check all available ID's. If we're about at the end
- * of the range then wrap around and check the beginning values. If
- * we check all possible values and didn't find any free ones *then*
- * we can fail.
- */
- for(i = type_ptr->cls->reserved; i < ID_MASK; i++) {
- /* Handle end of range by wrapping to beginning */
- if(type_ptr->nextid > (unsigned)ID_MASK)
- type_ptr->nextid = type_ptr->cls->reserved;
-
- /* new ID to check for */
- next_id = H5I_MAKE(type, type_ptr->nextid);
- hash_loc = (unsigned)H5I_LOC(type_ptr->nextid, type_ptr->cls->hash_size);
- curr_id = type_ptr->id_list[hash_loc];
- if(curr_id == NULL)
- break; /* Ha! this is not likely... */
-
- while(curr_id) {
- if(curr_id->id == next_id)
- break;
- curr_id = curr_id->next;
- } /* end while */
- if(!curr_id)
- break; /* must not have found a match */
- type_ptr->nextid++;
- } /* end for */
-
- if(i >= (unsigned)ID_MASK)
- /* All the IDs are gone! */
+ H5I_wrap_ud_t udata; /* User data for iteration */
+ herr_t iter_status; /* Iteration status */
+
+ /* Set up user data for iteration */
+ udata.nextid = (hid_t)type_ptr->cls->reserved;
+
+ /* Iterate over all the ID nodes, looking for a gap in the ID sequence */
+ if((iter_status = H5SL_iterate(type_ptr->ids, H5I__wrapped_cb, &udata)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADITER, FAIL, "ID iteration failed")
+
+ /* If we didn't break out of the iteration and we're at the max. ID, we've used all the IDs */
+ if(0 == iter_status && udata.nextid >= ID_MASK)
HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type")
+
+ /* Sanity check */
+ HDassert(udata.nextid < ID_MASK);
+
+ /* Retain the next ID for the class */
+ type_ptr->nextid = udata.nextid;
} /* end if */
/* Set return value */
@@ -982,7 +960,7 @@ H5I_subst(hid_t id, const void *new_object)
FUNC_ENTER_NOAPI(NULL)
/* General lookup of the ID */
- if(NULL == (id_ptr = H5I_find_id(id)))
+ if(NULL == (id_ptr = H5I__find_id(id)))
HGOTO_ERROR(H5E_ATOM, H5E_NOTFOUND, NULL, "can't get ID ref count")
/* Get the old object pointer to return */
@@ -1019,7 +997,7 @@ H5I_object(hid_t id)
FUNC_ENTER_NOAPI(NULL)
/* General lookup of the ID */
- if(NULL != (id_ptr = H5I_find_id(id))) {
+ if(NULL != (id_ptr = H5I__find_id(id))) {
/* Get the object pointer to return */
/* (Casting away const OK -QAK) */
ret_value = (void *)id_ptr->obj_ptr;
@@ -1093,7 +1071,7 @@ H5I_object_verify(hid_t id, H5I_type_t id_type)
HDassert(id_type >= 1 && id_type < H5I_next_type);
/* Verify that the type of the ID is correct & lookup the ID */
- if(id_type == H5I_TYPE(id) && NULL != (id_ptr = H5I_find_id(id))) {
+ if(id_type == H5I_TYPE(id) && NULL != (id_ptr = H5I__find_id(id))) {
/* Get the object pointer to return */
/* (Casting away const OK -QAK) */
ret_value = (void *)id_ptr->obj_ptr;
@@ -1175,7 +1153,7 @@ done:
*
* Purpose: Removes the specified ID from its type, first checking that the
* type of the ID and the type type are the same. Public interface to
- * H5I_remove_verify.
+ * H5I__remove_verify.
*
* Return: Success: A pointer to the object that was removed, the
* same pointer which would have been found by
@@ -1198,7 +1176,7 @@ H5Iremove_verify(hid_t id, H5I_type_t id_type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
/* Remove the id */
- ret_value = H5I_remove_verify(id, id_type);
+ ret_value = H5I__remove_verify(id, id_type);
done:
FUNC_LEAVE_API(ret_value)
@@ -1206,7 +1184,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_remove_verify
+ * Function: H5I__remove_verify
*
* Purpose: Removes the specified ID from its type, first checking that
* the ID's type is the same as the ID type supplied as an argument
@@ -1222,11 +1200,11 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5I_remove_verify(hid_t id, H5I_type_t id_type)
+H5I__remove_verify(hid_t id, H5I_type_t id_type)
{
void * ret_value = NULL; /*return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_STATIC_NOERR
/* Argument checking will be performed by H5I_remove() */
@@ -1234,10 +1212,72 @@ H5I_remove_verify(hid_t id, H5I_type_t id_type)
if(id_type == H5I_TYPE(id))
ret_value = H5I_remove(id);
-done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_remove_verify() */
+} /* end H5I__remove_verify() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I__remove_common
+ *
+ * Purpose: Common code to remove a specified ID from its type.
+ *
+ * Return: Success: A pointer to the object that was removed, the
+ * same pointer which would have been found by
+ * calling H5I_object().
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * October 3, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5I__remove_common(H5I_id_type_t *type_ptr, hid_t id)
+{
+ H5I_id_info_t *curr_id; /*ptr to the current atom */
+ void * ret_value; /*return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(type_ptr);
+
+ /* Get the ID node for the 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")
+ /* (Casting away const OK -QAK) */
+ ret_value = (void *)curr_id->obj_ptr;
+
+ /* If there's room, and we can save IDs of this type, then
+ save the struct (and its ID) for future re-use */
+ if((type_ptr->cls->flags & H5I_CLASS_REUSE_IDS)
+ && (type_ptr->avail_count < MAX_FREE_ID_STRUCTS)) {
+ if(H5SL_insert(type_ptr->avail_ids, curr_id, &curr_id->id) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, NULL, "can't insert available ID node into skip list")
+ type_ptr->avail_count++;
+ } /* end if */
+ /* Otherwise, just toss it. */
+ else
+ curr_id = H5FL_FREE(H5I_id_info_t, curr_id);
+
+ /* Decrement the number of IDs in the type */
+ (type_ptr->id_count)--;
+
+ /* If there are no more IDs of this type, then we can free all available
+ ID strutures, and reset starting typeid and wrapped status. */
+ if(0 == type_ptr->id_count) {
+ if(H5SL_free(type_ptr->avail_ids, H5I__free_cb, NULL) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREMOVE, NULL, "can't release available ID nodes")
+ type_ptr->avail_count = 0;
+
+ type_ptr->nextid = (hid_t)type_ptr->cls->reserved;
+ type_ptr->wrapped = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I__remove_common() */
/*-------------------------------------------------------------------------
@@ -1258,12 +1298,8 @@ void *
H5I_remove(hid_t id)
{
H5I_id_type_t *type_ptr; /*ptr to the atomic type */
- H5I_id_info_t *curr_id; /*ptr to the current atom */
- H5I_id_info_t *last_id; /*ptr to the last atom */
- H5I_id_info_t *tmp_id_ptr; /*temp ptr to next atom */
H5I_type_t type; /*atom's atomic type */
- unsigned hash_loc; /*atom's hash table location */
- void * ret_value = NULL; /*return value */
+ void * ret_value; /*return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1272,65 +1308,12 @@ H5I_remove(hid_t id)
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(type_ptr == NULL || type_ptr->count <= 0)
+ if(type_ptr == NULL || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
- /* Get the bucket in which the ID is located */
- hash_loc = (unsigned)H5I_LOC(id, type_ptr->cls->hash_size);
- curr_id = type_ptr->id_list[hash_loc];
- if(NULL == curr_id)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID")
-
- last_id = NULL;
- while(curr_id != NULL) {
- if(curr_id->id == id)
- break;
- last_id = curr_id;
- curr_id = curr_id->next;
- } /* end while */
-
- if(curr_id != NULL) {
- if(last_id == NULL) {
- /* ID is the first in the chain */
- type_ptr->id_list[hash_loc] = curr_id->next;
- } else {
- last_id->next = curr_id->next;
- }
- /* (Casting away const OK -QAK) */
- ret_value = (void *)curr_id->obj_ptr;
-
- /* If there's room, and we can save IDs of this type, then
- save the struct (and its ID) for future re-use */
- if((type_ptr->reuse_ids)&&(type_ptr->free_count < MAX_FREE_ID_STRUCTS)) {
- curr_id->next = type_ptr->next_id_ptr;
- type_ptr->next_id_ptr = curr_id;
- type_ptr->free_count++;
- } /* end if */
- /* Otherwise, just toss it. */
- else
- curr_id = H5FL_FREE(H5I_id_info_t, curr_id);
- } /* end if */
- else {
- /* couldn't find the ID in the proper place */
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID")
- }
-
- /* Decrement the number of IDs in the type */
- (type_ptr->ids)--;
-
- /* If there are no more IDs of this type, then we can free all available
- ID strutures, and reset starting typeid and wrapped status. */
- if(type_ptr->ids == 0) {
- while(type_ptr->next_id_ptr) {
- tmp_id_ptr = type_ptr->next_id_ptr->next;
- (void)H5FL_FREE(H5I_id_info_t, type_ptr->next_id_ptr);
- type_ptr->next_id_ptr = tmp_id_ptr;
- } /* end while */
- type_ptr->free_count = 0;
-
- type_ptr->nextid = type_ptr->cls->reserved;
- type_ptr->wrapped = FALSE;
- } /* end if */
+ /* Remove the node from the type */
+ if(NULL == (ret_value = H5I__remove_common(type_ptr, id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, NULL, "can't remove ID node")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1408,11 +1391,11 @@ H5I_dec_ref(hid_t id)
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(NULL == type_ptr || type_ptr->count <= 0)
+ if(NULL == type_ptr || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
/* General lookup of the ID */
- if(NULL == (id_ptr = H5I_find_id(id)))
+ if(NULL == (id_ptr = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/*
@@ -1433,7 +1416,9 @@ H5I_dec_ref(hid_t id)
if(1 == id_ptr->count) {
/* (Casting away const OK -QAK) */
if(!type_ptr->cls->free_func || (type_ptr->cls->free_func)((void *)id_ptr->obj_ptr) >= 0) {
- H5I_remove(id);
+ /* Remove the node from the type */
+ if(NULL == H5I__remove_common(type_ptr, id))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, FAIL, "can't remove ID node")
ret_value = 0;
} /* end if */
else
@@ -1481,7 +1466,7 @@ H5I_dec_app_ref(hid_t id)
/* Check if the ID still exists */
if(ret_value > 0) {
/* General lookup of the ID */
- if(NULL == (id_ptr = H5I_find_id(id)))
+ if(NULL == (id_ptr = H5I__find_id(id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/* Adjust app_ref */
@@ -1587,13 +1572,6 @@ done:
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- *
- * Neil Fortner, 7 Aug 2008
- * Added app_ref parameter and support for the app_count field, to
- * distiguish between reference count from the library and from the
- * application.
- *
*-------------------------------------------------------------------------
*/
int
@@ -1614,11 +1592,11 @@ H5I_inc_ref(hid_t id, hbool_t app_ref)
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(!type_ptr || type_ptr->count <= 0)
+ if(!type_ptr || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* General lookup of the ID */
- if(NULL == (id_ptr = H5I_find_id(id)))
+ if(NULL == (id_ptr = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/* Adjust reference counts */
@@ -1679,13 +1657,6 @@ done:
* Programmer: Quincey Koziol
* Saturday, Decemeber 6, 2003
*
- * Modifications:
- *
- * Neil Fortner, 7 Aug 2008
- * Added app_ref parameter and support for the app_count field, to
- * distiguish between reference count from the library and from the
- * application.
- *
*-------------------------------------------------------------------------
*/
int
@@ -1706,11 +1677,11 @@ H5I_get_ref(hid_t id, hbool_t app_ref)
if(type <= H5I_BADID || type >= H5I_next_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(!type_ptr || type_ptr->count <= 0)
+ if(!type_ptr || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* General lookup of the ID */
- if(NULL == (id_ptr = H5I_find_id(id)))
+ if(NULL == (id_ptr = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/* Set return value */
@@ -1751,7 +1722,7 @@ H5Iinc_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
/* Do actual increment operation */
- if((ret_value = H5I_inc_type_ref(type)) < 0)
+ if((ret_value = H5I__inc_type_ref(type)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID type ref count")
done:
@@ -1760,7 +1731,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_inc_type_ref
+ * Function: H5I__inc_type_ref
*
* Purpose: Increment the reference count for an ID type.
*
@@ -1773,13 +1744,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-int
-H5I_inc_type_ref(H5I_type_t type)
+static int
+H5I__inc_type_ref(H5I_type_t type)
{
H5I_id_type_t *type_ptr; /* ptr to the type */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(type > 0 && type < H5I_next_type);
@@ -1790,11 +1761,11 @@ H5I_inc_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
- ret_value = (int)(++(type_ptr->count));
+ ret_value = (int)(++(type_ptr->init_count));
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_inc_type_ref() */
+} /* end H5I__inc_type_ref() */
/*-------------------------------------------------------------------------
@@ -1869,7 +1840,7 @@ H5I_dec_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(type_ptr == NULL || type_ptr->count <= 0)
+ if(type_ptr == NULL || type_ptr->init_count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/*
@@ -1878,13 +1849,13 @@ H5I_dec_type_ref(H5I_type_t type)
* free all memory it used. The free function is invoked for each atom
* being freed.
*/
- if(1 == type_ptr->count) {
- H5I_destroy_type(type);
+ if(1 == type_ptr->init_count) {
+ H5I__destroy_type(type);
ret_value = 0;
} /* end if */
else {
- --(type_ptr->count);
- ret_value = (herr_t)type_ptr->count;
+ --(type_ptr->init_count);
+ ret_value = (herr_t)type_ptr->init_count;
} /* end else */
done:
@@ -1922,7 +1893,7 @@ H5Iget_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
/* Do actual retrieve operation */
- if((ret_value = H5I_get_type_ref(type)) < 0)
+ if((ret_value = H5I__get_type_ref(type)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID type ref count")
done:
@@ -1931,7 +1902,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_get_type_ref
+ * Function: H5I__get_type_ref
*
* Purpose: Retrieve the reference count for an ID type.
*
@@ -1945,13 +1916,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-int
-H5I_get_type_ref(H5I_type_t type)
+static int
+H5I__get_type_ref(H5I_type_t type)
{
H5I_id_type_t *type_ptr; /*ptr to the type */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(type >= 0);
@@ -1962,11 +1933,11 @@ H5I_get_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
- ret_value = (int)type_ptr->count;
+ ret_value = (int)type_ptr->init_count;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_get_type_ref() */
+} /* end H5I__get_type_ref() */
/*-------------------------------------------------------------------------
@@ -1994,7 +1965,7 @@ H5Iis_valid(hid_t id)
H5TRACE1("t", "i", id);
/* Find the ID */
- if (NULL == (id_ptr = H5I_find_id(id)))
+ if (NULL == (id_ptr = H5I__find_id(id)))
ret_value = FALSE;
/* Check if the found id is an internal id */
@@ -2007,7 +1978,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_search_cb
+ * Function: H5I__search_cb
*
* Purpose: Callback routine for H5Isearch, when it calls H5I_iterate.
* Calls "user" callback search function, and then sets return
@@ -2024,19 +1995,19 @@ done:
*-------------------------------------------------------------------------
*/
static int
-H5I_search_cb(void *obj, hid_t id, void *_udata)
+H5I__search_cb(void *obj, hid_t id, void *_udata)
{
H5I_search_ud_t *udata = (H5I_search_ud_t *)_udata; /* User data for callback */
int ret_value; /* Callback return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC_NOERR
ret_value = (*udata->app_cb)(obj, id, udata->app_key);
if(ret_value > 0)
udata->ret_obj = obj;
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_search_cb() */
+} /* end H5I__search_cb() */
/*-------------------------------------------------------------------------
@@ -2083,7 +2054,7 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
/* Note that H5I_iterate returns an error code. We ignore it
* here, as we can't do anything with it without revising the API.
*/
- H5I_iterate(type, H5I_search_cb, &udata, TRUE);
+ (void)H5I_iterate(type, H5I__search_cb, &udata, TRUE);
/* Set return value */
ret_value = udata.ret_obj;
@@ -2094,6 +2065,46 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5I__iterate_cb
+ *
+ * Purpose: Callback routine for H5I_iterate, invokes "user" callback
+ * function, and then sets return value, based on the result of
+ * that callback.
+ *
+ * Return: Success: Non-negative on success
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, October 3, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5I__iterate_cb(void *_item, void UNUSED *_key, void *_udata)
+{
+ H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */
+ H5I_iterate_ud_t *udata = (H5I_iterate_ud_t *)_udata; /* User data for callback */
+ int ret_value = H5_ITER_CONT; /* Callback return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Don't make callback if app_ref is set and the appl. ref count is 0 */
+ if((!udata->app_ref) || (item->app_count > 0)) {
+ herr_t cb_ret_val;
+
+ /* (Casting away const OK) */
+ cb_ret_val = (*udata->user_func)((void *)item->obj_ptr, item->id, udata->user_udata);
+ if(cb_ret_val > 0)
+ 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 */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I__iterate_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5I_iterate
*
* Purpose: Apply function FUNC to each member of type TYPE (with
@@ -2135,33 +2146,19 @@ H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_re
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- /* Only iterate through hash table if it is initialized and there are IDs in group */
- if(type_ptr && type_ptr->count > 0 && type_ptr->ids > 0) {
- unsigned u; /* Counter */
-
- /* Start at the beginning of the array */
- for(u = 0; u < type_ptr->cls->hash_size; u++) {
- H5I_id_info_t *id_ptr; /* Ptr to the new ID */
-
- id_ptr = type_ptr->id_list[u];
- while(id_ptr) {
- H5I_id_info_t *next_id; /* Ptr to the next ID */
-
- /* Protect against ID being deleted in callback */
- next_id = id_ptr->next;
- if((!app_ref) || (id_ptr->app_count > 0)) {
- herr_t cb_ret_val; /* Callback return value */
-
- /* (Casting away const OK) */
- cb_ret_val = (*func)((void *)id_ptr->obj_ptr, id_ptr->id, udata);
- if(cb_ret_val > 0)
- HGOTO_DONE(SUCCEED) /* terminate iteration early */
- else if(cb_ret_val < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "func failed")
- } /* end if */
- id_ptr = next_id;
- } /* end while */
- } /* end for */
+ /* Only iterate through ID list if it is initialized and there are IDs in type */
+ if(type_ptr && type_ptr->init_count > 0 && type_ptr->id_count > 0) {
+ H5I_iterate_ud_t iter_udata; /* User data for iteration callback */
+ herr_t iter_status; /* Iteration status */
+
+ /* Set up iterator user data */
+ iter_udata.user_func = func;
+ iter_udata.user_udata = udata;
+ iter_udata.app_ref = app_ref;
+
+ /* Iterate over IDs */
+ if((iter_status = H5SL_iterate(type_ptr->ids, H5I__iterate_cb, &iter_udata)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADITER, FAIL, "iteration failed")
} /* end if */
done:
@@ -2170,7 +2167,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_find_id
+ * Function: H5I__find_id
*
* Purpose: Given an object ID find the info struct that describes the
* object.
@@ -2184,16 +2181,13 @@ done:
*-------------------------------------------------------------------------
*/
static H5I_id_info_t *
-H5I_find_id(hid_t id)
+H5I__find_id(hid_t id)
{
H5I_id_type_t *type_ptr; /*ptr to the type */
- H5I_id_info_t *last_id; /*ptr to the last ID */
- H5I_id_info_t *id_ptr; /*ptr to the new ID */
H5I_type_t type; /*ID's type */
- unsigned hash_loc; /*bucket pointer */
H5I_id_info_t *ret_value; /*return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC_NOERR
/* Check arguments */
type = H5I_TYPE(id);
@@ -2201,35 +2195,15 @@ H5I_find_id(hid_t id)
HGOTO_DONE(NULL);
type_ptr = H5I_id_type_list_g[type];
- if (!type_ptr || type_ptr->count <= 0)
+ if (!type_ptr || type_ptr->init_count <= 0)
HGOTO_DONE(NULL);
- /* Get the bucket in which the ID is located */
- hash_loc = (unsigned)H5I_LOC(id, type_ptr->cls->hash_size);
- id_ptr = type_ptr->id_list[hash_loc];
-
- /* Scan the bucket's linked list for a match */
- last_id = NULL;
- while(id_ptr) {
- if(id_ptr->id == id) {
- /* If we found an object, move it to the front of the list, if it isn't there already */
- if(last_id != NULL) {
- last_id->next = id_ptr->next;
- id_ptr->next = type_ptr->id_list[hash_loc];
- type_ptr->id_list[hash_loc] = id_ptr;
- } /* end if */
- break;
- } /* end if */
- last_id = id_ptr;
- id_ptr = id_ptr->next;
- } /* end while */
-
- /* Set the return value */
- ret_value = id_ptr;
+ /* Locate the ID node for the ID */
+ ret_value = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_find_id() */
+} /* end H5I__find_id() */
/*-------------------------------------------------------------------------
@@ -2360,9 +2334,66 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I_get_file_id() */
+#ifdef H5I_DEBUG_OUTPUT
/*-------------------------------------------------------------------------
- * Function: H5I_debug
+ * Function: H5I__debug_cb
+ *
+ * Purpose: Dump the contents of an ID to stderr for debugging.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Friday, February 19, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5I__debug_cb(void *_item, void UNUSED *_key, void *_udata)
+{
+ H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */
+ H5I_type_t type = *(H5I_type_t *)_udata; /* User data */
+ H5G_name_t *path = NULL;
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ fprintf(stderr, " id = %lu\n", (unsigned long)(item->id));
+ fprintf(stderr, " count = %u\n", item->count);
+ fprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(item->obj_ptr));
+
+ /* Get the group location, so we get get the name */
+ switch(type) {
+ case H5I_GROUP:
+ path = H5G_nameof((H5G_t*)item->obj_ptr);
+ break;
+
+ case H5I_DATASET:
+ path = H5D_nameof((H5D_t*)item->obj_ptr);
+ break;
+
+ case H5I_DATATYPE:
+ path = H5T_nameof((H5T_t*)item->obj_ptr);
+ break;
+
+ default:
+ break; /* Other types of IDs are not stored in files */
+ } /* end switch*/
+
+ if(path) {
+ if(path->user_path_r)
+ fprintf(stderr, " user_path = %s\n", H5RS_get_str(path->user_path_r));
+ if(path->full_path_r)
+ fprintf(stderr, " full_path = %s\n", H5RS_get_str(path->full_path_r));
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5I__debug_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I__debug
*
* Purpose: Dump the contents of a type to stderr for debugging.
*
@@ -2374,74 +2405,28 @@ done:
*
*-------------------------------------------------------------------------
*/
-#ifdef H5I_DEBUG_OUTPUT
static herr_t
-H5I_debug(H5I_type_t type)
+H5I__debug(H5I_type_t type)
{
H5I_id_type_t *type_ptr;
- H5I_id_info_t *cur;
- H5G_name_t *path;
- int is, js;
- unsigned int iu;
- herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC_NOERR
fprintf(stderr, "Dumping ID type %d\n", (int)type);
type_ptr = H5I_id_type_list_g[type];
/* Header */
- fprintf(stderr, " count = %u\n", type_ptr->count);
- fprintf(stderr, " reserved = %u\n", type_ptr->cls->reserved);
- fprintf(stderr, " wrapped = %u\n", type_ptr->wrapped);
- fprintf(stderr, " hash_size = %lu\n", (unsigned long)type_ptr->cls->hash_size);
- fprintf(stderr, " ids = %u\n", type_ptr->ids);
- fprintf(stderr, " nextid = %u\n", type_ptr->nextid);
-
- /* Cache */
- fprintf(stderr, " Cache:\n");
- for (is=0; is<ID_CACHE_SIZE; is++) {
- if (H5I_cache_g[is] && H5I_TYPE(H5I_cache_g[is]->id)==type) {
- fprintf(stderr, " Entry-%d, ID=%lu\n",
- is, (unsigned long)(H5I_cache_g[is]->id));
- }
- }
+ fprintf(stderr, " init_count = %u\n", type_ptr->init_count);
+ fprintf(stderr, " reserved = %u\n", type_ptr->cls->reserved);
+ fprintf(stderr, " wrapped = %u\n", type_ptr->wrapped);
+ fprintf(stderr, " id_count = %u\n", type_ptr->id_count);
+ fprintf(stderr, " nextid = %u\n", type_ptr->nextid);
/* List */
fprintf(stderr, " List:\n");
- for (iu=0; iu<type_ptr->hash_size; iu++) {
- for (js=0, cur=type_ptr->id_list[iu]; cur; cur=cur->next, js++) {
- fprintf(stderr, " #%u.%d\n", iu, js);
- fprintf(stderr, " id = %lu\n", (unsigned long)(cur->id));
- fprintf(stderr, " count = %u\n", cur->count);
- fprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(cur->obj_ptr));
-
- /* Get the group location, so we get get the name */
- switch(type) {
- case H5I_GROUP:
- path = H5G_nameof((H5G_t*)cur->obj_ptr);
- break;
- case H5I_DATASET:
- path = H5D_nameof((H5D_t*)cur->obj_ptr);
- break;
- case H5I_DATATYPE:
- path = H5T_nameof((H5T_t*)cur->obj_ptr);
- break;
- default:
- continue; /* Other types of IDs are not stored in files */
- } /* end switch*/
-
- if(path) {
- if(path->user_path_r)
- fprintf(stderr, " user_path = %s\n", H5RS_get_str(path->user_path_r));
- if(ent->canon_path_r)
- fprintf(stderr, " canon_path = %s\n", H5RS_get_str(path->canon_path_r));
- } /* end if */
- } /* end for */
- } /* end for */
+ H5SL_iterate(type_ptr->ids, H5I__debug_cb, &type);
-done:
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5I_debug() */
+} /* end H5I__debug() */
#endif /* H5I_DEBUG_OUTPUT */
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index ff1463d..88c2432 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -37,6 +37,7 @@
/* Flags for ID class */
#define H5I_CLASS_IS_APPLICATION 0x01
+#define H5I_CLASS_REUSE_IDS 0x02
/****************************/
@@ -46,7 +47,6 @@
typedef struct H5I_class_t {
H5I_type_t type_id; /* Class ID for the type */
unsigned flags; /* Class behavior flags */
- size_t hash_size; /* Minimum hash table size for the type */
unsigned reserved; /* Number of reserved IDs for this type */
/* [A specific number of type entries may be
* reserved to enable "constant" values to be
@@ -69,7 +69,6 @@ typedef struct H5I_class_t {
H5_DLL herr_t H5I_register_type(const H5I_class_t *cls);
H5_DLL int H5I_nmembers(H5I_type_t type);
H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref);
-H5_DLL int H5I_destroy_type(H5I_type_t type);
H5_DLL hid_t H5I_register(H5I_type_t type, const void *object, hbool_t app_ref);
H5_DLL void *H5I_subst(hid_t id, const void *new_object);
H5_DLL void *H5I_object(hid_t id);
@@ -77,16 +76,13 @@ H5_DLL void *H5I_object_verify(hid_t id, H5I_type_t id_type);
H5_DLL H5I_type_t H5I_get_type(hid_t id);
H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref);
H5_DLL void *H5I_remove(hid_t id);
-H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
H5_DLL herr_t H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref);
H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_dec_ref(hid_t id);
H5_DLL int H5I_dec_app_ref(hid_t id);
H5_DLL int H5I_dec_app_ref_always_close(hid_t id);
-H5_DLL int H5I_inc_type_ref(H5I_type_t type);
H5_DLL herr_t H5I_dec_type_ref(H5I_type_t type);
-H5_DLL int H5I_get_type_ref(H5I_type_t type);
#endif /* _H5Iprivate_H */
diff --git a/src/H5Pint.c b/src/H5Pint.c
index b15f039..19b22c8 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -268,8 +268,7 @@ H5FL_DEFINE_STATIC(H5P_genplist_t);
/* Generic Property Class ID class */
static const H5I_class_t H5I_GENPROPCLS_CLS[1] = {{
H5I_GENPROP_CLS, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5P_close_class /* Callback routine for closing objects of this class */
}};
@@ -278,7 +277,6 @@ static const H5I_class_t H5I_GENPROPCLS_CLS[1] = {{
static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{
H5I_GENPROP_LST, /* ID class value */
0, /* Class flags */
- 128, /* Minimum hash size for class */
0, /* # of reserved IDs for class */
(H5I_free_t)H5P_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5R.c b/src/H5R.c
index 3d14321..c42c6e1 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -78,8 +78,7 @@ static ssize_t H5R_get_name(H5F_t *file, hid_t lapl_id, hid_t dxpl_id, hid_t id,
/* Reference ID class */
static const H5I_class_t H5I_REFERENCE_CLS[1] = {{
H5I_REFERENCE, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
0, /* # of reserved IDs for class */
NULL /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5S.c b/src/H5S.c
index 2eebba4..1ba0248 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -89,8 +89,7 @@ H5FL_ARR_DEFINE(hsize_t,H5S_MAX_RANK);
/* Dataspace ID class */
static const H5I_class_t H5I_DATASPACE_CLS[1] = {{
H5I_DATASPACE, /* ID class value */
- 0, /* Class flags */
- 64, /* Minimum hash size for class */
+ H5I_CLASS_REUSE_IDS, /* Class flags */
2, /* # of reserved IDs for class */
(H5I_free_t)H5S_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5SL.c b/src/H5SL.c
index 2e2ad1e..2e72819 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -549,10 +549,12 @@ H5SL_init_interface(void)
/* Allocate space for array of factories */
H5SL_fac_g = (H5FL_fac_head_t **)H5MM_malloc(sizeof(H5FL_fac_head_t *));
+ HDassert(H5SL_fac_g);
H5SL_fac_nalloc_g = 1;
/* Initialize first factory */
H5SL_fac_g[0] = H5FL_fac_init(sizeof(H5SL_node_t *));
+ HDassert(H5SL_fac_g[0]);
H5SL_fac_nused_g = 1;
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -681,6 +683,10 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
H5SL_INSERT(OBJ, slist, prev, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_INSERT(SCALAR, slist, prev, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_INSERT(GENERIC, slist, prev, const void, key, -)
break;
@@ -1110,6 +1116,10 @@ H5SL_remove(H5SL_t *slist, const void *key)
H5SL_REMOVE(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_REMOVE(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_REMOVE(GENERIC, slist, x, const void, key, -)
break;
@@ -1293,6 +1303,10 @@ H5SL_search(H5SL_t *slist, const void *key)
H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_SEARCH(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_SEARCH(GENERIC, slist, x, const void, key, -)
break;
@@ -1382,6 +1396,10 @@ H5SL_less(H5SL_t *slist, const void *key)
H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_SEARCH(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_SEARCH(GENERIC, slist, x, const void, key, -)
break;
@@ -1484,6 +1502,10 @@ H5SL_greater(H5SL_t *slist, const void *key)
H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_SEARCH(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_SEARCH(GENERIC, slist, x, const void, key, -)
break;
@@ -1576,6 +1598,10 @@ H5SL_find(H5SL_t *slist, const void *key)
H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_FIND(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_FIND(GENERIC, slist, x, const void, key, -)
break;
@@ -1665,6 +1691,10 @@ H5SL_below(H5SL_t *slist, const void *key)
H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_FIND(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_FIND(GENERIC, slist, x, const void, key, -)
break;
@@ -1767,6 +1797,10 @@ H5SL_above(H5SL_t *slist, const void *key)
H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_HID:
+ H5SL_FIND(SCALAR, slist, x, const hid_t, key, -)
+ break;
+
case H5SL_TYPE_GENERIC:
H5SL_FIND(GENERIC, slist, x, const void, key, -)
break;
@@ -1994,7 +2028,8 @@ H5SL_item(H5SL_node_t *slist_node)
herr_t
H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data)
{
- H5SL_node_t *node; /* Pointers to skip list nodes */
+ H5SL_node_t *node; /* Pointer to current skip list node */
+ H5SL_node_t *next; /* Pointer to next skip list node */
herr_t ret_value = 0; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -2008,12 +2043,16 @@ H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data)
/* Free skip list nodes */
node = slist->header->forward[0];
while(node != NULL) {
+ /* Protect against the node being deleted by the callback */
+ next = node->forward[0];
+
/* Call the iterator callback */
/* Casting away const OK -QAK */
if((ret_value = (op)(node->item, (void *)node->key, op_data)) != 0)
break;
- node = node->forward[0];
+ /* Advance to next node */
+ node = next;
} /* end while */
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h
index 07ee414..ce2f091 100644
--- a/src/H5SLprivate.h
+++ b/src/H5SLprivate.h
@@ -48,6 +48,7 @@ typedef enum {
H5SL_TYPE_UNSIGNED, /* Skip list keys are 'unsigned's */
H5SL_TYPE_SIZE, /* Skip list keys are 'size_t's */
H5SL_TYPE_OBJ, /* Skip list keys are 'H5_obj_t's */
+ H5SL_TYPE_HID, /* Skip list keys are 'hid_t's */
H5SL_TYPE_GENERIC /* Skip list keys are unknown, comparison callback supplied */
} H5SL_type_t;
diff --git a/src/H5T.c b/src/H5T.c
index d73d270..05dfe2a 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -530,7 +530,6 @@ H5FL_DEFINE_STATIC(H5T_path_t);
static const H5I_class_t H5I_DATATYPE_CLS[1] = {{
H5I_DATATYPE, /* ID class value */
0, /* Class flags */
- 64, /* Minimum hash size for class */
8, /* # of reserved IDs for class */
(H5I_free_t)H5T_close /* Callback routine for closing objects of this class */
}};
diff --git a/src/H5private.h b/src/H5private.h
index f828a46..ac4574f 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -210,10 +210,11 @@
*/
#define eventa(func_name) h5_mpe_eventa
#define eventb(func_name) h5_mpe_eventb
-#define MPE_LOG_VARS \
- static int eventa(FUNC) = -1; \
- static int eventb(FUNC) = -1; \
- const char* p_event_start = "start" FUNC;
+#define MPE_LOG_VARS \
+ static int h5_mpe_eventa = -1; \
+ static int h5_mpe_eventb = -1; \
+ static char p_event_start[128]; \
+ static char p_event_end[128];
/* Hardwire the color to "red", since that's what all the routines are using
* now. In the future, if we want to change that color for a given routine,
@@ -222,15 +223,18 @@
* color information down to the BEGIN_MPE_LOG macro (which should have a new
* BEGIN_MPE_LOG_COLOR variant). -QAK
*/
-#define BEGIN_MPE_LOG \
- if (H5_MPEinit_g){ \
- if (eventa(FUNC) == -1 && eventb(FUNC) == -1) { \
- const char* p_color = "red"; \
- eventa(FUNC)=MPE_Log_get_event_number(); \
- eventb(FUNC)=MPE_Log_get_event_number(); \
- MPE_Describe_state(eventa(FUNC), eventb(FUNC), (char *)FUNC, (char *)p_color); \
- } \
- MPE_Log_event(eventa(FUNC), 0, (char *)p_event_start); \
+#define BEGIN_MPE_LOG \
+ if(H5_MPEinit_g) { \
+ if(h5_mpe_eventa == -1 && h5_mpe_eventb == -1) { \
+ const char *p_color = "red"; \
+ \
+ h5_mpe_eventa = MPE_Log_get_event_number(); \
+ h5_mpe_eventb = MPE_Log_get_event_number(); \
+ HDsnprintf(p_event_start, sizeof(p_event_start) - 1, "start_%s", FUNC); \
+ HDsnprintf(p_event_end, sizeof(p_event_end) - 1, "end_%s", FUNC); \
+ MPE_Describe_state(h5_mpe_eventa, h5_mpe_eventb, (char *)FUNC, (char *)p_color); \
+ } \
+ MPE_Log_event(h5_mpe_eventa, 0, p_event_start); \
}
@@ -240,9 +244,9 @@
*
* Programmer: Long Wang
*/
-#define FINISH_MPE_LOG \
- if (H5_MPEinit_g) { \
- MPE_Log_event(eventb(FUNC), 0, (char *)FUNC); \
+#define FINISH_MPE_LOG \
+ if(H5_MPEinit_g) { \
+ MPE_Log_event(h5_mpe_eventb, 0, p_event_end); \
}
#else /* H5_HAVE_MPE */