summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST12
-rwxr-xr-xconfigure83
-rw-r--r--configure.in10
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5.c6
-rw-r--r--src/H5A.c10
-rw-r--r--src/H5AC.c181
-rw-r--r--src/H5ACprivate.h7
-rw-r--r--src/H5B.c142
-rw-r--r--src/H5Bprivate.h2
-rw-r--r--src/H5D.c1096
-rw-r--r--src/H5Dcontig.c106
-rw-r--r--src/H5Distore.c13
-rw-r--r--src/H5Dprivate.h35
-rw-r--r--src/H5Dseq.c46
-rw-r--r--src/H5E.c2
-rw-r--r--src/H5Epublic.h4
-rw-r--r--src/H5F.c327
-rw-r--r--src/H5FD.c39
-rw-r--r--src/H5FDfamily.c41
-rw-r--r--src/H5FDgass.c8
-rw-r--r--src/H5FDlog.c6
-rw-r--r--src/H5FDlog.h4
-rw-r--r--src/H5FDmpio.c12
-rw-r--r--src/H5FDmpiposix.c6
-rw-r--r--src/H5FDmulti.c24
-rw-r--r--src/H5FDsec2.c2
-rw-r--r--src/H5FDsrb.c7
-rw-r--r--src/H5FDstream.c2
-rw-r--r--src/H5FL.c209
-rw-r--r--src/H5FLprivate.h38
-rw-r--r--src/H5FO.c277
-rw-r--r--src/H5FOprivate.h42
-rw-r--r--src/H5FPclient.c6
-rw-r--r--src/H5Fcontig.c106
-rw-r--r--src/H5Fistore.c13
-rw-r--r--src/H5Fpkg.h15
-rw-r--r--src/H5Fprivate.h46
-rw-r--r--src/H5Fpublic.h24
-rw-r--r--src/H5Fseq.c46
-rw-r--r--src/H5G.c521
-rw-r--r--src/H5Gent.c26
-rw-r--r--src/H5Gnode.c170
-rw-r--r--src/H5Gpkg.h1
-rw-r--r--src/H5Gprivate.h11
-rw-r--r--src/H5Gstab.c76
-rw-r--r--src/H5HG.c28
-rw-r--r--src/H5HL.c76
-rw-r--r--src/H5I.c12
-rw-r--r--src/H5MMprivate.h4
-rw-r--r--src/H5O.c395
-rw-r--r--src/H5Oattr.c11
-rw-r--r--src/H5Odtype.c26
-rw-r--r--src/H5Oefl.c3
-rw-r--r--src/H5Ofill.c121
-rw-r--r--src/H5Ofphdf5.c4
-rw-r--r--src/H5Olayout.c6
-rw-r--r--src/H5Omtime.c208
-rw-r--r--src/H5Opline.c (renamed from src/H5Ocomp.c)7
-rw-r--r--src/H5Oplist.c206
-rw-r--r--src/H5Oprivate.h41
-rw-r--r--src/H5Osdspace.c18
-rw-r--r--src/H5Ostab.c6
-rw-r--r--src/H5P.c1891
-rw-r--r--src/H5Pdcpl.c62
-rw-r--r--src/H5Pfapl.c8
-rw-r--r--src/H5Ppkg.h27
-rw-r--r--src/H5Pprivate.h5
-rw-r--r--src/H5Ppublic.h64
-rw-r--r--src/H5R.c23
-rw-r--r--src/H5RS.c390
-rw-r--r--src/H5RSprivate.h52
-rw-r--r--src/H5S.c149
-rw-r--r--src/H5ST.c795
-rw-r--r--src/H5STprivate.h61
-rw-r--r--src/H5Sall.c4
-rw-r--r--src/H5Shyper.c73
-rw-r--r--src/H5Smpio.c12
-rw-r--r--src/H5Spkg.h3
-rw-r--r--src/H5Spoint.c8
-rw-r--r--src/H5Sprivate.h40
-rw-r--r--src/H5Sselect.c322
-rw-r--r--src/H5T.c159
-rw-r--r--src/H5TB.c192
-rw-r--r--src/H5TBprivate.h11
-rw-r--r--src/H5Tconv.c128
-rw-r--r--src/H5Tprivate.h1
-rw-r--r--src/H5Tpublic.h174
-rw-r--r--src/H5Tvlen.c12
-rw-r--r--src/H5detect.c2
-rw-r--r--src/Makefile.in26
-rw-r--r--test/Makefile.in15
-rw-r--r--test/dsets.c15
-rw-r--r--test/fillval.c2
-rw-r--r--test/gen_new_mtime.c65
-rw-r--r--test/gen_old_mtime.c66
-rw-r--r--test/istore.c3
-rw-r--r--test/mtime.c68
-rw-r--r--test/ntypes.c1
-rw-r--r--test/ohdr.c13
-rw-r--r--test/tattr.c25
-rw-r--r--test/testhdf5.c2
-rw-r--r--test/testhdf5.h2
-rw-r--r--test/tgenprop.c38
-rw-r--r--test/titerate.c14
-rw-r--r--test/tmtimen.h5bin0 -> 1576 bytes
-rw-r--r--test/tmtimeo.h5bin0 -> 1576 bytes
-rw-r--r--test/trefstr.c378
-rw-r--r--test/ttst.c400
-rw-r--r--test/tvlstr.c9
-rw-r--r--tools/h5dump/h5dump.c2
-rw-r--r--tools/h5dump/h5dumpgentest.c2
112 files changed, 7705 insertions, 3143 deletions
diff --git a/MANIFEST b/MANIFEST
index e25c841..80a88f0 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -830,6 +830,8 @@
./src/H5FDstream.h
./src/H5FL.c
./src/H5FLprivate.h
+./src/H5FO.c
+./src/H5FOprivate.h
./src/H5FP.c
./src/H5FPclient.c
./src/H5FPprivate.h
@@ -859,7 +861,6 @@
./src/H5MPprivate.h
./src/H5O.c
./src/H5Oattr.c
-./src/H5Ocomp.c
./src/H5Ocont.c
./src/H5Odtype.c
./src/H5Oefl.c
@@ -869,6 +870,7 @@
./src/H5Omtime.c
./src/H5Oname.c
./src/H5Onull.c
+./src/H5Opline.c
./src/H5Oplist.c
./src/H5Oprivate.h
./src/H5Opublic.h
@@ -886,6 +888,8 @@
./src/H5R.c
./src/H5Rprivate.h
./src/H5Rpublic.h
+./src/H5RS.c
+./src/H5RSprivate.h
./src/H5S.c
./src/H5Sall.c
./src/H5Shyper.c
@@ -896,6 +900,8 @@
./src/H5Sprivate.h
./src/H5Spublic.h
./src/H5Sselect.c
+./src/H5ST.c
+./src/H5STprivate.h
./src/H5T.c
./src/H5Tbit.c
./src/H5Tconv.c
@@ -958,6 +964,8 @@
./test/gen_old_array.c _DO_NOT_DISTRIBUTE_
./test/gen_new_array.c _DO_NOT_DISTRIBUTE_
./test/gen_new_fill.c _DO_NOT_DISTRIBUTE_
+./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_
+./test/gen_new_mtime.c _DO_NOT_DISTRIBUTE_
./test/set_extent.c
./test/srb_append.c
./test/srb_read.c
@@ -978,6 +986,8 @@
./test/titerate.c
./test/tmeta.c
./test/tmisc.c
+./test/tmtimen.h5
+./test/tmtimeo.h5
./test/ttime.c
./test/trefer.c
./test/tselect.c
diff --git a/configure b/configure
index 861fe77..48826df 100755
--- a/configure
+++ b/configure
@@ -7788,6 +7788,83 @@ fi
+for ac_func in difftime gettimeofday
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+char (*f) ();
+
+#ifdef F77_DUMMY_MAIN
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
@@ -28619,8 +28696,7 @@ rm -f conftest.$ac_objext conftest.$ac_ext
-
-for ac_func in difftime fork gethostname getpwuid getrusage
+for ac_func in fork gethostname getpwuid getrusage
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -28699,8 +28775,7 @@ done
-
-for ac_func in gettimeofday BSDgettimeofday longjmp setsysinfo sigaction
+for ac_func in BSDgettimeofday longjmp setsysinfo sigaction
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/configure.in b/configure.in
index 0e1640b..7ed536e 100644
--- a/configure.in
+++ b/configure.in
@@ -468,6 +468,12 @@ dnl
AC_HEADER_STDC
AC_HEADER_TIME
+dnl ----------------------------------------------------------------------
+dnl Check for these two functions before <sys/time.h> is checked for, otherwise
+dnl they are not detected correctly on Solaris [2.6].
+dnl
+AC_CHECK_FUNCS(difftime gettimeofday)
+
dnl Unix
AC_CHECK_HEADERS([sys/resource.h sys/time.h unistd.h sys/ioctl.h sys/stat.h])
AC_CHECK_HEADERS([sys/socket.h sys/types.h])
@@ -1287,8 +1293,8 @@ AC_MSG_RESULT(no))
dnl ----------------------------------------------------------------------
dnl Check for functions.
dnl
-AC_CHECK_FUNCS(difftime fork gethostname getpwuid getrusage)
-AC_CHECK_FUNCS(gettimeofday BSDgettimeofday longjmp setsysinfo sigaction)
+AC_CHECK_FUNCS(fork gethostname getpwuid getrusage)
+AC_CHECK_FUNCS(BSDgettimeofday longjmp setsysinfo sigaction)
AC_CHECK_FUNCS(signal snprintf vsnprintf strdup system waitpid)
dnl ----------------------------------------------------------------------
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 39d2fd9..c548de4 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -236,6 +236,8 @@ Documentation
o Performance
-------------
+ * Improved dataset creation time by about 30% (relative to the 1.4.x
+ branch).
New Features
diff --git a/src/H5.c b/src/H5.c
index 13cda68..742cd77 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -1388,9 +1388,7 @@ H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds)
*
* WARNING: DO NOT CALL ANY HDF5 FUNCTION THAT CALLS FUNC_ENTER(). DOING
* SO MAY CAUSE H5_trace() TO BE INVOKED RECURSIVELY OR MAY
- * CAUSE LIBRARY INITIALIZATIONS THAT ARE NOT DESIRED. DO NOT
- * USE THE H5T_*_* CONSTANTS SINCE THEY CALL H5_open() WHICH
- * INVOKES FUNC_ENTER().
+ * CAUSE LIBRARY INITIALIZATIONS THAT ARE NOT DESIRED.
*
* Return: void
*
@@ -1453,7 +1451,7 @@ H5_trace (double *returning, const char *func, const char *type, ...)
if (H5_debug_g.ttimes) {
H5_timer_begin(&event_time);
} else {
- memset(&event_time, 0, sizeof event_time);
+ HDmemset(&event_time, 0, sizeof event_time);
}
/* Print the first part of the line. This is the indication of the
diff --git a/src/H5A.c b/src/H5A.c
index 8f7f0bb..ab180d2 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -275,7 +275,7 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
H5E_clear ();
/* Create the attribute message and save the attribute index */
- if (H5O_modify(&(attr->ent), H5O_ATTR, H5O_NEW_MESG, 0, attr) < 0)
+ if (H5O_modify(&(attr->ent), H5O_ATTR, H5O_NEW_MESG, 0, 1, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages");
/* Register the new attribute and get an ID for it */
@@ -635,7 +635,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf)
/* Perform data type conversion */
if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf,
- H5P_DEFAULT)<0) {
+ H5P_DATASET_XFER_DEFAULT)<0) {
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL,
"data type conversion failed");
}
@@ -650,7 +650,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf)
/* Modify the attribute data */
attr->data=tconv_buf; /* Set the data pointer temporarily */
- if (H5O_modify(&(attr->ent), H5O_ATTR, idx, 0, attr) < 0)
+ if (H5O_modify(&(attr->ent), H5O_ATTR, idx, 0, 1, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL,
"unable to update attribute header messages");
@@ -787,7 +787,7 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf)
}
/* Perform data type conversion. */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf, H5P_DEFAULT)<0)
+ if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf, H5P_DATASET_XFER_DEFAULT)<0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed");
/* Copy the converted data into the user's buffer */
@@ -1223,7 +1223,7 @@ H5A_rename(H5G_entry_t *ent, const char *old_name, const char *new_name)
found_attr->initialized=TRUE;
/* Modify the attribute message */
- if (H5O_modify(ent, H5O_ATTR, idx, 0, found_attr) < 0)
+ if (H5O_modify(ent, H5O_ATTR, idx, 0, 1, found_attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages");
/* Close the attribute */
diff --git a/src/H5AC.c b/src/H5AC.c
index dfdf6d4..fa4f1cb 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -4,7 +4,7 @@
*
*-------------------------------------------------------------------------
*
- * Created: hdf5cache.c
+ * Created: H5AC.c
* Jul 9 1997
* Robb Matzke <matzke@llnl.gov>
*
@@ -103,7 +103,7 @@ H5AC_init_interface(void)
assert(H5P_CLS_DATASET_XFER_g!=(-1));
/* Get the dataset transfer property list class object */
- if (NULL == (xfer_pclass = H5I_object_verify(H5P_CLS_DATASET_XFER_g, H5I_GENPROP_CLS)))
+ if (NULL == (xfer_pclass = H5I_object(H5P_CLS_DATASET_XFER_g)))
HGOTO_ERROR(H5E_CACHE, H5E_BADATOM, FAIL, "can't get property list class");
/* Create a new dataset transfer property list */
@@ -206,14 +206,14 @@ H5AC_create(H5F_t *f, int size_hint)
assert(NULL == f->shared->cache);
if (size_hint < 1) size_hint = H5AC_NSLOTS;
- if (NULL==(f->shared->cache = cache = H5FL_ALLOC(H5AC_t,1)))
+ if (NULL==(f->shared->cache = cache = H5FL_CALLOC(H5AC_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
cache->nslots = size_hint;
- cache->slot = H5FL_ARR_ALLOC(H5AC_info_ptr_t,cache->nslots,1);
+ cache->slot = H5FL_ARR_CALLOC(H5AC_info_ptr_t,cache->nslots);
if (NULL==cache->slot)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
#ifdef H5AC_DEBUG
- if ((cache->prot = H5FL_ARR_ALLOC(H5AC_prot_t,cache->nslots,1))==NULL)
+ if ((cache->prot = H5FL_ARR_CALLOC(H5AC_prot_t,cache->nslots))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
#endif /* H5AC_DEBUG */
@@ -341,13 +341,13 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
{
unsigned idx;
herr_t status;
- void *thing = NULL;
+ void *thing;
H5AC_flush_func_t flush;
- H5AC_info_t **info = NULL;
- H5AC_t *cache = NULL;
+ H5AC_info_t **info;
+ H5AC_t *cache;
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5AC_find, NULL);
+ FUNC_ENTER_NOAPI(H5AC_find_f, NULL);
assert(f);
assert(f->shared->cache);
@@ -355,6 +355,8 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
assert(type->load);
assert(type->flush);
assert(H5F_addr_defined(addr));
+
+ /* Get local copies of information */
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
info = cache->slot + idx;
@@ -362,18 +364,18 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
/*
* Return right away if the item is in the cache.
*/
- if ((*info) && (*info)->type == type && H5F_addr_eq((*info)->addr, addr)) {
+ if ((*info) && H5F_addr_eq(addr,(*info)->addr)) {
+ /* Sanity check that the object in the cache is the correct type */
+ assert((*info)->type==type);
+
+#ifdef H5AC_DEBUG
cache->diagnostics[type->id].nhits++;
+#endif /* H5AC_DEBUG */
HGOTO_DONE(*info);
}
+#ifdef H5AC_DEBUG
cache->diagnostics[type->id].nmisses++;
-
- /*
- * Fail if the item in the cache is at the correct address but is
- * of the wrong type.
- */
- if ((*info) && (*info)->type && (*info)->type != type && H5F_addr_eq((*info)->addr, addr))
- HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, NULL, "internal error (correct address, wrong type)");
+#endif /* H5AC_DEBUG */
#ifdef H5AC_DEBUG
/*
@@ -403,7 +405,9 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* Free the previous cache entry if there is one.
*/
if (*info) {
+#ifdef H5AC_DEBUG
H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */
+#endif /* H5AC_DEBUG */
flush = (*info)->type->flush;
status = (flush)(f, H5AC_dxpl_id, TRUE, (*info)->addr, (*info));
@@ -416,7 +420,9 @@ H5AC_find_f(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "unable to flush just-loaded object");
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "unable to flush existing cached object");
}
+#ifdef H5AC_DEBUG
cache->diagnostics[type_id].nflushes++;
+#endif /* H5AC_DEBUG */
}
/*
@@ -459,37 +465,29 @@ H5AC_compare(const void *_a, const void *_b)
int a = *((const int *) _a);
int b = *((const int *) _b);
int ret_value=0;
+ H5AC_info_t *slot_a;
+ H5AC_info_t *slot_b;
/* Use FUNC_ENTER_NOINIT here to avoid performance issues */
FUNC_ENTER_NOINIT(H5AC_compare);
assert(current_cache_g);
- if(NULL==current_cache_g->slot[a] || NULL == current_cache_g->slot[b]) {
- if(NULL==current_cache_g->slot[a]) {
- if (NULL == current_cache_g->slot[b]) {
- HGOTO_DONE(0);
- } else
- HGOTO_DONE(-1);
- }
- else {
- HGOTO_DONE(1);
- }
- }
- else if (NULL == current_cache_g->slot[a]->type) {
- if (NULL == current_cache_g->slot[b]->type) {
- HGOTO_DONE(0);
- } else
- HGOTO_DONE(-1);
- } else if (NULL == current_cache_g->slot[b]->type) {
- HGOTO_DONE(1);
- } else if (current_cache_g->slot[a]->addr < current_cache_g->slot[b]->addr) {
- HGOTO_DONE(-1);
- } else if (current_cache_g->slot[a]->addr > current_cache_g->slot[b]->addr) {
- HGOTO_DONE(1);
+ /* Create aliases for slots */
+ slot_a=current_cache_g->slot[a];
+ slot_b=current_cache_g->slot[b];
+
+ assert(slot_a);
+ assert(slot_b);
+ assert(slot_a->type);
+ assert(slot_b->type);
+
+ if (slot_a->addr < slot_b->addr) {
+ ret_value=(-1);
+ } else if (slot_a->addr > slot_b->addr) {
+ ret_value=1;
}
-done:
FUNC_LEAVE(ret_value);
}
#endif
@@ -524,21 +522,23 @@ done:
herr_t
H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
{
- unsigned i;
+ unsigned i;
herr_t status;
H5AC_flush_func_t flush=NULL;
H5AC_info_t **info;
#ifdef H5AC_SORT_BY_ADDR
int *map = NULL;
#endif /* H5AC_SORT_BY_ADDR */
- unsigned nslots;
- H5AC_t *cache = NULL;
+ unsigned nslots;
+ H5AC_t *cache;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_flush, FAIL);
assert(f);
assert(f->shared->cache);
+
+ /* Get local copy of this information */
cache = f->shared->cache;
if (!H5F_addr_defined(addr)) {
@@ -549,7 +549,7 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
* Sort the cache entries by address since flushing them in
* ascending order by address may be much more efficient.
*/
- if (NULL==(map=H5FL_ARR_ALLOC(int,cache->nslots,0)))
+ if (NULL==(map=H5FL_ARR_MALLOC(int,cache->nslots)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
for (i = nslots = 0; i < cache->nslots; i++) {
if (cache->slot[i]!=NULL)
@@ -581,7 +581,9 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
continue;
#endif /* H5AC_SORT_BY_ADDR */
if (!type || type == (*info)->type) {
+#ifdef H5AC_DEBUG
H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */
+#endif /* H5AC_DEBUG */
flush = (*info)->type->flush;
@@ -592,20 +594,16 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
} /* end if */
else
status = (flush)(f, H5P_DATASET_XFER_DEFAULT, destroy, (*info)->addr, (*info));
- if (status < 0) {
-#ifdef H5AC_SORT_BY_ADDR
- map = H5FL_ARR_FREE(int,map);
-#endif /* H5AC_SORT_BY_ADDR */
+ if (status < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache");
- }
+
+#ifdef H5AC_DEBUG
cache->diagnostics[type_id].nflushes++;
+#endif /* H5AC_DEBUG */
if (destroy)
(*info)= NULL;
}
}
-#ifdef H5AC_SORT_BY_ADDR
- map = H5FL_ARR_FREE(int,map);
-#endif /* H5AC_SORT_BY_ADDR */
/*
* If there are protected object then fail. However, everything
@@ -616,9 +614,10 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
} else {
i = H5AC_HASH(f, addr);
if (cache->slot[i] && (!type || cache->slot[i]->type == type) &&
- H5F_addr_eq(cache->slot[i]->addr, addr)) {
-
+ H5F_addr_eq(addr,cache->slot[i]->addr)) {
+#ifdef H5AC_DEBUG
H5AC_subid_t type_id=cache->slot[i]->type->id; /* Remember this for later */
+#endif /* H5AC_DEBUG */
/*
* Flush just this entry.
@@ -627,13 +626,20 @@ H5AC_flush(H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
if ((flush)(f, H5AC_dxpl_id, destroy, cache->slot[i]->addr,
cache->slot[i]) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object");
+#ifdef H5AC_DEBUG
cache->diagnostics[type_id].nflushes++;
+#endif /* H5AC_DEBUG */
if (destroy)
cache->slot[i]= NULL;
}
}
done:
+#ifdef H5AC_SORT_BY_ADDR
+ if(map!=NULL)
+ map = H5FL_ARR_FREE(int,map);
+#endif /* H5AC_SORT_BY_ADDR */
+
FUNC_LEAVE(ret_value);
}
@@ -662,10 +668,10 @@ done:
herr_t
H5AC_set(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
{
- unsigned idx;
- H5AC_flush_func_t flush=NULL;
- H5AC_info_t **info = NULL;
- H5AC_t *cache = NULL;
+ unsigned idx;
+ H5AC_flush_func_t flush;
+ H5AC_info_t **info;
+ H5AC_t *cache;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_set, FAIL);
@@ -677,6 +683,7 @@ H5AC_set(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
assert(H5F_addr_defined(addr));
assert(thing);
+ /* Get local copy of this information */
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
info = cache->slot + idx;
@@ -693,19 +700,26 @@ H5AC_set(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
#endif
+ /* Flush any object already in cache slot */
if ((*info)) {
+#ifdef H5AC_DEBUG
H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */
+#endif /* H5AC_DEBUG */
flush = (*info)->type->flush;
if ((flush)(f, H5AC_dxpl_id, TRUE, (*info)->addr, (*info)) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object");
+#ifdef H5AC_DEBUG
cache->diagnostics[type_id].nflushes++;
+#endif /* H5AC_DEBUG */
}
(*info)=thing;
(*info)->type = type;
(*info)->addr = addr;
+#ifdef H5AC_DEBUG
cache->diagnostics[type->id].ninits++;
+#endif /* H5AC_DEBUG */
done:
FUNC_LEAVE(ret_value);
@@ -737,9 +751,9 @@ herr_t
H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
haddr_t new_addr)
{
- unsigned old_idx, new_idx;
- H5AC_flush_func_t flush=NULL;
- H5AC_t *cache = NULL;
+ unsigned old_idx, new_idx;
+ H5AC_flush_func_t flush;
+ H5AC_t *cache;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_rename, FAIL);
@@ -748,6 +762,7 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
assert(f->shared->cache);
assert(type);
+ /* Get local copy of this information */
old_idx = H5AC_HASH(f, old_addr);
new_idx = H5AC_HASH(f, new_addr);
cache = f->shared->cache;
@@ -771,7 +786,7 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
* new hash value is the same as the old one.
*/
if (cache->slot[old_idx]->type != type ||
- H5F_addr_ne(cache->slot[old_idx]->addr, old_addr)) {
+ H5F_addr_ne(cache->slot[old_idx]->addr, old_addr)) {
HGOTO_DONE(SUCCEED);
}
if (old_idx == new_idx) {
@@ -782,13 +797,17 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr,
* Free the item from the destination cache line.
*/
if (cache->slot[new_idx]) {
+#ifdef H5AC_DEBUG
H5AC_subid_t type_id=cache->slot[new_idx]->type->id; /* Remember this for later */
+#endif /* H5AC_DEBUG */
flush = cache->slot[new_idx]->type->flush;
if ((flush)(f, H5AC_dxpl_id, TRUE, cache->slot[new_idx]->addr,
cache->slot[new_idx]) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object");
+#ifdef H5AC_DEBUG
cache->diagnostics[type_id].nflushes++;
+#endif /* H5AC_DEBUG */
}
/*
@@ -836,9 +855,9 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
const void *udata1, void *udata2)
{
int idx;
- void *thing = NULL;
- H5AC_t *cache = NULL;
- H5AC_info_t **info = NULL;
+ void *thing;
+ H5AC_t *cache;
+ H5AC_info_t **info;
void *ret_value; /* Return value */
#ifdef H5AC_DEBUG
@@ -862,6 +881,7 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
assert(type->flush);
assert(H5F_addr_defined(addr));
+ /* Get local copy of this information */
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
info = cache->slot + idx;
@@ -869,22 +889,20 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
prot = cache->prot + idx;
#endif /* H5AC_DEBUG */
- if ((*info) && (*info)->type == type && H5F_addr_eq((*info)->addr, addr)) {
+ if ((*info) && H5F_addr_eq(addr,(*info)->addr)) {
+ /* Sanity check that the object in the cache is the correct type */
+ assert((*info)->type==type);
+
/*
* The object is already cached; simply remove it from the cache.
*/
+#ifdef H5AC_DEBUG
cache->diagnostics[(*info)->type->id].nhits++;
+#endif /* H5AC_DEBUG */
thing = (*info);
(*info)->type = NULL;
(*info)->addr = HADDR_UNDEF;
(*info)= NULL;
-
- } else if ((*info) && (*info)->type && H5F_addr_eq((*info)->addr, addr)) {
- /*
- * Right address but wrong object type.
- */
- HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, NULL, "internal error");
-
} else {
#ifdef H5AC_DEBUG
/*
@@ -902,7 +920,9 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
+#ifdef H5AC_DEBUG
cache->diagnostics[type->id].nmisses++;
+#endif /* H5AC_DEBUG */
if (NULL == (thing = (type->load)(f, H5P_DATASET_XFER_DEFAULT, addr, udata1, udata2)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "unable to load object");
}
@@ -963,11 +983,11 @@ done:
herr_t
H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
{
- unsigned idx;
- H5AC_flush_func_t flush=NULL;
- H5AC_t *cache = NULL;
- H5AC_info_t **info = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned idx;
+ H5AC_flush_func_t flush;
+ H5AC_t *cache;
+ H5AC_info_t **info;
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_unprotect, FAIL);
@@ -979,6 +999,7 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
assert(H5F_addr_defined(addr));
assert(thing);
+ /* Get local copy of this information */
idx = H5AC_HASH(f, addr);
cache = f->shared->cache;
info = cache->slot + idx;
@@ -988,13 +1009,17 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
* better not be another copy of the protected object.
*/
if (*info) {
+#ifdef H5AC_DEBUG
H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */
+#endif /* H5AC_DEBUG */
assert(H5F_addr_ne((*info)->addr, addr));
flush = (*info)->type->flush;
if ((flush)(f, H5AC_dxpl_id, TRUE, (*info)->addr, (*info)) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object");
+#ifdef H5AC_DEBUG
cache->diagnostics[type_id].nflushes++;
+#endif /* H5AC_DEBUG */
}
#ifdef H5AC_DEBUG
/*
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index 44d4ca8..d587df6 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -99,12 +99,14 @@ typedef struct H5AC_t {
H5AC_prot_t *prot; /*the protected slots */
#endif /* H5AC_DEBUG */
int nprots; /*number of protected objects */
+#ifdef H5AC_DEBUG
struct {
unsigned nhits; /*number of cache hits */
unsigned nmisses; /*number of cache misses */
unsigned ninits; /*number of cache inits */
unsigned nflushes; /*number of flushes to disk */
} diagnostics[H5AC_NTYPES]; /*diagnostics for each type of object*/
+#endif /* H5AC_DEBUG */
} H5AC_t;
#ifdef H5_HAVE_PARALLEL
@@ -133,6 +135,10 @@ H5_DLL herr_t H5AC_set(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *thing);
H5_DLL herr_t H5AC_debug(H5F_t *f);
+/* This seems to be slower than just calling H5AC_find_f, which performs the
+ * cache lookup also. - QAK
+ */
+#ifdef OLD_WAY
#define H5AC_find(F,TYPE,ADDR,UDATA1,UDATA2) \
((F)->shared->cache->slot[H5AC_HASH(F,ADDR)]!=NULL && \
((F)->shared->cache->slot[H5AC_HASH(F,ADDR)]->type==(TYPE) && \
@@ -140,6 +146,7 @@ H5_DLL herr_t H5AC_debug(H5F_t *f);
((F)->shared->cache->diagnostics[(TYPE)->id].nhits++, \
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)]) : \
H5AC_find_f(F, TYPE, ADDR, UDATA1, UDATA2))
+#endif /* OLD_WAY */
#endif /* !_H5ACprivate_H */
diff --git a/src/H5B.c b/src/H5B.c
index 700cf3f..a0386b0 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -212,7 +212,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
size = H5B_nodesize(f, type, &total_native_keysize, sizeof_rkey);
if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, (hsize_t)size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree root node");
- if (NULL==(bt = H5FL_ALLOC(H5B_t,1)))
+ if (NULL==(bt = H5FL_CALLOC(H5B_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree root node");
bt->type = type;
bt->sizeof_rkey = sizeof_rkey;
@@ -222,10 +222,10 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
bt->left = HADDR_UNDEF;
bt->right = HADDR_UNDEF;
bt->nchildren = 0;
- if (NULL==(bt->page=H5FL_BLK_ALLOC(page,size,1)) ||
- NULL==(bt->native=H5FL_BLK_ALLOC(native_block,total_native_keysize,0)) ||
- NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,(size_t)(2*H5B_Kvalue(f,type)),0)) ||
- NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(size_t)(2*H5B_Kvalue(f,type)+1),0)))
+ if (NULL==(bt->page=H5FL_BLK_CALLOC(page,size)) ||
+ NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_native_keysize)) ||
+ NULL==(bt->child=H5FL_ARR_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type)))) ||
+ NULL==(bt->key=H5FL_ARR_MALLOC(H5B_key_t,(size_t)(2*H5F_KVALUE(f,type)+1))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree root node");
/*
@@ -234,7 +234,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
* translated to native format.
*/
for (i = 0, offset = H5B_SIZEOF_HDR(f);
- i < 2 * H5B_Kvalue(f, type);
+ i < 2 * H5F_KVALUE(f, type);
i++, offset += bt->sizeof_rkey + H5F_SIZEOF_ADDR(f)) {
bt->key[i].dirty = FALSE;
@@ -246,9 +246,9 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
/*
* The last possible key...
*/
- bt->key[2 * H5B_Kvalue(f, type)].dirty = FALSE;
- bt->key[2 * H5B_Kvalue(f, type)].rkey = bt->page + offset;
- bt->key[2 * H5B_Kvalue(f, type)].nkey = NULL;
+ bt->key[2 * H5F_KVALUE(f, type)].dirty = FALSE;
+ bt->key[2 * H5F_KVALUE(f, type)].rkey = bt->page + offset;
+ bt->key[2 * H5F_KVALUE(f, type)].nkey = NULL;
/*
* Cache the new B-tree node.
@@ -276,54 +276,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5B_Kvalue
- *
- * Purpose: Replaced a macro to retrieve a B-tree key value for a certain
- * type, now that the generic properties are being used to store
- * the B-tree values.
- *
- * Return: Success: Non-negative, and the B-tree key value is
- * returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Raymond Lu
- * slu@ncsa.uiuc.edu
- * Oct 14 2001
- *
- * Modifications:
- * Quincey Koziol, 2001-10-15
- * Added this header and removed unused ret_value variable.
- *-------------------------------------------------------------------------
- */
-int
-H5B_Kvalue(H5F_t *f, const H5B_class_t *type)
-{
- int btree_k[H5B_NUM_BTREE_ID];
- H5P_genplist_t *plist;
- int ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5B_Kvalue, FAIL);
-
- assert(f);
- assert(type);
-
- /* Check arguments */
- if (NULL == (plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list");
-
- if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes");
-
- /* Set return value */
- ret_value=btree_k[type->id];
-
-done:
- FUNC_LEAVE(ret_value);
-} /* end H5B_Kvalue() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5B_load
*
* Purpose: Loads a B-tree node from the disk.
@@ -364,17 +316,17 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
assert(type);
assert(type->get_sizeof_rkey);
- if (NULL==(bt = H5FL_ALLOC(H5B_t,1)))
+ if (NULL==(bt = H5FL_CALLOC(H5B_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
bt->sizeof_rkey = (type->get_sizeof_rkey) (f, udata);
size = H5B_nodesize(f, type, &total_nkey_size, bt->sizeof_rkey);
bt->type = type;
bt->dirty = FALSE;
bt->ndirty = 0;
- if (NULL==(bt->page=H5FL_BLK_ALLOC(page,size,0)) ||
- NULL==(bt->native=H5FL_BLK_ALLOC(native_block,total_nkey_size,0)) ||
- NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(size_t)(2*H5B_Kvalue(f,type)+1),0)) ||
- NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,(size_t)(2*H5B_Kvalue(f,type)),0)))
+ if (NULL==(bt->page=H5FL_BLK_MALLOC(page,size)) ||
+ NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_nkey_size)) ||
+ NULL==(bt->key=H5FL_ARR_MALLOC(H5B_key_t,(size_t)(2*H5F_KVALUE(f,type)+1))) ||
+ NULL==(bt->child=H5FL_ARR_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type)))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, bt->page)<0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node");
@@ -398,7 +350,7 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
H5F_addr_decode(f, (const uint8_t **) &p, &(bt->right));
/* the child/key pairs */
- for (i = 0; i < 2 * H5B_Kvalue(f, type); i++) {
+ for (i = 0; i < 2 * H5F_KVALUE(f, type); i++) {
bt->key[i].dirty = FALSE;
bt->key[i].rkey = p;
@@ -413,9 +365,9 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
}
}
- bt->key[2 * H5B_Kvalue(f, type)].dirty = FALSE;
- bt->key[2 * H5B_Kvalue(f, type)].rkey = p;
- bt->key[2 * H5B_Kvalue(f, type)].nkey = NULL;
+ bt->key[2 * H5F_KVALUE(f, type)].dirty = FALSE;
+ bt->key[2 * H5F_KVALUE(f, type)].rkey = p;
+ bt->key[2 * H5F_KVALUE(f, type)].nkey = NULL;
/* Set return value */
ret_value = bt;
@@ -675,9 +627,9 @@ H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
/*
* Initialize variables.
*/
- assert(old_bt->nchildren == 2 * H5B_Kvalue(f, type));
+ assert(old_bt->nchildren == 2 * H5F_KVALUE(f, type));
recsize = old_bt->sizeof_rkey + H5F_SIZEOF_ADDR(f);
- k = H5B_Kvalue(f, type);
+ k = H5F_KVALUE(f, type);
#ifdef H5B_DEBUG
if (H5DEBUG(B)) {
@@ -770,7 +722,7 @@ H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
new_bt->right = old_bt->right;
if (H5F_addr_defined(old_bt->right)) {
- if (NULL == (tmp_bt = H5AC_find(f, H5AC_BT, old_bt->right, type, udata)))
+ if (NULL == (tmp_bt = H5AC_find_f(f, H5AC_BT, old_bt->right, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load right sibling");
tmp_bt->dirty = TRUE;
tmp_bt->left = *new_addr_p;
@@ -919,7 +871,7 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
assert(H5B_INS_RIGHT == my_ins);
/* the current root */
- if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata)))
+ if (NULL == (bt = H5AC_find_f(f, H5AC_BT, addr, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to locate root of B-tree");
level = bt->level;
if (!lt_key_changed) {
@@ -929,7 +881,7 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
}
/* the new node */
- if (NULL == (bt = H5AC_find(f, H5AC_BT, child, type, udata)))
+ if (NULL == (bt = H5AC_find_f(f, H5AC_BT, child, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load new node");
if (!rt_key_changed) {
if (!bt->key[bt->nchildren].nkey &&
@@ -948,7 +900,7 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space to move root");
/* update the new child's left pointer */
- if (NULL == (bt = H5AC_find(f, H5AC_BT, child, type, udata)))
+ if (NULL == (bt = H5AC_find_f(f, H5AC_BT, child, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load new child");
bt->dirty = TRUE;
bt->left = old_root;
@@ -958,7 +910,7 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
* at the new location -QAK
*/
/* Bring the old root into the cache if it's not already */
- if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata)))
+ if (NULL == (bt = H5AC_find_f(f, H5AC_BT, addr, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load new child");
/* Make certain the old root info is marked as dirty before moving it, */
@@ -1038,7 +990,7 @@ H5B_insert_child(H5F_t *f, const H5B_class_t *type, H5B_t *bt,
FUNC_ENTER_NOINIT(H5B_insert_child);
assert(bt);
- assert(bt->nchildren<2*H5B_Kvalue(f, type));
+ assert(bt->nchildren<2*H5F_KVALUE(f, type));
bt->dirty = TRUE;
recsize = bt->sizeof_rkey + H5F_SIZEOF_ADDR(f);
@@ -1383,7 +1335,7 @@ H5B_insert_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type,
/*
* If this node is full then split it before inserting the new child.
*/
- if (bt->nchildren == 2 * H5B_Kvalue(f, type)) {
+ if (bt->nchildren == 2 * H5F_KVALUE(f, type)) {
if (H5B_split(f, type, bt, addr, idx, split_ratios, udata,
new_node_p/*out*/)<0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, H5B_INS_ERROR, "unable to split node");
@@ -1488,7 +1440,7 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, H5B_operator_t op, haddr_t addr,
assert(H5F_addr_defined(addr));
assert(udata);
- if (NULL == (bt=H5AC_find(f, H5AC_BT, addr, type, udata)))
+ if (NULL == (bt=H5AC_find_f(f, H5AC_BT, addr, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node");
if (bt->level > 0) {
/* Keep following the left-most child until we reach a leaf node. */
@@ -1499,8 +1451,8 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, H5B_operator_t op, haddr_t addr,
* We've reached the left-most leaf. Now follow the right-sibling
* pointer from leaf to leaf until we've processed all leaves.
*/
- if (NULL==(child=H5FL_ARR_ALLOC(haddr_t,(size_t)(2*H5B_Kvalue(f,type)),0)) ||
- NULL==(key=H5MM_malloc((2*H5B_Kvalue(f, type)+1)*type->sizeof_nkey)))
+ if (NULL==(child=H5FL_ARR_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type)))) ||
+ NULL==(key=H5MM_malloc((2*H5F_KVALUE(f, type)+1)*type->sizeof_nkey)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
for (cur_addr=addr, ret_value=0; H5F_addr_defined(cur_addr); cur_addr=next_addr) {
@@ -1509,7 +1461,7 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, H5B_operator_t op, haddr_t addr,
* leave the B-tree node protected during an application
* callback.
*/
- if (NULL==(bt=H5AC_find (f, H5AC_BT, cur_addr, type, udata)))
+ if (NULL==(bt=H5AC_find_f (f, H5AC_BT, cur_addr, type, udata)))
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node");
for (i=0; i<bt->nchildren; i++)
child[i] = bt->child[i];
@@ -1698,13 +1650,13 @@ H5B_remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type,
bt->ndirty = 0;
if (level>0) {
if (H5F_addr_defined(bt->left)) {
- if (NULL==(sibling=H5AC_find(f, H5AC_BT, bt->left, type, udata)))
+ if (NULL==(sibling=H5AC_find_f(f, H5AC_BT, bt->left, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to unlink node from tree");
sibling->right = bt->right;
sibling->dirty = TRUE;
}
if (H5F_addr_defined(bt->right)) {
- if (NULL==(sibling=H5AC_find(f, H5AC_BT, bt->right, type, udata)))
+ if (NULL==(sibling=H5AC_find_f(f, H5AC_BT, bt->right, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to unlink node from tree");
sibling->left = bt->left;
sibling->dirty = TRUE;
@@ -1862,7 +1814,7 @@ H5B_remove(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
* If the B-tree is now empty then make sure we mark the root node as
* being at level zero
*/
- if (NULL==(bt=H5AC_find(f, H5AC_BT, addr, type, udata)))
+ if (NULL==(bt=H5AC_find_f(f, H5AC_BT, addr, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree root node");
if (0==bt->nchildren && 0!=bt->level) {
bt->level = 0;
@@ -1915,20 +1867,20 @@ H5B_nodesize(H5F_t *f, const H5B_class_t *type,
assert(f);
assert(type);
assert(sizeof_rkey > 0);
- assert(H5B_Kvalue(f, type) > 0);
+ assert(H5F_KVALUE(f, type) > 0);
/*
* Total native key size.
*/
if (total_nkey_size)
- *total_nkey_size = (2 * H5B_Kvalue(f, type) + 1) * type->sizeof_nkey;
+ *total_nkey_size = (2 * H5F_KVALUE(f, type) + 1) * type->sizeof_nkey;
/*
* Total node size.
*/
size = (H5B_SIZEOF_HDR(f) + /*node header */
- 2 * H5B_Kvalue(f, type) * H5F_SIZEOF_ADDR(f) + /*child pointers */
- (2 * H5B_Kvalue(f, type) + 1) * sizeof_rkey); /*keys */
+ 2 * H5F_KVALUE(f, type) * H5F_SIZEOF_ADDR(f) + /*child pointers */
+ (2 * H5F_KVALUE(f, type) + 1) * sizeof_rkey); /*keys */
/* Set return value */
ret_value=size;
@@ -1979,19 +1931,19 @@ H5B_copy(H5F_t *f, const H5B_t *old_bt)
size = H5B_nodesize(f, old_bt->type, &total_native_keysize, old_bt->sizeof_rkey);
/* Allocate memory for the new H5B_t object */
- if (NULL==(new_node = H5FL_ALLOC(H5B_t,0)))
+ if (NULL==(new_node = H5FL_MALLOC(H5B_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node");
/* Copy the main structure */
HDmemcpy(new_node,old_bt,sizeof(H5B_t));
/* Compute the number of keys in this node */
- nkeys=2*H5B_Kvalue(f,old_bt->type);
+ nkeys=2*H5F_KVALUE(f,old_bt->type);
- if (NULL==(new_node->page=H5FL_BLK_ALLOC(page,size,0)) ||
- NULL==(new_node->native=H5FL_BLK_ALLOC(native_block,total_native_keysize,0)) ||
- NULL==(new_node->child=H5FL_ARR_ALLOC(haddr_t,nkeys,0)) ||
- NULL==(new_node->key=H5FL_ARR_ALLOC(H5B_key_t,(nkeys+1),0)))
+ if (NULL==(new_node->page=H5FL_BLK_MALLOC(page,size)) ||
+ NULL==(new_node->native=H5FL_BLK_MALLOC(native_block,total_native_keysize)) ||
+ NULL==(new_node->child=H5FL_ARR_MALLOC(haddr_t,nkeys)) ||
+ NULL==(new_node->key=H5FL_ARR_MALLOC(H5B_key_t,(nkeys+1))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node");
/* Copy the other structures */
@@ -2064,7 +2016,7 @@ H5B_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth,
/*
* Load the tree node.
*/
- if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata)))
+ if (NULL == (bt = H5AC_find_f(f, H5AC_BT, addr, type, udata)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node");
/*
@@ -2101,7 +2053,7 @@ H5B_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth,
HDfprintf(stream, "%*s%-*s %d (%d)\n", indent, "", fwidth,
"Number of children (max):",
(int) (bt->nchildren),
- (int) (2 * H5B_Kvalue(f, type)));
+ (int) (2 * H5F_KVALUE(f, type)));
/*
* Print the child addresses
@@ -2164,7 +2116,7 @@ H5B_assert(H5F_t *f, haddr_t addr, const H5B_class_t *type, void *udata)
}
}
/* Initialize the queue */
- bt = H5AC_find(f, H5AC_BT, addr, type, udata);
+ bt = H5AC_find_f(f, H5AC_BT, addr, type, udata);
assert(bt);
cur = H5MM_calloc(sizeof(struct child_t));
assert (cur);
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 3a59d93..d22edcb 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -140,6 +140,4 @@ H5_DLL herr_t H5B_remove(H5F_t *f, const H5B_class_t *type, haddr_t addr,
void *udata);
H5_DLL herr_t H5B_iterate (H5F_t *f, const H5B_class_t *type, H5B_operator_t
op, haddr_t addr, void *udata);
-H5_DLL int H5B_Kvalue(H5F_t *f, const H5B_class_t *type);
-
#endif
diff --git a/src/H5D.c b/src/H5D.c
index 7485d7e..cab38cd 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -19,6 +19,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free Lists */
+#include "H5FOprivate.h" /* File objects */
#include "H5Gprivate.h" /* Group headers */
#include "H5HLprivate.h" /* Name heap */
#include "H5Iprivate.h" /* IDs */
@@ -64,12 +65,25 @@ static int interface_initialize_g = 0;
/* Local functions */
static herr_t H5D_init_interface(void);
-static herr_t H5D_alloc_storage (H5F_t *f, H5D_t *dset,H5D_time_alloc_t time_alloc);
-static herr_t H5D_init_storage(H5D_t *dataset);
-H5D_t * H5D_new(hid_t dcpl_id);
+static herr_t H5D_alloc_storage (H5F_t *f, H5D_t *dset,H5D_time_alloc_t time_alloc,
+ hbool_t update_time, hbool_t full_overwrite);
+static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite);
+static H5D_t * H5D_new(hid_t dcpl_id, hbool_t creating);
+static H5D_t * H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
+ const H5S_t *space, hid_t dcpl_id);
+static H5D_t * H5D_open_oid(H5G_entry_t *ent);
+static herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type,
+ const H5S_t *mem_space, const H5S_t *file_space,
+ hid_t dset_xfer_plist, void *buf/*out*/);
+static herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type,
+ const H5S_t *mem_space, const H5S_t *file_space,
+ hid_t dset_xfer_plist, const void *buf);
static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
const H5T_t *buf_type, const H5S_t *space);
static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation);
+static hsize_t H5D_get_storage_size(H5D_t *dset);
+static haddr_t H5D_get_offset(H5D_t *dset);
+static herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size);
/* Declare a free list to manage the H5D_t struct */
H5FL_DEFINE_STATIC(H5D_t);
@@ -86,6 +100,9 @@ H5FL_BLK_DEFINE_STATIC(vlen_vl_buf);
/* Declare a free list to manage other blocks of VL data */
H5FL_BLK_DEFINE_STATIC(vlen_fl_buf);
+/* Define a static "default" dataset structure to use to initialize new datasets */
+static H5D_t H5D_def_dset;
+
/*-------------------------------------------------------------------------
* Function: H5D_init
@@ -188,6 +205,7 @@ H5D_init_interface(void)
H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF;
H5O_pline_t pline = H5D_CRT_DATA_PIPELINE_DEF;
+ H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */
size_t nprops; /* Number of properties */
herr_t ret_value = SUCCEED; /* Return value */
@@ -202,7 +220,7 @@ H5D_init_interface(void)
assert(H5P_CLS_DATASET_XFER_g!=(-1));
/* Get the pointer to the dataset transfer class */
- if (NULL == (xfer_pclass = H5I_object_verify(H5P_CLS_DATASET_XFER_g, H5I_GENPROP_CLS)))
+ if (NULL == (xfer_pclass = H5I_object(H5P_CLS_DATASET_XFER_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -282,7 +300,7 @@ H5D_init_interface(void)
assert(H5P_CLS_DATASET_CREATE_g != -1);
/* Get the pointer to the dataset creation class */
- if(NULL == (crt_pclass = H5I_object_verify(H5P_CLS_DATASET_CREATE_g, H5I_GENPROP_CLS)))
+ if(NULL == (crt_pclass = H5I_object(H5P_CLS_DATASET_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -331,6 +349,37 @@ H5D_init_interface(void)
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list");
} /* end if */
+ /* Reset the "default dataset" information */
+ HDmemset(&H5D_def_dset,0,sizeof(H5D_t));
+
+ /* Get the default dataset cretion property list values and initialize the
+ * default dataset with them.
+ */
+ if (NULL == (def_dcpl = H5I_object(H5P_LST_DATASET_CREATE_g)))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, NULL, "can't get default dataset creation property list");
+
+ /* Set up the default allocation time information */
+ if(H5P_get(def_dcpl, H5D_CRT_ALLOC_TIME_NAME, &H5D_def_dset.alloc_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
+ if(H5D_def_dset.alloc_time==H5D_ALLOC_TIME_DEFAULT)
+ H5D_def_dset.alloc_time=H5D_ALLOC_TIME_LATE;
+
+ /* Get the default external file list information */
+ if(H5P_get(def_dcpl, H5D_CRT_EXT_FILE_LIST_NAME, &H5D_def_dset.efl) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list");
+
+ /* Get the default data storage method */
+ if(H5P_get(def_dcpl, H5D_CRT_LAYOUT_NAME, &H5D_def_dset.layout.type) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+
+ /* Get the default fill value time */
+ if (H5P_get(def_dcpl, H5D_CRT_FILL_TIME_NAME, &H5D_def_dset.fill_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+
+ /* Get the default fill value */
+ if (H5P_get(def_dcpl, H5D_CRT_FILL_VALUE_NAME, &H5D_def_dset.fill) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
+
done:
FUNC_LEAVE(ret_value);
}
@@ -404,25 +453,21 @@ H5D_crt_copy(hid_t new_plist_id, hid_t old_plist_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI(H5D_crt_copy, FAIL);
/* Verify property list ID */
- if (NULL == (new_plist = H5P_object_verify(new_plist_id,H5P_DATASET_CREATE)))
+ if (NULL == (new_plist = H5I_object(new_plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if (NULL == (old_plist = H5P_object_verify(old_plist_id,H5P_DATASET_CREATE)))
+ if (NULL == (old_plist = H5I_object(old_plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the fill value, external file list, and data pipeline properties
* from the old property list */
- HDmemset(&src_fill,0,sizeof(H5O_fill_t));
if(H5P_get(old_plist, H5D_CRT_FILL_VALUE_NAME, &src_fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
- HDmemset(&src_efl,0,sizeof(H5O_efl_t));
if(H5P_get(old_plist, H5D_CRT_EXT_FILE_LIST_NAME, &src_efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
- HDmemset(&src_pline,0,sizeof(H5O_pline_t));
if(H5P_get(old_plist, H5D_CRT_DATA_PIPELINE_NAME, &src_pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
/* Make copies of fill value, external file list, and data pipeline */
- HDmemset(&dst_fill,0,sizeof(H5O_fill_t));
if(src_fill.buf && (NULL==H5O_copy(H5O_FILL, &src_fill, &dst_fill))) {
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy fill value");
}
@@ -433,7 +478,6 @@ H5D_crt_copy(hid_t new_plist_id, hid_t old_plist_id, void UNUSED *copy_data)
HDmemset(&dst_efl,0,sizeof(H5O_efl_t));
if(NULL==H5O_copy(H5O_EFL, &src_efl, &dst_efl))
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy external file list");
- HDmemset(&dst_pline,0,sizeof(H5O_pline_t));
if(NULL==H5O_copy(H5O_PLINE, &src_pline, &dst_pline))
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy data pipeline");
@@ -481,18 +525,15 @@ H5D_crt_close(hid_t dcpl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI(H5D_crt_close, FAIL);
/* Check arguments */
- if (NULL == (plist = H5P_object_verify(dcpl_id,H5P_DATASET_CREATE)))
+ if (NULL == (plist = H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the fill value, external file list, and data pipeline properties
* from the old property list */
- HDmemset(&fill,0,sizeof(H5O_fill_t));
if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
- HDmemset(&efl,0,sizeof(H5O_efl_t));
if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
- HDmemset(&pline,0,sizeof(H5O_pline_t));
if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
@@ -540,7 +581,7 @@ H5D_xfer_create(hid_t dxpl_id, void UNUSED *create_data)
FUNC_ENTER_NOAPI(H5D_xfer_create, FAIL);
/* Check arguments */
- if (NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
/* Get the driver information */
@@ -634,7 +675,7 @@ H5D_xfer_close(hid_t dxpl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI(H5D_xfer_close, FAIL);
/* Check arguments */
- if (NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
@@ -717,8 +758,9 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
if(H5P_DEFAULT == plist_id)
plist_id = H5P_DATASET_CREATE_DEFAULT;
- if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list");
+ else
+ if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list");
/* build and open the new dataset */
if (NULL == (new_dset = H5D_create(loc, name, type, space, plist_id)))
@@ -728,6 +770,10 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
if ((ret_value = H5I_register(H5I_DATASET, new_dset)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset");
+ /* Add the dataset to the list of opened objects in the file */
+ if(H5FO_insert(new_dset->ent.file,new_dset->ent.header,ret_value)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert dataset into list of open objects");
+
done:
if(ret_value<0) {
if(new_dset!=NULL)
@@ -762,7 +808,7 @@ hid_t
H5Dopen(hid_t loc_id, const char *name)
{
H5G_entry_t *loc = NULL; /*location holding the dataset */
- H5D_t *dataset = NULL; /*the dataset */
+ H5G_entry_t ent; /*dataset symbol table entry */
hid_t ret_value;
FUNC_ENTER_API(H5Dopen, FAIL);
@@ -774,20 +820,15 @@ H5Dopen(hid_t loc_id, const char *name)
if (!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
- /* Find the dataset */
- if (NULL == (dataset = H5D_open(loc, name)))
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "dataset not found");
-
- /* Create an atom for the dataset */
- if ((ret_value = H5I_register(H5I_DATASET, dataset)) < 0)
+ /* Find the dataset object */
+ if (H5G_find(loc, name, NULL, &ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+
+ /* Open the dataset */
+ if ((ret_value = H5D_open(&ent)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset");
done:
- if(ret_value<0) {
- if(dataset!=NULL)
- H5D_close(dataset);
- } /* end if */
-
FUNC_LEAVE(ret_value);
}
@@ -874,7 +915,7 @@ H5Dget_space(hid_t dset_id)
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
/* Read the data space message and return a data space object */
- if (NULL==(space=H5D_get_space (dset)))
+ if (NULL==(space=H5S_copy (dset->space)))
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space");
/* Create an atom */
@@ -892,42 +933,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_get_space
- *
- * Purpose: Returns the data space associated with the dataset.
- *
- * Return: Success: Ptr to a copy of the data space.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Tuesday, August 25, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-H5S_t *
-H5D_get_space(H5D_t *dset)
-{
- H5S_t *space;
- H5S_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5D_get_space, NULL);
- assert(dset);
-
- if (NULL==(space=H5S_read(&(dset->ent))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load space info from dataset header");
-
- /* Set return value */
- ret_value=space;
-
-done:
- FUNC_LEAVE(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Dget_space_status
*
* Purpose: Returns the status of data space allocation.
@@ -981,7 +986,7 @@ done:
*/
static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation)
{
- H5S_t *space=NULL; /* Dataset's dataspace */
+ H5S_t *space; /* Dataset's dataspace */
hsize_t space_allocated; /* The number of bytes allocated for chunks */
hssize_t total_elem; /* The total number of elements in dataspace */
size_t type_size; /* The size of the datatype for the dataset */
@@ -990,9 +995,11 @@ static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation)
FUNC_ENTER_NOINIT(H5D_get_space_status);
+ assert(dset);
+
/* Get the dataset's dataspace */
- if((space=H5D_get_space(dset))==NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get dataspace");
+ space=dset->space;
+ assert(space);
/* Get the total number of elements in dataset's dataspace */
if((total_elem=H5S_get_simple_extent_npoints(space))<0)
@@ -1022,8 +1029,6 @@ static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation)
} /* end else */
done:
- if(space)
- H5S_close(space);
FUNC_LEAVE(ret_value);
}
@@ -1247,9 +1252,9 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
/* Get the default dataset transfer property list if the user didn't provide one */
if (H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
-
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
if (!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
@@ -1338,9 +1343,9 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
/* Get the default dataset transfer property list if the user didn't provide one */
if (H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
-
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
if (!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
@@ -1416,8 +1421,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t *
-H5D_new(hid_t dcpl_id)
+static H5D_t *
+H5D_new(hid_t dcpl_id, hbool_t creating)
{
H5P_genplist_t *plist; /* Property list created */
H5D_t *new_dset = NULL; /* New dataset object */
@@ -1425,16 +1430,31 @@ H5D_new(hid_t dcpl_id)
FUNC_ENTER_NOAPI(H5D_new, NULL);
- if (NULL==(new_dset = H5FL_ALLOC(H5D_t,1)))
+ if (NULL==(new_dset = H5FL_MALLOC(H5D_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if(H5P_DEFAULT == dcpl_id)
- dcpl_id = H5P_DATASET_CREATE_DEFAULT;
- /* Get the property list */
- if (NULL == (plist = H5P_object_verify(dcpl_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list");
+ /* If we are using the default dataset creation property list, during creation
+ * don't bother to copy it, just increment the reference count
+ */
+ if(creating && dcpl_id == H5P_DATASET_CREATE_DEFAULT) {
+ /* Copy the default dataset information */
+ HDmemcpy(new_dset,&H5D_def_dset,sizeof(H5D_t));
+
+ if(H5I_inc_ref(dcpl_id)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINC, NULL, "Can't increment default DCPL ID");
+ new_dset->dcpl_id = dcpl_id;
+ } /* end if */
+ else {
+ /* Reset the dataset information */
+ HDmemset(new_dset,0,sizeof(H5D_t));
+
+ /* Get the property list */
+ if (NULL == (plist = H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list");
+
+ new_dset->dcpl_id = H5P_copy_plist(plist);
+ } /* end else */
- new_dset->dcpl_id = H5P_copy_plist(plist);
new_dset->ent.header = HADDR_UNDEF;
/* Set return value */
@@ -1442,8 +1462,11 @@ H5D_new(hid_t dcpl_id)
done:
if(ret_value==NULL) {
- if(new_dset!=NULL)
+ if(new_dset!=NULL) {
+ if(new_dset->dcpl_id!=0)
+ H5I_dec_ref(new_dset->dcpl_id);
H5FL_FREE(H5D_t,new_dset);
+ } /* end if */
} /* end if */
FUNC_LEAVE(ret_value);
@@ -1451,7 +1474,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_update_entry_cache
+ * Function: H5D_update_entry_info
*
* Purpose: Create and fill an H5G_entry_t object for insertion into
* the group LOC.
@@ -1471,72 +1494,86 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
- const char *name, const H5S_t *space,
- H5P_genplist_t *plist, H5O_layout_t *layout, H5T_t *type,
- hbool_t allocate_header, haddr_t header)
+static herr_t
+H5D_update_entry_info(H5F_t *file, H5D_t *dset, H5P_genplist_t *plist)
{
- H5O_pline_t dcpl_pline;
- H5D_alloc_time_t alloc_time;
size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */
+ H5G_entry_t *ent=NULL; /* Dataset's group entry */
+ H5O_layout_t *layout; /* Dataset's layout information */
+ H5T_t *type; /* Dataset's datatype */
+ H5S_t *space; /* Dataset's dataspace */
+ H5D_alloc_time_t alloc_time;/* Dataset's allocation time */
+ H5O_efl_t *efl; /* Dataset's external file list */
/* fill value variables */
H5D_fill_time_t fill_time;
- H5O_fill_t fill_prop = { NULL, 0, NULL };
+ H5O_fill_t *fill_prop; /* Pointer to dataset's fill value information */
H5O_fill_new_t fill = { NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_FILL_TIME_ALLOC, TRUE };
H5D_fill_value_t fill_status;
+ H5O_t *oh=NULL; /* Pointer to dataset's object header */
+
/* return code */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5D_update_entry_cache, FAIL);
+ FUNC_ENTER_NOAPI(H5D_update_entry_info, FAIL);
+
+ /* Sanity checking */
+ assert(file);
+ assert(dset);
+ /* Pick up former parameters */
+ ent=&dset->ent;
+ layout=&dset->layout;
+ type=dset->type;
+ space=dset->space;
+ alloc_time=dset->alloc_time;
+ efl=&dset->efl;
+
+ /* Add the dataset's raw data size to the size of the header, if the raw data will be stored as compact */
if (layout->type == H5D_COMPACT)
ohdr_size += layout->size;
- /* If TRUE, then allocate the space in the file for the header */
- if (allocate_header) {
- /* Create (open for write access) an object header */
- if (H5O_create(file, ohdr_size, ent) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to create dataset object header");
- } else {
- /*
- * Just initialize the header to the specified address and open
- * it for us
- */
- HDmemset(ent, 0, sizeof(H5G_entry_t));
+ /* Create (open for write access) an object header */
+ if (H5O_create(file, ohdr_size, ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header");
- if (H5O_init(file, ohdr_size, ent, header) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to initialize dataset object header");
- }
+ /* Get a pointer to the object header itself */
+ if((oh=H5O_protect(ent))==NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header");
- /*
- * Retrieve properties of fill value and others. Copy them into new fill
- * value struct. Convert the fill value to the dataset type and write
- * the message
- */
- if (H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
+ /* Point at dataset's copy, to cache it for later */
+ fill_prop=&dset->fill;
+ fill_time=dset->fill_time;
- if (H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+ /* Check if dataset has non-default creation property list */
+ if(dset->dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ /*
+ * Retrieve properties of fill value and others. Copy them into new fill
+ * value struct. Convert the fill value to the dataset type and write
+ * the message
+ */
+ if (H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+ dset->fill_time=fill_time; /* Cache this for later */
- if (H5P_fill_value_defined(plist, &fill_status) < 0)
+ if(fill_time==H5D_FILL_TIME_NEVER && H5T_detect_class(type, H5T_VLEN))
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Dataset doesn't support VL datatype when fill value is not defined");
+
+ /* Get the fill value information from the property list */
+ if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
+ } /* end if */
+
+ if (H5P_is_fill_value_defined(fill_prop, &fill_status) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
if (fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) {
- if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
-
- if (H5O_copy(H5O_FILL, &fill_prop, &fill) == NULL)
+ if (H5O_copy(H5O_FILL, fill_prop, &fill) == NULL)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to copy fill value");
- if (fill_prop.buf && fill_prop.size > 0 && H5O_fill_convert(&fill, type) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to convert fill value to dataset type");
+ if (fill_prop->buf && fill_prop->size > 0 && H5O_fill_convert(&fill, type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert fill value to dataset type");
fill.fill_defined = TRUE;
} else if (fill_status == H5D_FILL_VALUE_UNDEFINED) {
@@ -1544,8 +1581,7 @@ H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
fill.type = fill.buf = NULL;
fill.fill_defined = FALSE;
} else {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
- "unable to determine if fill value is defined");
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to determine if fill value is defined");
}
fill.alloc_time = alloc_time;
@@ -1555,79 +1591,51 @@ H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to create dataset");
/* Write new fill value message */
- if (H5O_modify(ent, H5O_FILL_NEW, 0, H5O_FLAG_CONSTANT, &fill) < 0)
+ if (H5O_append(file, oh, H5O_FILL_NEW, H5O_FLAG_CONSTANT, &fill) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value header message");
- H5O_reset(H5O_FILL, &fill_prop);
- if (fill.buf && H5O_copy(H5O_FILL, &fill, &fill_prop) == NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL,"unable to copy fill value");
+ /* If there is valid information for the old fill value struct, update it */
+ if (fill.buf) {
+ /* Clear any previous values */
+ H5O_reset(H5O_FILL, fill_prop);
- H5O_reset(H5O_FILL_NEW, &fill);
+ /* Copy new fill value information to old fill value struct */
+ if(H5O_copy(H5O_FILL, &fill, fill_prop) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL,"unable to copy fill value");
- /* Write old fill value */
- if (fill_prop.buf && H5O_modify(ent, H5O_FILL, 0, H5O_FLAG_CONSTANT, &fill_prop) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update fill value header message");
+ /* Write old fill value */
+ if (fill_prop->buf && H5O_append(file, oh, H5O_FILL, H5O_FLAG_CONSTANT, fill_prop) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value header message");
- if (H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
+ /* Update dataset creation property */
+ if (H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
+ } /* end if */
/* Update the type and space header messages */
- if (H5O_modify(ent, H5O_DTYPE, 0, H5O_FLAG_CONSTANT | H5O_FLAG_SHARED, type) < 0 ||
- H5S_modify(ent, space) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update type or space header messages");
+ if (H5O_append(file, oh, H5O_DTYPE, H5O_FLAG_CONSTANT | H5O_FLAG_SHARED, type) < 0 ||
+ H5S_append(file, oh, space) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update type or space header messages");
- /* Update the filters message */
- if (H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve pipeline filter");
-
- if (dcpl_pline.nfilters > 0 &&
- H5O_modify(ent, H5O_PLINE, 0, H5O_FLAG_CONSTANT, &dcpl_pline) < 0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message");
-
- /* Add a modification time message. */
- if (H5O_touch(ent, TRUE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update modification time message");
-
- /* Give the dataset a name */
- if (H5G_insert(loc, name, ent) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to name dataset");
+ /* Update the filters message, if this is a chunked dataset */
+ if(layout->type==H5D_CHUNKED) {
+ H5O_pline_t pline; /* Chunked data I/O pipeline info */
-done:
- FUNC_LEAVE(ret_value);
-}
+ if (H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve pipeline filter");
-
-/*-------------------------------------------------------------------------
- * Function: H5D_update_external_storage_cache
- *
- * Purpose: Update the external cache if the dataset uses external
- * files.
- *
- * This code was originally found at the end of H5D_create()
- * but was placed here for general use.
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Errors:
- *
- * Programmer: Bill Wendling
- * Thursday, October 31, 2002
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
- H5O_efl_t *efl, H5O_layout_t *layout)
-{
- herr_t ret_value = SUCCEED;
+ if (pline.nfilters > 0 &&
+ H5O_append(file, oh, H5O_PLINE, H5O_FLAG_CONSTANT, &pline) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message");
+ } /* end if */
- FUNC_ENTER_NOAPI(H5D_update_external_storage_cache, FAIL);
+ /*
+ * Allocate storage if space allocate time is early; otherwise delay
+ * allocation until later.
+ */
+ if (alloc_time == H5D_ALLOC_TIME_EARLY)
+ if (H5D_alloc_storage(file, dset, H5D_ALLOC_CREATE, FALSE, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
/* Update external storage message */
if (efl->nused > 0) {
@@ -1639,13 +1647,11 @@ H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
if (H5HL_create(file, heap_size, &efl->heap_addr/*out*/) < 0 ||
H5HL_insert(file, efl->heap_addr, 1, "") == (size_t)(-1))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to create external file list name heap");
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create external file list name heap");
for (i = 0; i < efl->nused; ++i) {
size_t offset = H5HL_insert(file, efl->heap_addr,
- HDstrlen(efl->slot[i].name) + 1,
- efl->slot[i].name);
+ HDstrlen(efl->slot[i].name) + 1, efl->slot[i].name);
assert(0 == efl->slot[i].name_offset);
@@ -1655,16 +1661,26 @@ H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
efl->slot[i].name_offset = offset;
}
- if (H5O_modify(ent, H5O_EFL, 0, H5O_FLAG_CONSTANT, efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update external file list message");
+ if (H5O_append(file, oh, H5O_EFL, H5O_FLAG_CONSTANT, efl) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update external file list message");
}
/* Update layout message */
- if (H5D_COMPACT != layout->type && H5O_modify(ent, H5O_LAYOUT, 0, 0, layout) < 0)
+ /* (Don't make layout message constant yet, since space may not be allocated) */
+ /* Note: this is relying on H5D_alloc_storage not calling H5O_modify during dataset creation */
+ if (H5D_COMPACT != layout->type && H5O_append(file, oh, H5O_LAYOUT, 0, layout) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout");
+ /* Add a modification time message. */
+ if (H5O_touch_oh(file, oh, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message");
+
done:
+ /* Release pointer to object header itself */
+ if(ent!=NULL && oh!=NULL)
+ if(H5O_unprotect(ent,oh)<0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header");
+
FUNC_LEAVE(ret_value);
}
@@ -1726,7 +1742,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t *
+static H5D_t *
H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
const H5S_t *space, hid_t dcpl_id)
{
@@ -1736,16 +1752,10 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
hsize_t comp_data_size;
unsigned u;
hsize_t max_dim[H5O_LAYOUT_NDIMS]={0};
- H5O_efl_t efl;
- H5F_t *f = NULL;
- H5O_pline_t dcpl_pline;
- H5D_layout_t dcpl_layout;
+ H5F_t *file;
int chunk_ndims = 0;
hsize_t chunk_size[32]={0};
- H5D_alloc_time_t alloc_time;
- H5D_fill_time_t fill_time;
- H5P_genplist_t *plist; /* Property list */
- H5P_genplist_t *new_plist; /* New Property list */
+ H5P_genplist_t *new_plist=NULL; /* New Property list */
FUNC_ENTER_NOAPI(H5D_create, NULL);
@@ -1755,97 +1765,105 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
assert (type);
assert (space);
- /* Get property list object */
- if (NULL == (plist = H5P_object_verify(dcpl_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
-
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter");
- if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
- if(dcpl_pline.nfilters > 0 && H5D_CHUNKED != dcpl_layout)
- HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
-
- /* Check if the alloc_time is the default and set it accordingly */
- if(alloc_time==H5D_ALLOC_TIME_DEFAULT) {
- switch(dcpl_layout) {
- case H5D_COMPACT:
- alloc_time=H5D_ALLOC_TIME_EARLY;
- break;
-
- case H5D_CONTIGUOUS:
- alloc_time=H5D_ALLOC_TIME_LATE;
- break;
-
- case H5D_CHUNKED:
- alloc_time=H5D_ALLOC_TIME_INCR;
- break;
-
- default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
- } /* end switch */
- } /* end if */
-
- /* Don't allow compact datasets to allocate space later */
- if(dcpl_layout==H5D_COMPACT && alloc_time!=H5D_ALLOC_TIME_EARLY)
- HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset doesn't support late space allocation");
-
- /* What file is the dataset being added to? */
- if (NULL==(f=H5G_insertion_file(loc, name)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to locate insertion point");
-
- /* If MPIO or MPIPOSIX is used, no filter support yet. */
- if((IS_H5FD_MPIO(f) || IS_H5FD_MPIPOSIX(f)) && dcpl_pline.nfilters > 0)
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel I/O does not support filters yet");
-
- /* Check if this dataset is going into a parallel file and set space allocation time */
- if(IS_H5FD_MPIO(f) || IS_H5FD_MPIPOSIX(f))
- alloc_time=H5D_ALLOC_TIME_EARLY;
-
- if(H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill time");
-
- if(fill_time==H5D_FILL_TIME_NEVER && H5T_detect_class(type, H5T_VLEN))
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Dataset doesn't support VL datatype when fill value is not defined");
-
- /* Initialize the dataset object */
- if(NULL == (new_dset = H5D_new(dcpl_id)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
/* Check if the datatype is "sensible" for use in a dataset */
if(H5T_is_sensible(type)!=TRUE)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible");
+ /* Initialize the dataset object */
+ if(NULL == (new_dset = H5D_new(dcpl_id,TRUE)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
/* Copy datatype for dataset */
if((new_dset->type = H5T_copy(type, H5T_COPY_ALL))==NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy datatype");
+ /* What file is the dataset being added to? */
+ if (NULL==(file=H5G_insertion_file(loc, name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to locate insertion point");
+
/* Mark any VL datatypes as being on disk now */
- if (H5T_vlen_mark(new_dset->type, f, H5T_VLEN_DISK)<0)
+ if (H5T_vlen_mark(new_dset->type, file, H5T_VLEN_DISK)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
- /* Get new dataset's property list object */
- if (NULL == (new_plist = H5I_object(new_dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
+ /* Copy dataspace for dataset */
+ if((new_dset->space = H5S_copy(space))==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy dataspace");
+
+ /* Set the dataset's dataspace to 'all' selection */
+ if(H5S_select_all(new_dset->space,1)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection");
+
+ /* Check if the dataset has a non-default DCPL & get important values, if so */
+ if(new_dset->dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ H5D_layout_t dcpl_layout; /* Dataset's layout information */
+ H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */
+ H5D_alloc_time_t alloc_time; /* Dataset's allocation time */
+
+ /* Get new dataset's property list object */
+ if (NULL == (new_plist = H5I_object(new_dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
+
+ if(H5P_get(new_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter");
+ if(H5P_get(new_plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ if(dcpl_pline.nfilters > 0 && H5D_CHUNKED != dcpl_layout)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout");
+ if(H5P_get(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
+
+ /* Check if the alloc_time is the default and set it accordingly */
+ if(alloc_time==H5D_ALLOC_TIME_DEFAULT) {
+ switch(dcpl_layout) {
+ case H5D_COMPACT:
+ alloc_time=H5D_ALLOC_TIME_EARLY;
+ break;
+
+ case H5D_CONTIGUOUS:
+ alloc_time=H5D_ALLOC_TIME_LATE;
+ break;
+
+ case H5D_CHUNKED:
+ alloc_time=H5D_ALLOC_TIME_INCR;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
+ } /* end switch */
+ } /* end if */
- /* Set the alloc_time for the dataset, in case the default was used */
- if(H5P_set(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set allocation time");
+ /* Don't allow compact datasets to allocate space later */
+ if(dcpl_layout==H5D_COMPACT && alloc_time!=H5D_ALLOC_TIME_EARLY)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset doesn't support late space allocation");
- if(H5P_get(new_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ /* Set the alloc_time for the dataset, in case the default was used */
+ new_dset->alloc_time=alloc_time;
+
+ /* If MPIO or MPIPOSIX is used, no filter support yet. */
+ if((IS_H5FD_MPIO(file) || IS_H5FD_MPIPOSIX(file)) && dcpl_pline.nfilters > 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel I/O does not support filters yet");
+
+ /* Chunked datasets are non-default, so retrieve their info here */
+ if(H5P_get(new_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
- if(H5P_get(new_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list");
+ /* Get the dataset's external file list information */
+ if(H5P_get(new_plist, H5D_CRT_EXT_FILE_LIST_NAME, &new_dset->efl) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list");
- /* Total raw data size */
- if(H5P_get(new_plist, H5D_CRT_LAYOUT_NAME, &(new_dset->layout.type)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
- new_dset->layout.ndims = H5S_get_simple_extent_ndims(space) + 1;
+ /* Get the dataset's data storage method */
+ if(H5P_get(new_plist, H5D_CRT_LAYOUT_NAME, &(new_dset->layout.type)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ } /* end if */
+
+ /* Check if this dataset is going into a parallel file and set space allocation time */
+ if(IS_H5FD_MPIO(file) || IS_H5FD_MPIPOSIX(file))
+ new_dset->alloc_time=H5D_ALLOC_TIME_EARLY;
+
+ /* Set up layout information */
+ new_dset->layout.ndims = H5S_get_simple_extent_ndims(new_dset->space) + 1;
assert((unsigned)(new_dset->layout.ndims) <= NELMTS(new_dset->layout.dim));
- new_dset->layout.dim[new_dset->layout.ndims-1] = H5T_get_size(new_dset->type);
+ new_dset->layout.dim[new_dset->layout.ndims-1] = H5T_get_size(new_dset->type);
new_dset->layout.addr = HADDR_UNDEF; /* Initialize to no address */
switch (new_dset->layout.type) {
@@ -1855,15 +1873,15 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
* Also, only the slowest varying dimension of a simple data space
* can be extendible.
*/
- if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
+ if ((ndims=H5S_get_simple_extent_dims(new_dset->space, new_dset->layout.dim, max_dim))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize contiguous storage");
for (i=1; i<ndims; i++) {
if (max_dim[i]>new_dset->layout.dim[i])
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "only the first dimension can be extendible");
}
- if (efl.nused>0) {
- hsize_t max_points = H5S_get_npoints_max (space);
- hsize_t max_storage = H5O_efl_total_size (&efl);
+ if (new_dset->efl.nused>0) {
+ hsize_t max_points = H5S_get_npoints_max (new_dset->space);
+ hsize_t max_storage = H5O_efl_total_size (&new_dset->efl);
if (H5S_UNLIMITED==max_points) {
if (H5O_EFL_UNLIMITED!=max_storage)
@@ -1883,9 +1901,9 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
* Chunked storage allows any type of data space extension, so we
* don't even bother checking.
*/
- if(chunk_ndims != H5S_get_simple_extent_ndims(space))
+ if(chunk_ndims != H5S_get_simple_extent_ndims(new_dset->space))
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "dimensionality of chunks doesn't match the data space");
- if (efl.nused>0)
+ if (new_dset->efl.nused>0)
HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, NULL, "external storage not supported with chunked layout");
/*
@@ -1895,7 +1913,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
if(H5P_get(new_plist, H5D_CRT_CHUNK_SIZE_NAME, chunk_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve chunk size");
- if (H5S_get_simple_extent_dims(space, NULL, max_dim)<0)
+ if (H5S_get_simple_extent_dims(new_dset->space, NULL, max_dim)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to query maximum dimensions");
for (u=0; u<new_dset->layout.ndims-1; u++) {
if(max_dim[u] != H5S_UNLIMITED && max_dim[u] < chunk_size[u])
@@ -1917,7 +1935,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
/* Verify data size is smaller than maximum header message size
* (64KB) minus other layout message fields.
*/
- comp_data_size=H5O_MAX_SIZE-H5O_layout_meta_size(f, &(new_dset->layout));
+ comp_data_size=H5O_MAX_SIZE-H5O_layout_meta_size(file, &(new_dset->layout));
if(new_dset->layout.size > comp_data_size)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "compact dataset size is bigger than header message maximum size");
if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
@@ -1931,38 +1949,32 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
} /* end switch */
/*
- * Update the entry cache. That is, create and add a new
- * "H5G_entry_t" object to the group this dataset is being initially
- * created in.
+ * Update the dataset's entry info.
*/
- if (H5D_update_entry_cache(f, &new_dset->ent, loc, name, space, new_plist,
- &new_dset->layout, new_dset->type, TRUE, (haddr_t)0) != SUCCEED)
+ if (H5D_update_entry_info(file, new_dset, new_plist) != SUCCEED)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the metadata cache");
- /*
- * Allocate storage if space allocate time is early; otherwise delay
- * allocation until later.
+ /*
+ * Give the dataset a name. That is, create and add a new
+ * "H5G_entry_t" object to the group this dataset is being initially
+ * created in.
*/
- if (H5P_get(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
-
- if (alloc_time == H5D_ALLOC_TIME_EARLY)
- if (H5D_alloc_storage(f, new_dset, H5D_ALLOC_CREATE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
-
- /* Update the external storage cache if this is an external object */
- if (H5D_update_external_storage_cache(f, &new_dset->ent, &efl, &new_dset->layout) != SUCCEED)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the external metadata cache");
+ if (H5G_insert(loc, name, &new_dset->ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to name dataset");
/* Success */
ret_value = new_dset;
done:
if (!ret_value && new_dset) {
+ if (new_dset->space)
+ H5S_close(new_dset->space);
if (new_dset->type)
H5T_close(new_dset->type);
if (H5F_addr_defined(new_dset->ent.header))
H5O_close(&(new_dset->ent));
+ if(new_dset->dcpl_id!=0)
+ H5I_dec_ref(new_dset->dcpl_id);
new_dset->ent.file = NULL;
H5FL_FREE(H5D_t,new_dset);
}
@@ -2024,53 +2036,59 @@ done:
*-------------------------------------------------------------------------
* Function: H5D_open
*
- * Purpose: Finds a dataset named NAME in file F and builds a descriptor
- * for it, opening it for access.
- *
- * Return: Success: Pointer to a new dataset descriptor.
+ * Purpose: Checks if dataset is already open, or opens a dataset for
+ * access.
*
- * Failure: NULL
+ * Return: Success: Dataset ID
+ * Failure: FAIL
*
* Errors:
*
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
+ * Programmer: Quincey Koziol
+ * Friday, December 20, 2002
*
* Modifications:
- * Robb Matzke, 9 Jun 1998
- * The data space message is no longer cached in the dataset struct.
- *
- * Quincey Koziol, 12 Oct 1998
- * Moved guts of function into H5D_open_oid
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
*
*-------------------------------------------------------------------------
*/
-H5D_t *
-H5D_open(H5G_entry_t *loc, const char *name)
+hid_t
+H5D_open(H5G_entry_t *ent)
{
- H5D_t *dataset = NULL; /*the dataset which was found */
- H5D_t *ret_value = NULL; /*return value */
- H5G_entry_t ent; /*dataset symbol table entry */
+ hid_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_open, NULL);
/* check args */
- assert (loc);
- assert (name && *name);
+ assert (ent);
- /* Find the dataset object */
- if (H5G_find(loc, name, NULL, &ent) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found");
+ /* Check if dataset was already open */
+ if((ret_value=H5FO_opened(ent->file,ent->header))<0) {
+ H5D_t *dataset; /*the dataset which was found */
- /* Open the dataset object */
- if ((dataset=H5D_open_oid(&ent)) ==NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found");
+ H5E_clear();
- /* Success */
- ret_value = dataset;
+ /* Open the dataset object */
+ if ((dataset=H5D_open_oid(ent)) ==NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+
+ /* Create an atom for the dataset */
+ if ((ret_value = H5I_register(H5I_DATASET, dataset)) < 0) {
+ H5D_close(dataset);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset");
+ } /* end if */
+
+ /* Add the dataset to the list of opened objects in the file */
+ if(H5FO_insert(ent->file,ent->header,ret_value)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert dataset into list of open objects");
+ } /* end if */
+ else {
+ /* Dataset is already open, increment the reference count on the ID */
+ if(H5I_inc_ref(ret_value)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, FAIL, "Can't increment dataset ID");
+
+ /* Release the dataset entry we located earlier */
+ H5G_free_ent_name(ent);
+ } /* end else */
done:
FUNC_LEAVE(ret_value);
@@ -2104,15 +2122,14 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t *
+static H5D_t *
H5D_open_oid(H5G_entry_t *ent)
{
H5D_t *dataset = NULL; /*new dataset struct */
H5D_t *ret_value = NULL; /*return value */
H5O_fill_new_t fill = {NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_FILL_TIME_ALLOC, TRUE};
- H5O_fill_t fill_prop = {NULL, 0, NULL};
+ H5O_fill_t *fill_prop; /* Pointer to dataset's fill value area */
H5O_pline_t pline; /* I/O pipeline information */
- H5O_efl_t efl; /* External file information */
H5D_layout_t layout; /* Dataset layout */
int chunk_ndims;
H5P_genplist_t *plist; /* Property list */
@@ -2123,7 +2140,7 @@ H5D_open_oid(H5G_entry_t *ent)
assert (ent);
/* Allocate the dataset structure */
- if(NULL==(dataset = H5D_new(H5P_DEFAULT)))
+ if(NULL==(dataset = H5D_new(H5P_DATASET_CREATE_DEFAULT,FALSE)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Shallow copy (take ownership) of the group entry object */
@@ -2137,12 +2154,14 @@ H5D_open_oid(H5G_entry_t *ent)
if (NULL==(dataset->type=H5O_read(&(dataset->ent), H5O_DTYPE, 0, NULL)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load type info from dataset header");
+ if (NULL==(dataset->space=H5S_read(&(dataset->ent))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load space info from dataset header");
+
/* Get dataset creation property list object */
if (NULL == (plist = H5I_object(dataset->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
/* Get the optional filters message */
- HDmemset(&pline,0,sizeof(H5O_pline_t));
if(NULL == H5O_read(&(dataset->ent), H5O_PLINE, 0, &pline)) {
H5E_clear();
HDmemset(&pline, 0, sizeof(pline));
@@ -2195,10 +2214,13 @@ H5D_open_oid(H5G_entry_t *ent)
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
} /* end switch */
+ /* Point at dataset's copy, to cache it for later */
+ fill_prop=&dataset->fill;
+
/* Retrieve & release the previous fill-value settings */
- if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
+ if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't get fill value");
- H5O_reset(H5O_FILL, &fill_prop);
+ H5O_reset(H5O_FILL, fill_prop);
/* Get the new fill value message */
if(NULL == H5O_read(&(dataset->ent), H5O_FILL_NEW, 0, &fill)) {
@@ -2224,35 +2246,37 @@ H5D_open_oid(H5G_entry_t *ent)
} /* end switch */
} /* end if */
if(fill.fill_defined) {
- if(NULL==H5O_copy(H5O_FILL, &fill, &fill_prop))
+ if(NULL==H5O_copy(H5O_FILL, &fill, fill_prop))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't copy fill value");
} else {
/* For compatibility with v1.4. Retrieve the old fill value message.
* If size is 0, make it -1 for undefined. */
- if(NULL == H5O_read(&(dataset->ent), H5O_FILL, 0, &fill_prop)) {
+ if(NULL == H5O_read(&(dataset->ent), H5O_FILL, 0, fill_prop)) {
H5E_clear();
- HDmemset(&fill_prop, 0, sizeof(fill_prop));
+ HDmemset(fill_prop, 0, sizeof(H5O_fill_t));
}
- if(fill_prop.size == 0) {
- fill_prop.type = fill_prop.buf = NULL;
- fill_prop.size = (size_t)-1;
+ if(fill_prop->size == 0) {
+ fill_prop->type = fill_prop->buf = NULL;
+ fill_prop->size = (size_t)-1;
}
} /* end else */
- /* Set fill value properties */
- if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
+ /* Set revised fill value properties */
+ if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value");
+ dataset->alloc_time=fill.alloc_time; /* Cache this for later */
if(H5P_set(plist, H5D_CRT_ALLOC_TIME_NAME, &fill.alloc_time) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value");
+ dataset->fill_time=fill.fill_time; /* Cache this for later */
if(H5P_set(plist, H5D_CRT_FILL_TIME_NAME, &fill.fill_time) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value");
/* Get the external file list message, which might not exist. Space is
* also undefined when space allocate time is H5D_ALLOC_TIME_LATE. */
if( !H5F_addr_defined(dataset->layout.addr)) {
- HDmemset(&efl,0,sizeof(H5O_efl_t));
- if(NULL != H5O_read(&(dataset->ent), H5O_EFL, 0, &efl))
- if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
+ HDmemset(&dataset->efl,0,sizeof(H5O_efl_t));
+ if(NULL != H5O_read(&(dataset->ent), H5O_EFL, 0, &dataset->efl))
+ if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->efl) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set external file list");
}
/*
@@ -2263,7 +2287,7 @@ H5D_open_oid(H5G_entry_t *ent)
if ((H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR)
&& (dataset->layout.type!=H5D_COMPACT && dataset->layout.addr==HADDR_UNDEF)
&& (IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file))) {
- if (H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_OPEN)<0)
+ if (H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_OPEN, TRUE, FALSE)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize file storage");
}
@@ -2274,6 +2298,8 @@ done:
if (ret_value==NULL && dataset) {
if (H5F_addr_defined(dataset->ent.header))
H5O_close(&(dataset->ent));
+ if (dataset->space)
+ H5S_close(dataset->space);
if (dataset->type)
H5T_close(dataset->type);
dataset->ent.file = NULL;
@@ -2317,19 +2343,23 @@ H5D_close(H5D_t *dataset)
assert(dataset && dataset->ent.file);
/*
- * Release data type and creation property list -- there isn't much we
- * can do if one of these fails, so we just continue.
+ * Release datatype, dataspace and creation property list -- there isn't
+ * much we can do if one of these fails, so we just continue.
*/
- free_failed = (H5T_close(dataset->type) < 0 ||
+ free_failed=(H5T_close(dataset->type)<0 || H5S_close(dataset->space)<0 ||
H5I_dec_ref(dataset->dcpl_id) < 0);
/* Update header message of layout for compact dataset. */
if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty) {
- if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
+ if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, 1, &(dataset->layout))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
dataset->layout.dirty = FALSE;
} /* end if */
+ /* Remove the dataset from the list of opened objects in the file */
+ if(H5FO_delete(dataset->ent.file,dataset->ent.header)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't remove dataset from list of open objects");
+
/* Close the dataset object */
H5O_close(&(dataset->ent));
@@ -2400,7 +2430,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/)
{
@@ -2413,8 +2443,11 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
H5S_conv_t *sconv=NULL; /*space conversion funcs*/
H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
herr_t ret_value = SUCCEED; /*return value */
herr_t status; /*function return status*/
size_t src_type_size; /*size of source type */
@@ -2422,7 +2455,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
size_t target_size; /*desired buffer size */
hsize_t request_nelmts; /*requested strip mine */
H5T_bkg_t need_bkg; /*type of background buf*/
- H5S_t *free_this_space=NULL; /*data space to free */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_dxpl_t *dx = NULL;
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
@@ -2432,10 +2464,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#ifdef H5S_DEBUG
H5_timer_t timer;
#endif
- H5O_efl_t efl; /* External File List info */
- H5O_fill_t fill; /* Fill value info */
- H5D_fill_time_t fill_time; /* When to write the fill values */
- H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */
H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
unsigned sconv_flags=0; /* Flags for the space conversion */
@@ -2447,24 +2475,16 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(mem_type);
assert(buf);
- /* Initialize these before any errors can occur */
- HDmemset(&mem_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&bkg_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&file_iter,0,sizeof(H5S_sel_iter_t));
-
/* Get the dataset's creation property list */
if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (dx_plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if (!file_space) {
- if (NULL==(free_this_space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
- file_space = free_this_space;
- } /* end if */
+ if (!file_space)
+ file_space = dataset->space;
if (!mem_space)
mem_space = file_space;
nelmts = (*mem_space->select.get_npoints)(mem_space);
@@ -2500,15 +2520,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
/* Retrieve dataset properties */
- if(H5P_fill_value_defined(dc_plist, &fill_status)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
- if((fill_status==H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED)
- && H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill value");
- if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill time");
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
+ /* <none needed in the general case> */
/* If space hasn't been allocated and not using external storage,
* return fill value to buffer if fill time is upon allocation, or
@@ -2516,8 +2528,20 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* fill time is NEVER, there is no way to tell whether part of data
* has been overwritten. So just proceed in reading.
*/
- if(nelmts > 0 && efl.nused==0 && dataset->layout.type!=H5D_COMPACT
+ if(nelmts > 0 && dataset->efl.nused==0 && dataset->layout.type!=H5D_COMPACT
&& dataset->layout.addr==HADDR_UNDEF) {
+ H5O_fill_t fill; /* Fill value info */
+ H5D_fill_time_t fill_time; /* When to write the fill values */
+ H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
+
+ /* Retrieve dataset's fill-value properties */
+ if(H5P_fill_value_defined(dc_plist, &fill_status)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
+ if((fill_status==H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED)
+ && H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill value");
+ if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill time");
/* Should be impossible, but check anyway... */
if(fill_status == H5D_FILL_VALUE_UNDEFINED && fill_time == H5D_FILL_TIME_ALLOC)
@@ -2581,10 +2605,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
/* Sanity check dataset, then read it */
- assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused>0 || dataset->layout.type==H5D_COMPACT);
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 || dataset->layout.type==H5D_COMPACT);
status = (sconv->read)(dataset->ent.file, &(dataset->layout),
- dc_plist, H5T_get_size(dataset->type),
- file_space, mem_space, dxpl_id, buf/*out*/);
+ dc_plist, &(dataset->efl), H5T_get_size(dataset->type),
+ file_space, mem_space, dxpl_id, buf/*out*/);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[1].read_timer), &timer);
sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->type);
@@ -2636,10 +2660,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
/* Figure out the strip mine size. */
if ((*file_space->select.iter_init)(file_space, src_type_size, &file_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
if ((*mem_space->select.iter_init)(mem_space, dst_type_size, &mem_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
if ((*mem_space->select.iter_init)(mem_space, dst_type_size, &bkg_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
/* Sanity check elements in temporary buffer */
if (request_nelmts<=0)
@@ -2662,13 +2689,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
} /* end else */
if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_ALLOC(type_conv,target_size,0))==NULL)
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
/* Allocate background buffer */
H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
- if((bkg_buf=H5FL_BLK_ALLOC(type_conv,(size_t)(request_nelmts*dst_type_size),0))==NULL)
+ if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
} /* end if */
@@ -2687,9 +2714,9 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
/* Sanity check that space is allocated, then read data from it */
- assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused > 0);
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused > 0);
n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
- dc_plist, src_type_size, file_space,
+ dc_plist, &(dataset->efl), src_type_size, file_space,
&file_iter, smine_nelmts, dxpl_id, tconv_buf/*out*/);
#ifdef H5S_DEBUG
@@ -2753,9 +2780,12 @@ done:
} /* end if */
#endif /*H5_HAVE_PARALLEL*/
/* Release selection iterators */
- (*file_space->select.iter_release)(&file_iter);
- (*mem_space->select.iter_release)(&mem_iter);
- (*mem_space->select.iter_release)(&bkg_iter);
+ if(file_iter_init)
+ (*file_space->select.iter_release)(&file_iter);
+ if(mem_iter_init)
+ (*mem_space->select.iter_release)(&mem_iter);
+ if(bkg_iter_init)
+ (*mem_space->select.iter_release)(&bkg_iter);
if (src_id >= 0)
H5I_dec_ref(src_id);
@@ -2766,8 +2796,6 @@ done:
H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
H5FL_BLK_FREE(type_conv,bkg_buf);
- if (free_this_space)
- H5S_close(free_this_space);
FUNC_LEAVE(ret_value);
} /* end H5D_read() */
@@ -2816,7 +2844,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
const H5S_t *file_space, hid_t dxpl_id, const void *buf)
{
@@ -2829,8 +2857,11 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
H5S_conv_t *sconv=NULL; /*space conversion funcs*/
H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
herr_t ret_value = SUCCEED; /*return value */
herr_t status; /*function return status*/
size_t src_type_size; /*size of source type */
@@ -2838,7 +2869,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
size_t target_size; /*desired buffer size */
hsize_t request_nelmts; /*requested strip mine */
H5T_bkg_t need_bkg; /*type of background buf*/
- H5S_t *free_this_space=NULL; /*data space to free */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_dxpl_t *dx = NULL;
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
@@ -2848,10 +2878,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#ifdef H5S_DEBUG
H5_timer_t timer;
#endif
- H5O_efl_t efl; /* External File List info */
- H5O_fill_t fill; /* Fill value info */
- H5D_fill_time_t fill_time; /* When to write the fill values */
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */
H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
unsigned sconv_flags=0; /* Flags for the space conversion */
@@ -2863,24 +2889,16 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(mem_type);
assert(buf);
- /* Initialize these before any errors can occur */
- HDmemset(&mem_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&bkg_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&file_iter,0,sizeof(H5S_sel_iter_t));
-
/* Get the dataset's creation property list */
if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (dx_plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if (!file_space) {
- if (NULL==(free_this_space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
- file_space = free_this_space;
- } /* end if */
+ if (!file_space)
+ file_space = dataset->space;
if (!mem_space)
mem_space = file_space;
nelmts = (*mem_space->select.get_npoints)(mem_space);
@@ -2941,20 +2959,19 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
/* Retrieve dataset properties */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve fill value");
- if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve fill time");
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
- if(H5P_get(dc_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
+ /* <none needed currently> */
/* Allocate data space and initialize it if it hasn't been. */
if(nelmts > 0 && dataset->layout.type!=H5D_COMPACT &&
dataset->layout.addr==HADDR_UNDEF) {
+ hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
+
+ /* Get the number of elements in file dataset's dataspace */
+ if((file_nelmts=H5S_get_simple_extent_npoints(file_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset");
+
/* Allocate storage */
- if(H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_WRITE)<0)
+ if(H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_WRITE, TRUE, (hbool_t)((hsize_t)file_nelmts==nelmts ? TRUE : FALSE))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
} /* end if */
@@ -3005,8 +3022,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
status = (sconv->write)(dataset->ent.file, &(dataset->layout),
- dc_plist, H5T_get_size(dataset->type),
- file_space, mem_space, dxpl_id, buf);
+ dc_plist, &(dataset->efl), H5T_get_size(dataset->type),
+ file_space, mem_space, dxpl_id, buf);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].write_timer), &timer);
sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type);
@@ -3061,10 +3078,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
/* Figure out the strip mine size. */
if ((*file_space->select.iter_init)(file_space, dst_type_size, &file_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
if ((*mem_space->select.iter_init)(mem_space, src_type_size, &mem_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
if ((*file_space->select.iter_init)(file_space, dst_type_size, &bkg_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
/*
* Get a temporary buffer for type conversion unless the app has already
@@ -3087,13 +3107,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
} /* end else */
if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_ALLOC(type_conv,target_size,0))==NULL)
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
/* Allocate background buffer */
H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
- if((bkg_buf=H5FL_BLK_ALLOC(type_conv,(size_t)(request_nelmts*dst_type_size),1))==NULL)
+ if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
} /* end if */
@@ -3126,9 +3146,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
- dc_plist, dst_type_size, file_space,
- &bkg_iter, smine_nelmts, dxpl_id,
- bkg_buf/*out*/);
+ dc_plist, &(dataset->efl), dst_type_size, file_space,
+ &bkg_iter, smine_nelmts, dxpl_id, bkg_buf/*out*/);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].bkg_timer), &timer);
@@ -3152,9 +3171,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
status = H5S_select_fscat(dataset->ent.file, &(dataset->layout),
- dc_plist, dst_type_size,
- file_space, &file_iter, smine_nelmts,
- dxpl_id, tconv_buf);
+ dc_plist, &(dataset->efl), dst_type_size, file_space, &file_iter,
+ smine_nelmts, dxpl_id, tconv_buf);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].scat_timer), &timer);
@@ -3186,9 +3204,12 @@ done:
} /* end if */
#endif /*H5_HAVE_PARALLEL*/
/* Release selection iterators */
- (*file_space->select.iter_release)(&file_iter);
- (*mem_space->select.iter_release)(&mem_iter);
- (*file_space->select.iter_release)(&bkg_iter);
+ if(file_iter_init)
+ (*file_space->select.iter_release)(&file_iter);
+ if(mem_iter_init)
+ (*mem_space->select.iter_release)(&mem_iter);
+ if(bkg_iter_init)
+ (*file_space->select.iter_release)(&bkg_iter);
if (src_id >= 0)
H5I_dec_ref(src_id);
@@ -3199,8 +3220,6 @@ done:
H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
H5FL_BLK_FREE(type_conv,bkg_buf);
- if (free_this_space)
- H5S_close(free_this_space);
FUNC_LEAVE(ret_value);
} /* end H5D_write() */
@@ -3230,8 +3249,6 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
{
int changed; /* Flag to indicate that the dataspace was successfully extended */
H5S_t *space = NULL; /* Dataset's dataspace */
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
- H5P_genplist_t *plist; /* Property list */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_extend, FAIL);
@@ -3240,12 +3257,6 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
assert (dataset);
assert (size);
- /* Get the dataset creation property list */
- if (NULL == (plist = H5I_object(dataset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
-
/*
* NOTE: Restrictions on extensions were checked when the dataset was
* created. All extensions are allowed here since none should be
@@ -3253,24 +3264,22 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
*/
/* Increase the size of the data space */
- if (NULL==(space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space info from dataset header");
+ space=dataset->space;
if ((changed=H5S_extend (space, size))<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to increase size of data space");
if (changed>0){
/* Save the new dataspace in the file if necessary */
- if (H5S_modify (&(dataset->ent), space)<0)
+ if (H5S_modify (&(dataset->ent), space, TRUE)<0)
HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace");
/* Allocate space for the new parts of the dataset, if appropriate */
- if(alloc_time==H5D_ALLOC_TIME_EARLY)
- if (H5D_alloc_storage(dataset->ent.file, dataset, H5D_ALLOC_EXTEND)<0)
+ if(dataset->alloc_time==H5D_ALLOC_TIME_EARLY)
+ if (H5D_alloc_storage(dataset->ent.file, dataset, H5D_ALLOC_EXTEND, TRUE, FALSE)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value");
} /* end if */
done:
- H5S_close(space);
FUNC_LEAVE (ret_value);
}
@@ -3347,7 +3356,7 @@ H5D_typeof (H5D_t *dset)
*
*-------------------------------------------------------------------------
*/
-H5F_t *
+static H5F_t *
H5D_get_file (const H5D_t *dset)
{
/* Use FUNC_ENTER_NOINIT here to avoid performance issues */
@@ -3379,12 +3388,9 @@ H5D_get_file (const H5D_t *dset)
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
+H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc,
+ hbool_t update_time, hbool_t full_overwrite)
{
- H5P_genplist_t *plist; /* Dataset's creation property list */
- H5O_efl_t efl; /* External File List info */
- H5D_fill_time_t fill_time; /* When to write fill values */
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
struct H5O_layout_t *layout; /* The dataset's layout information */
hsize_t nbytes; /* The number of bytes in the dataset */
unsigned space_allocated=0; /* Flag to indicate that space was allocated */
@@ -3397,23 +3403,11 @@ H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
assert (f);
assert (dset);
- /* Get external file list properties */
- if (NULL == (plist = H5I_object(dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
-
/* If the data is stored in external files, don't set an address for the layout
* We assume that external storage is already
* allocated by the caller, or at least will be before I/O is performed.
*/
- if(efl.nused==0) {
- /* Get properties needed */
- if(H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
-
+ if(dset->efl.nused==0) {
/* Get a pointer to the dataset's layout information */
layout=&(dset->layout);
@@ -3441,6 +3435,11 @@ H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
/* Indicate that we allocated space */
space_allocated=1;
} /* end if */
+
+ /* If MPIO or MPIPOSIX is used, indicate that space was allocated, so the B-tree gets expanded */
+ if(IS_H5FD_MPIO(f) || IS_H5FD_MPIPOSIX(f))
+ space_allocated=1;
+
break;
case H5D_COMPACT:
@@ -3462,19 +3461,22 @@ H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
HGOTO_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
} /* end switch */
- /* If we are filling the dataset on allocation, do that now */
- if(fill_time==H5D_FILL_TIME_ALLOC
- && !(alloc_time==H5D_ALLOC_TIME_INCR && time_alloc==H5D_ALLOC_WRITE)) {
- if(H5D_init_storage(dset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value");
- } /* end if */
+ /* Check if we actually allocated space before performing other actions */
+ if(space_allocated) {
+ /* If we are filling the dataset on allocation, do that now */
+ if(dset->fill_time==H5D_FILL_TIME_ALLOC
+ && !(dset->alloc_time==H5D_ALLOC_TIME_INCR && time_alloc==H5D_ALLOC_WRITE)) {
+ if(H5D_init_storage(dset, full_overwrite) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value");
+ } /* end if */
- /* Also update header message for layout with new address
- * (this is only for forward compatibility).
- */
- if(space_allocated && time_alloc!=H5D_ALLOC_CREATE)
- if (H5O_modify (&(dset->ent), H5O_LAYOUT, 0, H5O_FLAG_CONSTANT, &(dset->layout)) < 0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
+ /* Also update header message for layout with new address
+ * (this is only for forward compatibility).
+ */
+ if(time_alloc!=H5D_ALLOC_CREATE)
+ if (H5O_modify (&(dset->ent), H5O_LAYOUT, 0, H5O_FLAG_CONSTANT, update_time, &(dset->layout)) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
+ } /* end if */
} /* end if */
done:
@@ -3504,13 +3506,11 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_init_storage(H5D_t *dset)
+H5D_init_storage(H5D_t *dset, hbool_t full_overwrite)
{
hssize_t snpoints; /* Number of points in space (for error checking) */
size_t npoints; /* Number of points in space */
- H5S_t *space = NULL; /* Dataset's dataspace */
- H5O_fill_t fill; /* Fill value information */
- H5O_efl_t efl; /* External File List info */
+ H5S_t *space; /* Dataset's dataspace */
H5P_genplist_t *plist; /* Property list */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3518,17 +3518,8 @@ H5D_init_storage(H5D_t *dset)
assert(dset);
- /* Get fill value, external file list, and data pipeline properties */
- if (NULL == (plist = H5I_object(dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
- if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
-
/* Get the dataset's dataspace */
- if (NULL==(space=H5S_read (&(dset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
+ space=dset->space;
/* Get the number of elements in the dataset's dataspace */
snpoints = H5S_get_simple_extent_npoints(space);
@@ -3537,19 +3528,31 @@ H5D_init_storage(H5D_t *dset)
switch (dset->layout.type) {
case H5D_COMPACT:
- /* If the fill value is defined, initialize the data buffer with it */
- if(fill.buf)
- /* Initialize the cached data buffer with the fill value */
- H5V_array_fill(dset->layout.buf, fill.buf, fill.size, npoints);
- else /* If the fill value is default, zero set data buf. */
- HDmemset(dset->layout.buf, 0, dset->layout.size);
+ /* If we will be immediately overwriting the values, don't bother to clear them */
+ if(!full_overwrite) {
+ /* If the fill value is defined, initialize the data buffer with it */
+ if(dset->fill.buf)
+ /* Initialize the cached data buffer with the fill value */
+ H5V_array_fill(dset->layout.buf, dset->fill.buf, dset->fill.size, npoints);
+ else /* If the fill value is default, zero set data buf. */
+ HDmemset(dset->layout.buf, 0, dset->layout.size);
+ } /* end if */
break;
case H5D_CONTIGUOUS:
- if (H5F_contig_fill(dset->ent.file, H5P_DATASET_XFER_DEFAULT,
- &(dset->layout), plist, space, H5T_get_size(dset->type))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
- break;
+ /* Don't write default fill values to external files */
+ /* If we will be immediately overwriting the values, don't bother to clear them */
+ if((dset->efl.nused==0 || dset->fill.buf) && !full_overwrite) {
+ /* Get dataset's creation property list */
+ if (NULL == (plist = H5I_object(dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
+ if (H5F_contig_fill(dset->ent.file, H5P_DATASET_XFER_DEFAULT,
+ &(dset->layout), plist, &(dset->efl), space,
+ &dset->fill, H5T_get_size(dset->type))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
+ } /* end if */
+ break;
case H5D_CHUNKED:
/*
@@ -3561,21 +3564,22 @@ H5D_init_storage(H5D_t *dset)
int ndims;
hsize_t dim[H5O_LAYOUT_NDIMS];
+ /* Get dataset's creation property list */
+ if (NULL == (plist = H5I_object(dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
if ((ndims=H5S_get_simple_extent_dims(space, dim, NULL))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple data space info");
dim[ndims] = dset->layout.dim[ndims];
if (H5F_istore_allocate(dset->ent.file, H5P_DATASET_XFER_DEFAULT,
- &(dset->layout), dim, plist)<0)
+ &(dset->layout), dim, plist, full_overwrite)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
} /* end if */
break;
} /* end switch */
done:
- if (space)
- H5S_close(space);
-
FUNC_LEAVE(ret_value);
}
@@ -3638,7 +3642,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-hsize_t
+static hsize_t
H5D_get_storage_size(H5D_t *dset)
{
unsigned u; /* Index variable */
@@ -3732,7 +3736,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-haddr_t
+static haddr_t
H5D_get_offset(H5D_t *dset)
{
haddr_t ret_value;
@@ -3894,9 +3898,9 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
/* Get the default dataset transfer property list if the user didn't provide one */
if (H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
-
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
/* Call H5Diterate with args, etc. */
ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim,&plist_id);
@@ -3923,7 +3927,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *
+static void *
H5D_vlen_get_buf_size_alloc(size_t size, void *info)
{
H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)info;
@@ -3970,7 +3974,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t *point, void *op_data)
{
H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)op_data;
@@ -4060,9 +4064,9 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't create dataspace");
/* Grab the temporary buffers required */
- if((vlen_bufsize.fl_tbuf=H5FL_BLK_ALLOC(vlen_fl_buf,1,0))==NULL)
+ if((vlen_bufsize.fl_tbuf=H5FL_BLK_MALLOC(vlen_fl_buf,1))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
- if((vlen_bufsize.vl_tbuf=H5FL_BLK_ALLOC(vlen_vl_buf,1,0))==NULL)
+ if((vlen_bufsize.vl_tbuf=H5FL_BLK_MALLOC(vlen_vl_buf,1))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
/* Get the pointer to the dataset transfer class */
@@ -4160,7 +4164,7 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
/* Get the maximum buffer size needed and allocate it */
buf_size=MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5FL_BLK_ALLOC(type_elem,buf_size,0)) || NULL==(bkg_buf = H5FL_BLK_ALLOC(type_elem,buf_size,1)))
+ if (NULL==(tconv_buf = H5FL_BLK_MALLOC(type_elem,buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(type_elem,buf_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Copy the user's data into the buffer for conversion */
@@ -4180,7 +4184,7 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
}
/* Perform data type conversion */
- if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, H5P_DEFAULT)<0)
+ if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, H5P_DATASET_XFER_DEFAULT)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
/* Fill the selection in the memory buffer */
@@ -4311,7 +4315,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5D_set_extent(H5D_t *dset, const hsize_t *size)
{
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Current dimension sizes */
@@ -4319,7 +4323,6 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
herr_t ret_value = SUCCEED; /* Return value */
H5S_t *space = NULL;
H5P_genplist_t *plist;
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
int u;
unsigned shrink = 0; /* Flag to indicate a dimension has shrank */
unsigned expand = 0; /* Flag to indicate a dimension has grown */
@@ -4335,8 +4338,7 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
* Get the data space
*-------------------------------------------------------------------------
*/
- if(NULL == (space = H5S_read(&(dset->ent))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space info from dset header");
+ space = dset->space;
/*-------------------------------------------------------------------------
* Check if we are shrinking or expanding any of the dimensions
@@ -4361,23 +4363,17 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
/* Don't bother updating things, unless they've changed */
if(changed) {
- /* Get the dataset creation property list */
- if(NULL == (plist = H5I_object(dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dset creation property list");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
-
/*-------------------------------------------------------------------------
* Modify the dataset storage
*-------------------------------------------------------------------------
*/
/* Save the new dataspace in the file if necessary */
- if(H5S_modify(&(dset->ent), space) < 0)
+ if(H5S_modify(&(dset->ent), space, TRUE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace");
/* Allocate space for the new parts of the dataset, if appropriate */
- if(expand && alloc_time==H5D_ALLOC_TIME_EARLY)
- if(H5D_alloc_storage(dset->ent.file, dset, H5D_ALLOC_EXTEND) < 0)
+ if(expand && dset->alloc_time==H5D_ALLOC_TIME_EARLY)
+ if(H5D_alloc_storage(dset->ent.file, dset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage");
@@ -4387,6 +4383,10 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
*-------------------------------------------------------------------------
*/
if(shrink && H5D_CHUNKED == dset->layout.type) {
+ /* Get the dataset creation property list */
+ if(NULL == (plist = H5I_object(dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dset creation property list");
+
/* Remove excess chunks */
if(H5F_istore_prune_by_extent(dset->ent.file, &dset->layout, space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to remove chunks ");
@@ -4398,8 +4398,6 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
} /* end if */
done:
- if(space)
- H5S_close(space);
FUNC_LEAVE(ret_value);
}
@@ -4449,7 +4447,7 @@ H5D_flush(H5F_t *f)
if(NULL==(dataset=H5I_object_verify(id_list[j], H5I_DATASET)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset object");
if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty)
- if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
+ if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, 1, &(dataset->layout))<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message");
dataset->layout.dirty = FALSE;
}
@@ -4459,7 +4457,7 @@ done:
if(id_list!=NULL)
H5MM_xfree(id_list);
FUNC_LEAVE(ret_value);
-}
+} /* end H5D_flush() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index fce1ba9..a63a9ce 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -36,8 +36,11 @@ static int interface_initialize_g = 0;
/* Declare a PQ free list to manage the sieve buffer information */
H5FL_BLK_DEFINE(sieve_buf);
-/* Extern the free list to manage blocks of type conversion data */
-H5FL_BLK_EXTERN(type_conv);
+/* Declare the free list to manage blocks of non-zero fill-value data */
+H5FL_BLK_DEFINE_STATIC(non_zero_fill);
+
+/* Declare the free list to manage blocks of zero fill-value data */
+H5FL_BLK_DEFINE_STATIC(zero_fill);
/*-------------------------------------------------------------------------
@@ -56,11 +59,10 @@ H5FL_BLK_EXTERN(type_conv);
*/
herr_t
H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5S_t *space,
- size_t elmt_size)
+ struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
+ const struct H5S_t *space,
+ const struct H5O_fill_t *fill, size_t elmt_size)
{
- H5O_fill_t fill; /* Fill value information */
- H5O_efl_t efl; /* External File List info */
hssize_t snpoints; /* Number of points in space (for error checking) */
size_t npoints; /* Number of points in space */
size_t ptsperbuf; /* Maximum # of points which fit in the buffer */
@@ -77,6 +79,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
unsigned blocks_written=0; /* Flag to indicate that chunk was actually written */
unsigned using_mpi=0; /* Flag to indicate that the file is being accessed with an MPI-capable file driver */
#endif /* H5_HAVE_PARALLEL */
+ int non_zero_fill_f=(-1); /* Indicate that a non-zero fill-value was used */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_contig_fill, FAIL);
@@ -91,12 +94,6 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
assert(space);
assert(elmt_size>0);
- /* Get necessary properties from dataset creation property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "can't get fill value");
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
-
#ifdef H5_HAVE_PARALLEL
/* Retrieve up MPI parameters */
if(IS_H5FD_MPIO(f)) {
@@ -136,46 +133,62 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
assert(snpoints>=0);
H5_ASSIGN_OVERFLOW(npoints,snpoints,hssize_t,size_t);
- /* Don't write default fill-values to external files */
- if(efl.nused>0 && !fill.buf)
- HGOTO_DONE(SUCCEED);
-
- /* If fill value is library default, use the element size */
- if(!fill.buf)
- fill.size=elmt_size;
+ /* If fill value is not library default, use it to set the element size */
+ if(fill->buf)
+ elmt_size=fill->size;
/*
* Fill the entire current extent with the fill value. We can do
* this quite efficiently by making sure we copy the fill value
* in relatively large pieces.
*/
- ptsperbuf = MAX(1, bufsize/fill.size);
- bufsize = ptsperbuf*fill.size;
-
- /* Allocate temporary buffer */
- if ((buf=H5FL_BLK_ALLOC(type_conv,bufsize,0))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer");
-
- /* Fill the buffer with the user's fill value */
- if(fill.buf)
- H5V_array_fill(buf, fill.buf, fill.size, ptsperbuf);
- else /* Fill the buffer with the default fill value */
- HDmemset(buf,0,bufsize);
+ ptsperbuf = MAX(1, bufsize/elmt_size);
+ bufsize = ptsperbuf*elmt_size;
+
+ /* Fill the buffer with the user's fill value */
+ if(fill->buf) {
+ /* Allocate temporary buffer */
+ if ((buf=H5FL_BLK_MALLOC(non_zero_fill,bufsize))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer");
+
+ H5V_array_fill(buf, fill->buf, elmt_size, ptsperbuf);
+
+ /* Indicate that a non-zero fill buffer was used */
+ non_zero_fill_f=1;
+ } /* end if */
+ else { /* Fill the buffer with the default fill value */
+ htri_t buf_avail;
+
+ /* Check if there is an already zeroed out buffer available */
+ buf_avail=H5FL_BLK_AVAIL(zero_fill,bufsize);
+ assert(buf_avail!=FAIL);
+
+ /* Allocate temporary buffer (zeroing it if no buffer is available) */
+ if(!buf_avail)
+ buf=H5FL_BLK_CALLOC(zero_fill,bufsize);
+ else
+ buf=H5FL_BLK_MALLOC(zero_fill,bufsize);
+ if(buf==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer");
+
+ /* Indicate that a zero fill buffer was used */
+ non_zero_fill_f=0;
+ } /* end else */
- /* Start at the beginning of the dataset */
- addr = 0;
+ /* Start at the beginning of the dataset */
+ addr = 0;
- /* Loop through writing the fill value to the dataset */
- while (npoints>0) {
- size = MIN(ptsperbuf, npoints) * fill.size;
+ /* Loop through writing the fill value to the dataset */
+ while (npoints>0) {
+ size = MIN(ptsperbuf, npoints) * elmt_size;
#ifdef H5_HAVE_PARALLEL
/* Check if this file is accessed with an MPI-capable file driver */
if(using_mpi) {
/* Round-robin write the chunks out from only one process */
if(mpi_round==mpi_rank) {
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, space,
- fill.size, size, addr, buf)<0)
+ if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
+ elmt_size, size, addr, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
} /* end if */
mpi_round=(++mpi_round)%mpi_size;
@@ -185,8 +198,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, space,
- fill.size, size, addr, buf)<0)
+ if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
+ elmt_size, size, addr, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -211,8 +224,13 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
done:
/* Free the buffer for fill values */
- if (buf)
- H5FL_BLK_FREE(type_conv,buf);
+ if (buf) {
+ assert(non_zero_fill_f>=0);
+ if(non_zero_fill_f)
+ H5FL_BLK_FREE(non_zero_fill,buf);
+ else
+ H5FL_BLK_FREE(zero_fill,buf);
+ } /* end if */
FUNC_LEAVE(ret_value);
}
@@ -661,7 +679,7 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
} /* end if */
else {
/* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_ALLOC(sieve_buf,f->shared->sieve_buf_size,0)))
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Determine the new sieve buffer size & location */
@@ -1128,7 +1146,7 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
} /* end if */
else {
/* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_ALLOC(sieve_buf,f->shared->sieve_buf_size,0)))
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Determine the new sieve buffer size & location */
diff --git a/src/H5Distore.c b/src/H5Distore.c
index ea74165..f617092 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -862,7 +862,7 @@ H5F_istore_init (H5F_t *f)
HDmemset (rdcc, 0, sizeof(H5F_rdcc_t));
if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) {
rdcc->nslots = f->shared->rdcc_nelmts;
- rdcc->slot = H5FL_ARR_ALLOC (H5F_rdcc_ent_ptr_t,rdcc->nslots,1);
+ rdcc->slot = H5FL_ARR_CALLOC (H5F_rdcc_ent_ptr_t,rdcc->nslots);
if (NULL==rdcc->slot)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
}
@@ -1440,7 +1440,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache");
/* Create a new entry */
- ent = H5FL_ALLOC(H5F_rdcc_ent_t,0);
+ ent = H5FL_MALLOC(H5F_rdcc_ent_t);
ent->locked = 0;
ent->dirty = FALSE;
ent->chunk_size = chunk_size;
@@ -1943,8 +1943,9 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
#ifdef H5_HAVE_PARALLEL
/* Additional sanity check when operating in parallel */
- if (chunk_addr==HADDR_UNDEF || pline.nfilters>0)
+ if (chunk_addr==HADDR_UNDEF || pline.nfilters>0) {
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
+ }
#endif /* H5_HAVE_PARALLEL */
/*
@@ -2312,7 +2313,7 @@ done:
*/
herr_t
H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- const hsize_t *space_dim, H5P_genplist_t *dc_plist)
+ const hsize_t *space_dim, H5P_genplist_t *dc_plist, hbool_t full_overwrite)
{
hssize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
hsize_t chunk_size; /* Size of chunk in bytes */
@@ -2407,7 +2408,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
} /* end for */
/* Check if fill values should be written to blocks */
- if(fill_time != H5D_FILL_TIME_NEVER) {
+ if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) {
/* Allocate chunk buffer for processes to use when writing fill values */
H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t);
if (NULL==(chunk = H5MM_malloc((size_t)chunk_size)))
@@ -2484,7 +2485,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk");
/* Check if fill values should be written to blocks */
- if(fill_time != H5D_FILL_TIME_NEVER) {
+ if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) {
#ifdef H5_HAVE_PARALLEL
/* Check if this file is accessed with an MPI-capable file driver */
if(using_mpi) {
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 7f2a0ce..cfef073 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -147,44 +147,24 @@
typedef struct H5D_t {
H5G_entry_t ent; /* cached object header stuff */
H5T_t *type; /* datatype of this dataset */
+ H5S_t *space; /* dataspace of this dataset */
hid_t dcpl_id; /* dataset creation property id */
H5O_layout_t layout; /* data layout */
+ /* Cache some frequently accessed values from the DCPL */
+ H5O_efl_t efl; /* External file list information */
+ H5D_alloc_time_t alloc_time; /* Dataset allocation time */
+ H5D_fill_time_t fill_time; /* Dataset fill value writing time */
+ H5O_fill_t fill; /* Dataset fill value information */
} H5D_t;
/* Functions defined in H5D.c */
H5_DLL herr_t H5D_init(void);
-
-H5_DLL herr_t H5D_update_entry_cache(H5F_t *f, H5G_entry_t *ent, H5G_entry_t *loc,
- const char *name, const H5S_t *space,
- H5P_genplist_t *new_plist, H5O_layout_t *layout,
- H5T_t *type, hbool_t allocate_header,
- haddr_t header);
-H5_DLL herr_t H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
- H5O_efl_t *efl, H5O_layout_t *layout);
-
-H5_DLL H5D_t *H5D_create(H5G_entry_t *loc, const char *name,
- const H5T_t *type, const H5S_t *space,
- hid_t dcpl_id);
-H5_DLL H5D_t *H5D_open(H5G_entry_t *loc, const char *name);
+H5_DLL hid_t H5D_open(H5G_entry_t *ent);
H5_DLL herr_t H5D_close(H5D_t *dataset);
H5_DLL htri_t H5D_isa(H5G_entry_t *ent);
-H5_DLL herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type,
- const H5S_t *mem_space, const H5S_t *file_space,
- hid_t dset_xfer_plist, void *buf/*out*/);
-H5_DLL herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type,
- const H5S_t *mem_space, const H5S_t *file_space,
- hid_t dset_xfer_plist, const void *buf);
H5_DLL herr_t H5D_extend(H5D_t *dataset, const hsize_t *size);
H5_DLL H5G_entry_t *H5D_entof(H5D_t *dataset);
H5_DLL H5T_t *H5D_typeof(H5D_t *dset);
-H5_DLL H5S_t *H5D_get_space(H5D_t *dset);
-H5_DLL H5D_t * H5D_open_oid(H5G_entry_t *ent);
-H5_DLL H5F_t * H5D_get_file(const H5D_t *dset);
-H5_DLL hsize_t H5D_get_storage_size(H5D_t *dset);
-H5_DLL haddr_t H5D_get_offset(H5D_t *dset);
-H5_DLL void *H5D_vlen_get_buf_size_alloc(size_t size, void *info);
-H5_DLL herr_t H5D_vlen_get_buf_size(void *elem, hid_t type_id, hsize_t ndim,
- hssize_t *point, void *op_data);
H5_DLL herr_t H5D_crt_copy(hid_t new_plist_t, hid_t old_plist_t,
void *copy_data);
H5_DLL herr_t H5D_crt_close(hid_t dxpl_id, void *close_data);
@@ -192,7 +172,6 @@ H5_DLL herr_t H5D_xfer_create(hid_t dxpl_id, void *create_data);
H5_DLL herr_t H5D_xfer_copy(hid_t new_plist_id, hid_t old_plist_id,
void *copy_data);
H5_DLL herr_t H5D_xfer_close(hid_t dxpl_id, void *close_data);
-H5_DLL herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size);
H5_DLL herr_t H5D_flush(H5F_t *f);
diff --git a/src/H5Dseq.c b/src/H5Dseq.c
index 6176003..9592725 100644
--- a/src/H5Dseq.c
+++ b/src/H5Dseq.c
@@ -59,9 +59,9 @@ static int interface_initialize_g = 0;
*/
herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const H5S_t *file_space, size_t elmt_size,
- size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ const H5S_t *file_space, size_t elmt_size,
+ size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -70,10 +70,11 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
done:
@@ -104,9 +105,9 @@ done:
*/
herr_t
H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const H5S_t *file_space, size_t elmt_size,
- size_t seq_len, hsize_t dset_offset, const void *buf)
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ const H5S_t *file_space, size_t elmt_size,
+ size_t seq_len, hsize_t dset_offset, const void *buf)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -115,10 +116,11 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -151,7 +153,7 @@ done:
*/
herr_t
H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
const H5S_t *file_space, size_t elmt_size,
size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
void *_buf/*out*/)
@@ -172,7 +174,6 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
unsigned u; /*counters */
size_t v; /*counters */
int i,j; /*counters */
- struct H5O_efl_t efl; /* External File List info */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
H5P_genplist_t *plist=NULL; /* Property list */
@@ -184,6 +185,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(real_buf);
/* Make certain we have the correct type of property list */
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
@@ -221,14 +223,10 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
- /* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get EFL value");
-
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Read directly from file if the dataset is in an external file */
- if (efl.nused>0) {
+ if (efl->nused>0) {
/* Iterate through the sequence vectors */
for(v=0; v<nseq; v++) {
#ifdef H5_HAVE_PARALLEL
@@ -260,7 +258,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
* file offsets, totally mixing up the data sieve buffer information. -QAK
*/
H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_read(f, &efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
+ if (H5O_efl_read(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
/* Increment offset in buffer */
@@ -281,7 +279,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/*
* This method is unable to access external raw data files
*/
- if (efl.nused>0)
+ if (efl->nused>0)
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
/* Compute the file offset coordinates and hyperslab size */
@@ -542,7 +540,7 @@ done:
*/
herr_t
H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
const H5S_t *file_space, size_t elmt_size,
size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
const void *_buf)
@@ -563,7 +561,6 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
unsigned u; /*counters */
size_t v; /*counters */
int i,j; /*counters */
- struct H5O_efl_t efl; /* External File List info */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
H5P_genplist_t *plist=NULL; /* Property list */
@@ -575,6 +572,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(real_buf);
/* Make certain we have the correct type of property list */
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
@@ -612,14 +610,10 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on chunked datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
- /* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get EFL value");
-
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Write directly to file if the dataset is in an external file */
- if (efl.nused>0) {
+ if (efl->nused>0) {
/* Iterate through the sequence vectors */
for(v=0; v<nseq; v++) {
#ifdef H5_HAVE_PARALLEL
@@ -650,7 +644,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
* file offsets, totally mixing up the data sieve buffer information. -QAK
*/
H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_write(f, &efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
+ if (H5O_efl_write(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
/* Increment offset in buffer */
@@ -671,7 +665,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/*
* This method is unable to access external raw data files
*/
- if (efl.nused>0)
+ if (efl->nused>0)
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
/* Compute the file offset coordinates and hyperslab size */
diff --git a/src/H5E.c b/src/H5E.c
index 98bfe1d..8b9ab13 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -72,6 +72,8 @@ static const H5E_major_mesg_t H5E_major_mesg_g[] = {
{H5E_VFL, "Virtual File Layer"},
{H5E_TBBT, "Threaded, Balanced, Binary Trees"},
{H5E_FPHDF5, "Flexible Parallel HDF5"},
+ {H5E_TST, "Ternary Search Trees"},
+ {H5E_RS, "Reference Counted Strings"},
};
static const H5E_minor_mesg_t H5E_minor_mesg_g[] = {
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 09e5af2..607bbf2 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -101,7 +101,9 @@ typedef enum H5E_major_t {
H5E_REFERENCE, /*References */
H5E_VFL, /*Virtual File Layer */
H5E_TBBT, /*Threaded, Balanced, Binary Trees */
- H5E_FPHDF5 /*Flexible Parallel HDF5 */
+ H5E_FPHDF5, /*Flexible Parallel HDF5 */
+ H5E_TST, /*Ternary Search Trees */
+ H5E_RS /*Reference Counted Strings */
} H5E_major_t;
/* Declare an enumerated type which holds all the valid minor HDF error codes */
diff --git a/src/H5F.c b/src/H5F.c
index 492dc42..bafda9a 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -243,7 +243,7 @@ H5F_init_interface(void)
assert(H5P_CLS_FILE_CREATE_g!=-1);
/* Get the pointer to file creation class */
- if(NULL == (crt_pclass = H5I_object_verify(H5P_CLS_FILE_CREATE_g, H5I_GENPROP_CLS)))
+ if(NULL == (crt_pclass = H5I_object(H5P_CLS_FILE_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -326,7 +326,7 @@ H5F_init_interface(void)
assert(H5P_CLS_FILE_ACCESS_g!=-1);
/* Get the pointer to file creation class */
- if(NULL == (acs_pclass = H5I_object_verify(H5P_CLS_FILE_ACCESS_g, H5I_GENPROP_CLS)))
+ if(NULL == (acs_pclass = H5I_object(H5P_CLS_FILE_ACCESS_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -407,7 +407,7 @@ H5F_init_interface(void)
assert(H5P_CLS_MOUNT_g!=-1);
/* Get the pointer to file mount class */
- if(NULL == (mnt_pclass = H5I_object_verify(H5P_CLS_MOUNT_g, H5I_GENPROP_CLS)))
+ if(NULL == (mnt_pclass = H5I_object(H5P_CLS_MOUNT_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -503,7 +503,7 @@ H5F_acs_create(hid_t fapl_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI(H5F_acs_create, FAIL);
/* Check argument */
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
/* Retrieve properties */
@@ -558,7 +558,7 @@ H5F_acs_close(hid_t fapl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI(H5F_acs_close, FAIL);
/* Check argument */
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
@@ -610,9 +610,9 @@ H5F_acs_copy(hid_t new_fapl_id, hid_t old_fapl_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI(H5F_acs_copy, FAIL);
- if(NULL == (new_plist = H5I_object_verify(new_fapl_id, H5I_GENPROP_LST)))
+ if(NULL == (new_plist = H5I_object(new_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list");
- if(NULL == (old_plist = H5I_object_verify(old_fapl_id, H5I_GENPROP_LST)))
+ if(NULL == (old_plist = H5I_object(old_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list");
/* Get values from old property list */
@@ -1375,7 +1375,7 @@ H5Fis_hdf5(const char *name)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified");
/* Open the file at the virtual file layer */
- if (NULL==(file=H5FD_open(name, H5F_ACC_RDONLY, H5P_DEFAULT, HADDR_UNDEF)))
+ if (NULL==(file=H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF)))
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file");
/* The file is an hdf5 file if the hdf5 file signature can be found */
@@ -1428,13 +1428,13 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
FUNC_ENTER_NOINIT(H5F_new);
- if (NULL==(f=H5FL_ALLOC(H5F_t,1)))
+ if (NULL==(f=H5FL_CALLOC(H5F_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if (shared) {
f->shared = shared;
} else {
- f->shared = H5FL_ALLOC(H5F_file_t,1);
+ f->shared = H5FL_CALLOC(H5F_file_t);
f->shared->boot_addr = HADDR_UNDEF;
f->shared->base_addr = HADDR_UNDEF;
f->shared->freespace_addr = HADDR_UNDEF;
@@ -1445,16 +1445,19 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
* new file handle. We do this early because some values might need
* to change as the file is being opened.
*/
- if(H5P_DEFAULT == fcpl_id)
- fcpl_id = H5P_FILE_CREATE_DEFAULT;
- if(NULL == (plist = H5P_object_verify(fcpl_id,H5P_FILE_CREATE)))
+ if(NULL == (plist = H5I_object(fcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list");
f->shared->fcpl_id = H5P_copy_plist(plist);
+ /* Get the FCPL values to cache */
+ if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address");
+ if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size");
+ if(H5P_get(plist, H5F_CRT_SYM_LEAF_NAME, &f->shared->sym_leaf_k)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size");
- if(H5P_DEFAULT == fapl_id)
- fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list");
if(H5P_get(plist, H5F_ACS_META_CACHE_SIZE_NAME, &(f->shared->mdc_nelmts)) < 0)
@@ -1486,6 +1489,10 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
/* Create the chunk cache */
H5F_istore_init(f);
+
+ /* Create the file's "open object" information */
+ if(H5FO_create(f)<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object TBBT");
} /* end else */
f->shared->nrefs++;
@@ -1561,13 +1568,17 @@ H5F_dest(H5F_t *f)
f->shared->root_grp=NULL;
}
if (H5AC_dest(f)) {
- HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
+ HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
ret_value = FAIL; /*but keep going*/
}
if (H5F_istore_dest (f)<0) {
- HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
+ HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
ret_value = FAIL; /*but keep going*/
}
+ if (H5FO_dest(f)<0) {
+ HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
+ ret_value = FAIL; /*but keep going*/
+ } /* end if */
f->shared->cwfs = H5MM_xfree (f->shared->cwfs);
/* Free the data sieve buffer, if it's been allocated */
@@ -1837,6 +1848,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
* empty or not.
*/
if (0==H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) {
+ /* Get values to cache from the FCPL */
+ if(H5P_get(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&shared->sizeof_addr)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address");
+ if(H5P_get(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &shared->sizeof_size)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size");
+ if(H5P_get(c_plist, H5F_CRT_SYM_LEAF_NAME, &shared->sym_leaf_k)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes");
+ if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, &shared->btree_k[0])<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes");
+
/*
* The superblock starts immediately after the user-defined header,
* which we have already insured is a proper size. The base address
@@ -1903,6 +1924,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address");
if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&sizeof_addr)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address");
+ shared->sizeof_addr=sizeof_addr; /* Keep a local copy also */
/* Size of file sizes */
sizeof_size = *p++;
@@ -1911,6 +1933,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size");
if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size");
+ shared->sizeof_size=sizeof_size; /* Keep a local copy also */
/* Reserved byte */
p++;
@@ -1921,6 +1944,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank");
if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes");
+ shared->sym_leaf_k=sym_leaf_k; /* Keep a local copy also */
/* Need 'get' call to set other array values */
if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
@@ -1930,6 +1954,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes");
if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes");
+ HDmemcpy(shared->btree_k,btree_k,sizeof(int)*H5B_NUM_BTREE_ID); /* Keep a local copy also */
/* File consistency flags. Not really used yet */
UINT32DECODE(p, shared->consist_flags);
@@ -2033,9 +2058,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
* second time or later, verify the access property list value matches
* the degree in shared file structure.
*/
- if(H5P_DEFAULT == fapl_id)
- fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if(NULL == (a_plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (a_plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list");
if(H5P_get(a_plist, H5F_CLOSE_DEGREE_NAME, &fc_degree) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree");
@@ -2138,14 +2161,16 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id,
/* Check file creation property list */
if(H5P_DEFAULT == fcpl_id)
fcpl_id = H5P_FILE_CREATE_DEFAULT;
- if(TRUE != H5P_isa_class(fcpl_id, H5P_FILE_CREATE))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file create property list");
+ else
+ if(TRUE != H5P_isa_class(fcpl_id, H5P_FILE_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file create property list");
/* Check the file access property list */
if(H5P_DEFAULT == fapl_id)
fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list");
+ else
+ if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list");
/*
* Adjust bit flags by turning on the creation bit and making sure that
@@ -2230,11 +2255,12 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags");
if(H5P_DEFAULT == fapl_id)
fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list");
+ else
+ if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list");
/* Open the file */
- if (NULL==(new_file=H5F_open(filename, flags, H5P_DEFAULT, fapl_id)))
+ if (NULL==(new_file=H5F_open(filename, flags, H5P_FILE_CREATE_DEFAULT, fapl_id)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file");
/* Get an atom for the file */
@@ -2399,8 +2425,6 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
int freespace_vers; /* Freespace info version */
int obj_dir_vers; /* Object header info version */
int share_head_vers;/* Shared header info version */
- int btree_k[H5B_NUM_BTREE_ID]; /* B-tree size info */
- unsigned sym_leaf_k; /* Number of symbols in B-tree leafs */
H5P_genplist_t *plist; /* Property list */
herr_t ret_value; /* Return value */
@@ -2492,10 +2516,6 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get object directory version");
if(H5P_get(plist, H5F_CRT_SHARE_HEAD_VERS_NAME, &share_head_vers) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get shared-header format version");
- if(H5P_get(plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for symbol table leaf nodes");
- if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes");
/* encode the file boot block */
p = sbuf;
@@ -2511,8 +2531,8 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
assert (H5F_SIZEOF_SIZE(f)<=255);
*p++ = (uint8_t)H5F_SIZEOF_SIZE(f);
*p++ = 0; /*reserved */
- UINT16ENCODE(p, sym_leaf_k);
- UINT16ENCODE(p, btree_k[H5B_SNODE_ID]);
+ UINT16ENCODE(p, f->shared->sym_leaf_k);
+ UINT16ENCODE(p, f->shared->btree_k[H5B_SNODE_ID]);
UINT32ENCODE(p, f->shared->consist_flags);
H5F_addr_encode(f, &p, f->shared->base_addr);
H5F_addr_encode(f, &p, f->shared->freespace_addr);
@@ -2904,6 +2924,7 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
H5F_t *parent = NULL; /*file containing mount point */
int lt, rt, md, cmp; /*binary search indices */
H5G_entry_t *ent = NULL; /*temporary symbol table entry */
+ H5RS_str_t *name_r; /* Ref-counted version of name */
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOINIT(H5F_mount);
@@ -2975,8 +2996,11 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
/* Search the open IDs and replace names for mount operation */
/* We pass H5G_UNKNOWN as object type; search all IDs */
- if (H5G_replace_name( H5G_UNKNOWN, loc, name, NULL, NULL, NULL, OP_MOUNT )<0)
+ name_r=H5RS_wrap(name);
+ assert(name_r);
+ if (H5G_replace_name( H5G_UNKNOWN, loc, name_r, NULL, NULL, NULL, OP_MOUNT )<0)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to replace name");
+ H5RS_decr(name_r);
done:
if (ret_value<0 && mount_point)
@@ -3050,7 +3074,7 @@ H5F_unmount(H5G_entry_t *loc, const char *name)
for (i=0; i<parent->mtab.nmounts; i++) {
if (parent->mtab.child[i].file==child) {
/* Search the open IDs replace names to reflect unmount operation */
- if (H5G_replace_name( H5G_UNKNOWN, mnt_ent, mnt_ent->user_path, NULL, NULL, NULL, OP_UNMOUNT )<0)
+ if (H5G_replace_name( H5G_UNKNOWN, mnt_ent, mnt_ent->user_path_r, NULL, NULL, NULL, OP_UNMOUNT )<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ");
/* Unmount the child */
@@ -3181,6 +3205,74 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5F_has_mount
+ *
+ * Purpose: Check if a file has mounted files within it.
+ *
+ * Return: Success: TRUE/FALSE
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 2, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5F_has_mount(const H5F_t *file)
+{
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_has_mount, FAIL);
+
+ assert(file);
+
+ if(file->mtab.nmounts>0)
+ ret_value=TRUE;
+ else
+ ret_value=FALSE;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5F_has_mount() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_is_mount
+ *
+ * Purpose: Check if a file is mounted within another file.
+ *
+ * Return: Success: TRUE/FALSE
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 2, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5F_is_mount(const H5F_t *file)
+{
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_is_mount, FAIL);
+
+ assert(file);
+
+ if(file->mtab.parent!=NULL)
+ ret_value=TRUE;
+ else
+ ret_value=FALSE;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5F_is_mount() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Fmount
*
* Purpose: Mount file CHILD_ID onto the group specified by LOC_ID and
@@ -3214,8 +3306,9 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
if(H5P_DEFAULT == plist_id)
plist_id = H5P_MOUNT_DEFAULT;
- if(TRUE != H5P_isa_class(plist_id, H5P_MOUNT))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property list");
+ else
+ if(TRUE != H5P_isa_class(plist_id, H5P_MOUNT))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property list");
/* Do the mount */
if (H5F_mount(loc, name, child, plist_id)<0)
@@ -3307,7 +3400,7 @@ H5Freopen(hid_t file_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
/* Get a new "top level" file struct, sharing the same "low level" file struct */
- if (NULL==(new_file=H5F_new(old_file->shared, H5P_DEFAULT, H5P_DEFAULT)))
+ if (NULL==(new_file=H5F_new(old_file->shared, H5P_FILE_CREATE_DEFAULT, H5P_FILE_ACCESS_DEFAULT)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file");
/* Keep old file's read/write intent in new file */
@@ -3373,27 +3466,14 @@ H5F_get_intent(const H5F_t *f)
size_t
H5F_sizeof_addr(const H5F_t *f)
{
- size_t sizeof_addr = 0;
- H5P_genplist_t *plist; /* Property list */
- size_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_sizeof_addr, 0);
+ /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
+ FUNC_ENTER_NOINIT(H5F_sizeof_addr);
assert(f);
assert(f->shared);
- /* Get property list */
- if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, UFAIL, "not a property list");
-
- if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, UFAIL, "can't get byte number for address");
-
- /* Set return value */
- ret_value=sizeof_addr;
-
done:
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(f->shared->sizeof_addr);
}
@@ -3419,31 +3499,88 @@ done:
size_t
H5F_sizeof_size(const H5F_t *f)
{
- size_t sizeof_size = 0;
- H5P_genplist_t *plist; /* Property list */
- size_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_sizeof_size, 0);
+ /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
+ FUNC_ENTER_NOINIT(H5F_sizeof_size);
assert(f);
assert(f->shared);
- /* Get property list */
- if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, UFAIL, "not a property list");
+done:
+ FUNC_LEAVE(f->shared->sizeof_size);
+}
- if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, UFAIL, "can't get byte number for object size");
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sym_leaf_k
+ *
+ * Purpose: Replaced a macro to retrieve the symbol table leaf size,
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-negative, and the symbol table leaf size is
+ * returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Raymond Lu
+ * slu@ncsa.uiuc.edu
+ * Oct 14 2001
+ *
+ * Modifications:
+ * Quincey Koziol, 2001-10-15
+ * Added this header and removed unused ret_value variable.
+ *-------------------------------------------------------------------------
+ */
+unsigned H5F_sym_leaf_k(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
+ FUNC_ENTER_NOINIT(H5F_sym_leaf_k);
- /* Set return value */
- ret_value=sizeof_size;
+ assert(f);
+ assert(f->shared);
done:
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(f->shared->sym_leaf_k);
}
/*-------------------------------------------------------------------------
+ * Function: H5F_Kvalue
+ *
+ * Purpose: Replaced a macro to retrieve a B-tree key value for a certain
+ * type, now that the generic properties are being used to store
+ * the B-tree values.
+ *
+ * Return: Success: Non-negative, and the B-tree key value is
+ * returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Raymond Lu
+ * slu@ncsa.uiuc.edu
+ * Oct 14 2001
+ *
+ * Modifications:
+ * Quincey Koziol, 2001-10-15
+ * Added this header and removed unused ret_value variable.
+ *-------------------------------------------------------------------------
+ */
+int
+H5F_Kvalue(const H5F_t *f, const H5B_class_t *type)
+{
+ /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
+ FUNC_ENTER_NOINIT(H5F_Kvalue);
+
+ assert(f);
+ assert(f->shared);
+ assert(type);
+
+done:
+ FUNC_LEAVE(f->shared->btree_k[type->id]);
+} /* end H5F_Kvalue() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_get_driver_id
*
* Purpose: Quick and dirty routine to retrieve the file's 'driver_id' value
@@ -3509,23 +3646,35 @@ done:
FUNC_LEAVE(ret_value);
} /* end H5F_get_fileno() */
-
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_base_addr
+ *
+ * Purpose: Quick and dirty routine to retrieve the file's 'base_addr' value
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
+ * December 20, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
haddr_t
H5F_get_base_addr(const H5F_t *f)
{
- haddr_t ret_value;
-
- FUNC_ENTER_NOAPI(H5F_get_base_addr, FAIL);
+ /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
+ FUNC_ENTER_NOINIT(H5F_get_base_addr);
assert(f);
assert(f->shared);
- /* Retrieve the file's base address */
- ret_value = f->shared->base_addr;
-
done:
- FUNC_LEAVE(ret_value);
-}
+ FUNC_LEAVE(f->shared->base_addr);
+} /* end H5F_get_bass_addr() */
/*-------------------------------------------------------------------------
@@ -3800,9 +3949,6 @@ H5F_debug(H5F_t *f, haddr_t UNUSED addr, FILE * stream, int indent,
int fwidth)
{
hsize_t userblock_size;
- int btree_k[H5B_NUM_BTREE_ID];
- unsigned sym_leaf_k;
- size_t sizeof_addr, sizeof_size;
int boot_vers, freespace_vers, obj_dir_vers, share_head_vers;
H5P_genplist_t *plist; /* Property list */
herr_t ret_value=SUCCEED; /* Return value */
@@ -3822,15 +3968,6 @@ H5F_debug(H5F_t *f, haddr_t UNUSED addr, FILE * stream, int indent,
if(H5P_get(plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get user block size");
- if(H5P_get(plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get rank for symbol table leaf nodes");
- if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get rank for btree nodes");
-
- if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for an address");
- if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for object size");
if(H5P_get(plist, H5F_CRT_BOOT_VERS_NAME, &boot_vers)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get boot block version");
@@ -3868,14 +4005,14 @@ H5F_debug(H5F_t *f, haddr_t UNUSED addr, FILE * stream, int indent,
HDfprintf(stream, "%*s%-*s %lu bytes\n", indent, "", fwidth,
"Size of user block:", (unsigned long) userblock_size);
HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth,
- "Size of file size_t type:", (unsigned) sizeof_size);
+ "Size of file size_t type:", (unsigned) f->shared->sizeof_size);
HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth,
- "Size of file haddr_t type:", (unsigned) sizeof_addr);
+ "Size of file haddr_t type:", (unsigned) f->shared->sizeof_addr);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Symbol table leaf node 1/2 rank:", sym_leaf_k);
+ "Symbol table leaf node 1/2 rank:", f->shared->sym_leaf_k);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Symbol table internal node 1/2 rank:",
- (unsigned) (btree_k[H5B_SNODE_ID]));
+ (unsigned) (f->shared->btree_k[H5B_SNODE_ID]));
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Boot block version number:", (unsigned) boot_vers);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
diff --git a/src/H5FD.c b/src/H5FD.c
index 60ab418..70098ce 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -513,7 +513,7 @@ H5FD_fapl_copy(hid_t driver_id, const void *old_fapl)
FUNC_ENTER_NOAPI(H5FD_fapl_copy, NULL);
/* Check args */
- if (NULL==(driver=H5I_object_verify(driver_id,H5I_VFL)))
+ if (NULL==(driver=H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver ID");
if (!old_fapl)
HGOTO_DONE(NULL); /*but no error*/
@@ -560,7 +560,7 @@ H5FD_fapl_free(hid_t driver_id, void *fapl)
FUNC_ENTER_NOAPI(H5FD_fapl_free, FAIL);
/* Check args */
- if (NULL==(driver=H5I_object_verify(driver_id,H5I_VFL)))
+ if (NULL==(driver=H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID");
/* Allow driver to free or do it ourselves */
@@ -606,7 +606,7 @@ H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl)
FUNC_ENTER_NOAPI(H5FD_dxpl_copy, NULL);
/* Check args */
- if (NULL==(driver=H5I_object_verify(driver_id,H5I_VFL)))
+ if (NULL==(driver=H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver ID");
if (!old_dxpl)
HGOTO_DONE(NULL); /*but no error*/
@@ -653,7 +653,7 @@ H5FD_dxpl_free(hid_t driver_id, void *dxpl)
FUNC_ENTER_NOAPI(H5FD_dxpl_free, FAIL);
/* Check args */
- if (NULL==(driver=H5I_object_verify(driver_id,H5I_VFL)))
+ if (NULL==(driver=H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID");
/* Allow driver to free or do it ourselves */
@@ -731,6 +731,13 @@ H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
FUNC_ENTER_API(H5FDopen, NULL);
+ /* Check arguments */
+ if(H5P_DEFAULT == fapl_id)
+ fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(fapl_id,H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
+
if (NULL==(ret_value=H5FD_open(name, flags, fapl_id, maxaddr)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to open file");
@@ -773,10 +780,8 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
FUNC_ENTER_NOAPI(H5FD_open, NULL);
- /* Check arguments */
- if(H5P_DEFAULT == fapl_id)
- fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ /* Get file access property list */
+ if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
if (0==maxaddr)
@@ -786,7 +791,7 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID");
/* Get driver info */
- if (NULL==(driver=H5I_object_verify(driver_id,H5I_VFL)))
+ if (NULL==(driver=H5I_object(driver_id)))
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list");
if (NULL==driver->open)
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method");
@@ -1392,7 +1397,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
else {
/* Attempt to allocate memory for temporary node */
- tmp = H5FL_ALLOC(H5FD_free_t,0);
+ tmp = H5FL_MALLOC(H5FD_free_t);
#ifdef H5F_DEBUG
if (H5DEBUG(F)) {
HDfprintf(H5DEBUG(F),
@@ -1807,7 +1812,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
tail_size=(file->accum_loc+file->accum_size)-tail_addr;
/* Write out the part of the accumulator after the block to free */
- if (H5FD_write(file, H5FD_MEM_DEFAULT, H5P_DEFAULT, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc))<0)
+ if (H5FD_write(file, H5FD_MEM_DEFAULT, H5P_DATASET_XFER_DEFAULT, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc))<0)
HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed");
} /* end if */
@@ -1904,7 +1909,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
} /* end if */
else {
/* Allocate a new node to hold the free block's information */
- if(NULL==(last = H5FL_ALLOC(H5FD_free_t,0)))
+ if(NULL==(last = H5FL_MALLOC(H5FD_free_t)))
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info");
last->addr = addr;
@@ -2336,8 +2341,9 @@ H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size
/* 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;
- if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list");
+ else
+ if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list");
if (!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null result buffer");
@@ -2563,8 +2569,9 @@ H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz
/* 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;
- if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list");
+ else
+ if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list");
if (!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer");
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index 00a98db..f6ad440 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -194,8 +194,11 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, hid_t memb_fapl_id)
/* Check arguments */
if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list");
- if(memb_fapl_id!=H5P_DEFAULT && TRUE != H5P_isa_class(memb_fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list");
+ if(H5P_DEFAULT == memb_fapl_id)
+ memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(memb_fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list");
/*
* Initialize driver specific information. No need to copy it into the FA
@@ -345,8 +348,8 @@ H5FD_family_fapl_copy(const void *_old_fa)
memcpy(new_fa, old_fa, sizeof(H5FD_family_fapl_t));
/* Deep copy the property list objects in the structure */
- if(old_fa->memb_fapl_id==H5P_DEFAULT)
- new_fa->memb_fapl_id = H5P_DEFAULT;
+ if(old_fa->memb_fapl_id==H5P_FILE_ACCESS_DEFAULT)
+ H5I_inc_ref(new_fa->memb_fapl_id);
else {
if(NULL == (plist = H5I_object(old_fa->memb_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
@@ -427,9 +430,14 @@ H5FD_family_dxpl_copy(const void *_old_dx)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
memcpy(new_dx, old_dx, sizeof(H5FD_family_dxpl_t));
- if(NULL == (plist = H5I_object(old_dx->memb_dxpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
- new_dx->memb_dxpl_id = H5P_copy_plist(plist);
+
+ if(old_dx->memb_dxpl_id==H5P_DATASET_XFER_DEFAULT)
+ H5I_inc_ref(new_dx->memb_dxpl_id);
+ else {
+ if(NULL == (plist = H5I_object(old_dx->memb_dxpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
+ new_dx->memb_dxpl_id = H5P_copy_plist(plist);
+ } /* end else */
/* Set return value */
ret_value=new_dx;
@@ -515,8 +523,9 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id,
/* Initialize file from file access properties */
if (NULL==(file=H5MM_calloc(sizeof(H5FD_family_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct");
- if (H5P_DEFAULT==fapl_id) {
- file->memb_fapl_id = H5P_DEFAULT;
+ if (H5P_FILE_ACCESS_DEFAULT==fapl_id) {
+ file->memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ H5I_inc_ref(file->memb_fapl_id);
file->memb_size = 1024*1024*1024; /*1GB*/
} else {
H5FD_family_fapl_t *fa;
@@ -524,8 +533,8 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id,
if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
fa = H5P_get_driver_info(plist);
- if(fa->memb_fapl_id==H5P_DEFAULT)
- file->memb_fapl_id = H5P_DEFAULT;
+ if(fa->memb_fapl_id==H5P_FILE_ACCESS_DEFAULT)
+ H5I_inc_ref(file->memb_fapl_id);
else {
if(NULL == (plist = H5I_object(fa->memb_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
@@ -920,8 +929,6 @@ H5FD_family_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle)
FUNC_ENTER_NOAPI(H5FD_family_get_handle, FAIL);
/* Get the plist structure and family offset */
- if(H5P_DEFAULT == fapl)
- fapl = H5Pcreate(H5P_FILE_ACCESS);
if(NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
if(H5P_get(plist, H5F_ACS_FAMILY_OFFSET_NAME, &offset) < 0)
@@ -963,7 +970,7 @@ H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si
{
H5FD_family_t *file = (H5FD_family_t*)_file;
unsigned char *buf = (unsigned char*)_buf;
- hid_t memb_dxpl_id = H5P_DEFAULT;
+ hid_t memb_dxpl_id = H5P_DATASET_XFER_DEFAULT;
int i;
haddr_t sub;
size_t req;
@@ -979,7 +986,7 @@ H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si
*/
if(NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list");
- if (H5P_DEFAULT!=dxpl_id && H5FD_FAMILY==H5P_get_driver(plist)) {
+ if (H5P_DATASET_XFER_DEFAULT!=dxpl_id && H5FD_FAMILY==H5P_get_driver(plist)) {
H5FD_family_dxpl_t *dx = H5P_get_driver_info(plist);
assert(TRUE==H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
@@ -1040,7 +1047,7 @@ H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, s
{
H5FD_family_t *file = (H5FD_family_t*)_file;
const unsigned char *buf = (const unsigned char*)_buf;
- hid_t memb_dxpl_id = H5P_DEFAULT;
+ hid_t memb_dxpl_id = H5P_DATASET_XFER_DEFAULT;
int i;
haddr_t sub;
size_t req;
@@ -1056,7 +1063,7 @@ H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, s
*/
if(NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list");
- if (H5P_DEFAULT!=dxpl_id && H5FD_FAMILY==H5P_get_driver(plist)) {
+ if (H5P_DATASET_XFER_DEFAULT!=dxpl_id && H5FD_FAMILY==H5P_get_driver(plist)) {
H5FD_family_dxpl_t *dx = H5P_get_driver_info(plist);
assert(TRUE==H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
diff --git a/src/H5FDgass.c b/src/H5FDgass.c
index 1f01240..4b42b27 100644
--- a/src/H5FDgass.c
+++ b/src/H5FDgass.c
@@ -17,15 +17,11 @@
#include "H5MMprivate.h" /* Memory allocation */
#include "H5Pprivate.h" /*property lists */
-
-#undef MAX
-#define MAX(X,Y) ((X)>(Y)?(X):(Y))
+#ifdef H5_HAVE_GASS
/* The driver identification number, initialized at runtime */
static hid_t H5FD_GASS_g = 0;
-#ifdef H5_HAVE_GASS
-
/* File operations */
#define OP_UNKNOWN 0
#define OP_READ 1
@@ -363,7 +359,7 @@ H5FD_gass_open(const char *name, unsigned flags, hid_t fapl_id,
/* Obtain a pointer to gass-specific file access properties */
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
- if (H5P_DEFAULT==fapl_id || H5FD_GASS!=H5P_get_driver(plist)) {
+ if (H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_GASS!=H5P_get_driver(plist)) {
GASS_INFO_NULL (_fa.info);
/* _fa.info = GASS_INFO_NULL; */
/* _fa.info = {0,0}; */ /*default*/
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 5e81260..f42da62 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -39,7 +39,7 @@ static hid_t H5FD_LOG_g = 0;
/* Driver-specific file access properties */
typedef struct H5FD_log_fapl_t {
- char *logfile; /* Allocated log file name */
+ char *logfile; /* Allocated log file name */
unsigned flags; /* Flags for logging behavior */
size_t buf_size; /* Size of buffers for track flavor and number of times each byte is accessed */
} H5FD_log_fapl_t;
@@ -283,7 +283,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Pset_fapl_log(hid_t fapl_id, char *logfile, int verbosity)
+H5Pset_fapl_log(hid_t fapl_id, const char *logfile, int verbosity)
{
H5FD_log_fapl_t fa; /* File access property list information */
H5P_genplist_t *plist; /* Property list pointer */
@@ -330,7 +330,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Pset_fapl_log(hid_t fapl_id, char *logfile, unsigned flags, size_t buf_size)
+H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size)
{
H5FD_log_fapl_t fa; /* File access property list information */
H5P_genplist_t *plist; /* Property list pointer */
diff --git a/src/H5FDlog.h b/src/H5FDlog.h
index adb4e0a..3a4bfc9 100644
--- a/src/H5FDlog.h
+++ b/src/H5FDlog.h
@@ -48,9 +48,9 @@ extern "C" {
H5_DLL hid_t H5FD_log_init(void);
#ifdef H5_WANT_H5_V1_4_COMPAT
-H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, char *logfile, int verbosity);
+H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, int verbosity);
#else /* H5_WANT_H5_V1_4_COMPAT */
-H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, char *logfile, unsigned flags, size_t buf_size);
+H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size);
#endif /* H5_WANT_H5_V1_4_COMPAT */
#ifdef __cplusplus
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 73a66db..0a483f0 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -25,6 +25,8 @@
#include "H5MMprivate.h" /* Memory allocation */
#include "H5Pprivate.h" /*property lists */
+#ifdef H5_HAVE_PARALLEL
+
/*
* The driver identification number, initialized at runtime if H5_HAVE_PARALLEL
* is defined. This allows applications to still have the H5FD_MPIO
@@ -33,8 +35,6 @@
*/
static hid_t H5FD_MPIO_g = 0;
-#ifdef H5_HAVE_PARALLEL
-
/*
* The description of a file belonging to this driver.
* The EOF value is only used just after the file is opened in order for the
@@ -255,6 +255,9 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
FUNC_ENTER_API(H5Pset_fapl_mpio, FAIL);
H5TRACE3("e","iMcMi",fapl_id,comm,info);
+ if(fapl_id==H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list");
+
/* Check arguments */
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list");
@@ -370,6 +373,9 @@ H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode)
FUNC_ENTER_API(H5Pset_dxpl_mpio, FAIL);
H5TRACE2("e","iDt",dxpl_id,xfer_mode);
+ if(dxpl_id==H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list");
+
/* Check arguments */
if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl");
@@ -848,7 +854,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
/* Obtain a pointer to mpio-specific file access properties */
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
- if (H5P_DEFAULT==fapl_id || H5FD_MPIO!=H5P_get_driver(plist)) {
+ if (H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_MPIO!=H5P_get_driver(plist)) {
_fa.comm = MPI_COMM_SELF; /*default*/
_fa.info = MPI_INFO_NULL; /*default*/
fa = &_fa;
diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c
index 63b445b..f1a2768 100644
--- a/src/H5FDmpiposix.c
+++ b/src/H5FDmpiposix.c
@@ -53,6 +53,8 @@
# include <gpfs_fcntl.h>
#endif
+#ifdef H5_HAVE_PARALLEL
+
/*
* The driver identification number, initialized at runtime if H5_HAVE_PARALLEL
* is defined. This allows applications to still have the H5FD_MPIPOSIX
@@ -61,8 +63,6 @@
*/
static hid_t H5FD_MPIPOSIX_g = 0;
-#ifdef H5_HAVE_PARALLEL
-
/* File operations */
#define OP_UNKNOWN 0
#define OP_READ 1
@@ -569,7 +569,7 @@ H5FD_mpiposix_open(const char *name, unsigned flags, hid_t fapl_id,
/* Obtain a pointer to mpiposix-specific file access properties */
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
- if (H5P_DEFAULT==fapl_id || H5FD_MPIPOSIX!=H5P_get_driver(plist)) {
+ if (H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_MPIPOSIX!=H5P_get_driver(plist)) {
_fa.comm = MPI_COMM_SELF; /*default*/
fa = &_fa;
} /* end if */
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index 9a9667e..45ee689 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -417,7 +417,7 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map,
}
if (!memb_fapl) {
for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
- _memb_fapl[mt] = H5P_DEFAULT;
+ _memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
}
memb_fapl = _memb_fapl;
}
@@ -464,6 +464,12 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map,
memcpy(fa.memb_name, memb_name, H5FD_MEM_NTYPES*sizeof(char*));
memcpy(fa.memb_addr, memb_addr, H5FD_MEM_NTYPES*sizeof(haddr_t));
fa.relax = relax;
+
+ /* Patch up H5P_DEFAULT property lists for members */
+ for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
+ if(fa.memb_fapl[mt]==H5P_DEFAULT)
+ fa.memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ }
return H5Pset_driver(fapl_id, H5FD_MULTI, &fa);
}
@@ -581,13 +587,19 @@ H5Pset_dxpl_multi(hid_t dxpl_id, const hid_t *memb_dxpl)
if (!memb_dxpl)
H5Epush_ret(func, H5E_INTERNAL, H5E_BADVALUE, "invalid pointer", -1);
for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
- if (H5P_DEFAULT!=memb_dxpl[mt] &&
- TRUE!=H5Pisa_class(memb_dxpl[mt], H5P_DATASET_XFER))
+ if (memb_dxpl[mt]!=H5P_DEFAULT && TRUE!=H5Pisa_class(memb_dxpl[mt], H5P_DATASET_XFER))
H5Epush_ret(func, H5E_PLIST, H5E_BADTYPE, "not a data transfer property list", -1);
}
/* Initialize the data transfer property list */
memcpy(dx.memb_dxpl, memb_dxpl, H5FD_MEM_NTYPES*sizeof(hid_t));
+
+ /* Convert "generic" default property lists into default dataset transfer property lists */
+ for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
+ if (dx.memb_dxpl[mt]==H5P_DEFAULT)
+ dx.memb_dxpl[mt]=H5P_DATASET_XFER_DEFAULT;
+ }
+
return H5Pset_driver(dxpl_id, H5FD_MULTI, &dx);
}
@@ -1173,7 +1185,7 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id,
*/
if (NULL==(file=calloc(1, sizeof(H5FD_multi_t))))
H5Epush_ret(func, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL);
- if (H5P_DEFAULT==fapl_id || H5FD_MULTI!=H5Pget_driver(fapl_id)) {
+ if (H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_MULTI!=H5Pget_driver(fapl_id)) {
close_fapl = fapl_id = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE);
}
@@ -1652,7 +1664,7 @@ H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, siz
H5Eclear();
/* Get the data transfer properties */
- if (H5P_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
+ if (H5P_FILE_ACCESS_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
dx = H5Pget_driver_info(dxpl_id);
}
@@ -1707,7 +1719,7 @@ H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si
H5Eclear();
/* Get the data transfer properties */
- if (H5P_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
+ if (H5P_FILE_ACCESS_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
dx = H5Pget_driver_info(dxpl_id);
}
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index f65bcbe..526f539 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -310,7 +310,7 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
HGOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file");
/* Create the new file struct */
- if (NULL==(file=H5FL_ALLOC(H5FD_sec2_t,1)))
+ if (NULL==(file=H5FL_CALLOC(H5FD_sec2_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct");
file->fd = fd;
diff --git a/src/H5FDsrb.c b/src/H5FDsrb.c
index bd44382..f2d87c8 100644
--- a/src/H5FDsrb.c
+++ b/src/H5FDsrb.c
@@ -17,11 +17,10 @@
#include "H5Pprivate.h" /*property lists */
-/* The driver identification number, initialized at runtime */
-static hid_t H5FD_SRB_g = 0;
-
#ifdef H5_HAVE_SRB
+/* The driver identification number, initialized at runtime */
+static hid_t H5FD_SRB_g = 0;
/*
* This driver supports systems that have the lseek64() function by defining
@@ -320,7 +319,7 @@ H5FD_srb_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
- if(H5P_DEFAULT==fapl_id || H5FD_SRB!=H5P_get_driver(plist)) {
+ if(H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_SRB!=H5P_get_driver(plist)) {
HDmemset((void*)&_fa, 0, sizeof(H5FD_srb_fapl_t));
fa = &_fa;
}
diff --git a/src/H5FDstream.c b/src/H5FDstream.c
index ee3ca99..a5c89bf 100644
--- a/src/H5FDstream.c
+++ b/src/H5FDstream.c
@@ -594,7 +594,7 @@ H5FD_stream_open (const char *filename,
#endif
fapl = NULL;
- if (H5P_DEFAULT != fapl_id) {
+ if (H5P_FILE_ACCESS_DEFAULT != fapl_id) {
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
fapl = H5P_get_driver_info (plist);
diff --git a/src/H5FL.c b/src/H5FL.c
index 917821c..1e49834 100644
--- a/src/H5FL.c
+++ b/src/H5FL.c
@@ -34,12 +34,12 @@ static int interface_initialize_g = 0;
Default limits on how much memory can accumulate on each free list before
it is garbage collected.
*/
-static size_t H5FL_reg_glb_mem_lim=1*16*65536;/* Default to 1MB limit on all regular free lists */
-static size_t H5FL_reg_lst_mem_lim=1*65536; /* Default to 64KB limit on each regular free list */
-static size_t H5FL_arr_glb_mem_lim=4*16*65536;/* Default to 4MB limit on all array free lists */
-static size_t H5FL_arr_lst_mem_lim=4*65536; /* Default to 256KB limit on each array free list */
-static size_t H5FL_blk_glb_mem_lim=16*16*65536; /* Default to 16MB limit on all block free lists */
-static size_t H5FL_blk_lst_mem_lim=16*65536; /* Default to 1024KB (1MB) limit on each block free list */
+static size_t H5FL_reg_glb_mem_lim=1*1024*1024; /* Default to 1MB limit on all regular free lists */
+static size_t H5FL_reg_lst_mem_lim=1*65536; /* Default to 64KB limit on each regular free list */
+static size_t H5FL_arr_glb_mem_lim=4*1024*1024; /* Default to 4MB limit on all array free lists */
+static size_t H5FL_arr_lst_mem_lim=4*65536; /* Default to 256KB limit on each array free list */
+static size_t H5FL_blk_glb_mem_lim=16*1024*1024; /* Default to 16MB limit on all block free lists */
+static size_t H5FL_blk_lst_mem_lim=1024*1024; /* Default to 1024KB (1MB) limit on each block free list */
/* A garbage collection node for regular free lists */
typedef struct H5FL_reg_gc_node_t {
@@ -248,7 +248,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FL_reg_alloc
+ * Function: H5FL_reg_malloc
*
* Purpose: Allocate a block on a free list
*
@@ -263,11 +263,11 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5FL_reg_alloc(H5FL_reg_head_t *head, unsigned clear)
+H5FL_reg_malloc(H5FL_reg_head_t *head)
{
void *ret_value; /* Pointer to object to return */
- FUNC_ENTER_NOAPI(H5FL_reg_alloc, NULL);
+ FUNC_ENTER_NOAPI(H5FL_reg_malloc, NULL);
/* Double check parameters */
assert(head);
@@ -301,13 +301,46 @@ H5FL_reg_alloc(H5FL_reg_head_t *head, unsigned clear)
head->allocated++;
} /* end else */
- /* Clear to zeros, if asked */
- if(clear)
- HDmemset(ret_value,0,head->size);
+done:
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_reg_malloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_reg_calloc
+ *
+ * Purpose: Allocate a block on a free list and clear it to zeros
+ *
+ * Return: Success: Pointer to a valid object
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_reg_calloc(H5FL_reg_head_t *head)
+{
+ void *ret_value; /* Pointer to object to return */
+
+ FUNC_ENTER_NOAPI(H5FL_reg_calloc, NULL);
+
+ /* Double check parameters */
+ assert(head);
+
+ /* Allocate the block */
+ if (NULL==(ret_value = H5FL_reg_malloc(head)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* Clear to zeros */
+ HDmemset(ret_value,0,head->size);
done:
FUNC_LEAVE (ret_value);
-} /* end H5FL_reg_alloc() */
+} /* end H5FL_reg_calloc() */
/*-------------------------------------------------------------------------
@@ -562,7 +595,7 @@ H5FL_blk_create_list(H5FL_blk_node_t **head, size_t size)
FUNC_ENTER_NOINIT(H5FL_blk_create_list);
/* Allocate room for the new free list node */
- if(NULL==(temp=H5FL_ALLOC(H5FL_blk_node_t,0)))
+ if(NULL==(temp=H5FL_MALLOC(H5FL_blk_node_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk info");
/* Set the correct values for the new free list */
@@ -632,7 +665,45 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FL_blk_alloc
+ * Function: H5FL_blk_free_block_avail
+ *
+ * Purpose: Checks if a free block of the appropriate size is available
+ * for a given list.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 16, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size)
+{
+ H5FL_blk_node_t *free_list; /* The free list of nodes of correct size */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FL_blk_free_block_avail, FAIL);
+
+ /* Double check parameters */
+ assert(head);
+
+ /* check if there is a free list for blocks of this size */
+ /* and if there are any blocks available on the list */
+ if((free_list=H5FL_blk_find_list(&(head->head),size))!=NULL && free_list->list!=NULL)
+ ret_value=TRUE;
+ else
+ ret_value=FALSE;
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FL_blk_free_block_avail() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_malloc
*
* Purpose: Allocates memory for a block. This routine is used
* instead of malloc because the block can be kept on a free list so
@@ -650,13 +721,13 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5FL_blk_alloc(H5FL_blk_head_t *head, size_t size, unsigned clear)
+H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size)
{
H5FL_blk_node_t *free_list; /* The free list of nodes of correct size */
H5FL_blk_list_t *temp; /* Temp. ptr to the new native list allocated */
void *ret_value; /* Pointer to the block to return to the user */
- FUNC_ENTER_NOAPI(H5FL_blk_alloc, NULL);
+ FUNC_ENTER_NOAPI(H5FL_blk_malloc, NULL);
/* Double check parameters */
assert(head);
@@ -702,13 +773,50 @@ H5FL_blk_alloc(H5FL_blk_head_t *head, size_t size, unsigned clear)
ret_value=((char *)temp)+sizeof(H5FL_blk_list_t);
} /* end else */
- /* Clear the block to zeros, if requested */
- if(clear)
- HDmemset(ret_value,0,size);
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FL_blk_malloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_calloc
+ *
+ * Purpose: Allocates memory for a block and clear it to zeros.
+ * This routine is used
+ * instead of malloc because the block can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: valid pointer to the block
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size)
+{
+ void *ret_value; /* Pointer to the block to return to the user */
+
+ FUNC_ENTER_NOAPI(H5FL_blk_calloc, NULL);
+
+ /* Double check parameters */
+ assert(head);
+
+ /* Allocate the block */
+ if (NULL==(ret_value = H5FL_blk_malloc(head,size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* Clear the block to zeros */
+ HDmemset(ret_value,0,size);
done:
FUNC_LEAVE(ret_value);
-} /* end H5FL_blk_alloc() */
+} /* end H5FL_blk_calloc() */
/*-------------------------------------------------------------------------
@@ -818,7 +926,7 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size)
/* check if we are actually changing the size of the buffer */
if(new_size!=temp->size) {
- if((ret_value=H5FL_blk_alloc(head,new_size,0))==NULL)
+ if((ret_value=H5FL_blk_malloc(head,new_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block");
blk_size=MIN(new_size,temp->size);
HDmemcpy(ret_value,block,blk_size);
@@ -829,7 +937,7 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size)
} /* end if */
/* Not re-allocating, just allocate a fresh block */
else
- ret_value=H5FL_blk_alloc(head,new_size,0);
+ ret_value=H5FL_blk_malloc(head,new_size);
done:
FUNC_LEAVE(ret_value);
@@ -1141,7 +1249,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FL_arr_alloc
+ * Function: H5FL_arr_malloc
*
* Purpose: Allocate an array of objects
*
@@ -1156,13 +1264,13 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5FL_arr_alloc(H5FL_arr_head_t *head, size_t elem, unsigned clear)
+H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
{
H5FL_arr_node_t *new_obj; /* Pointer to the new free list node allocated */
void *ret_value; /* Pointer to object to return */
size_t mem_size; /* Size of memory block being recycled */
- FUNC_ENTER_NOAPI(H5FL_arr_alloc, NULL);
+ FUNC_ENTER_NOAPI(H5FL_arr_malloc, NULL);
/* Double check parameters */
assert(head);
@@ -1215,18 +1323,51 @@ H5FL_arr_alloc(H5FL_arr_head_t *head, size_t elem, unsigned clear)
/* Get a pointer to the new block */
ret_value=((char *)new_obj)+sizeof(H5FL_arr_node_t);
} /* end else */
-
- /* Clear to zeros, if asked */
- if(clear)
- HDmemset(ret_value,0,mem_size);
} /* end if */
/* No fixed number of elements, use PQ routine */
else
- ret_value=H5FL_blk_alloc(&(head->u.queue),mem_size,clear);
+ ret_value=H5FL_blk_malloc(&(head->u.queue),mem_size);
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_arr_malloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_arr_calloc
+ *
+ * Purpose: Allocate an array of objects and clear it to zeros
+ *
+ * Return: Success: Pointer to a valid array object
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem)
+{
+ void *ret_value; /* Pointer to object to return */
+
+ FUNC_ENTER_NOAPI(H5FL_arr_calloc, NULL);
+
+ /* Double check parameters */
+ assert(head);
+
+ /* Allocate the array */
+ if (NULL==(ret_value = H5FL_arr_malloc(head,elem)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* Clear to zeros */
+ HDmemset(ret_value,0,head->size*elem);
done:
FUNC_LEAVE (ret_value);
-} /* end H5FL_arr_alloc() */
+} /* end H5FL_arr_calloc() */
/*-------------------------------------------------------------------------
@@ -1258,7 +1399,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem)
/* Check if we are really allocating the object */
if(obj==NULL) {
- ret_value=H5FL_arr_alloc(head,new_elem,0);
+ ret_value=H5FL_arr_malloc(head,new_elem);
} /* end if */
else {
/* Check if there is a maximum number of elements in array */
@@ -1272,7 +1413,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem)
/* Check if the size is really changing */
if(temp->nelem!=new_elem) {
/* Get the new array of objects */
- ret_value=H5FL_arr_alloc(head,new_elem,0);
+ ret_value=H5FL_arr_malloc(head,new_elem);
/* Copy the appropriate amount of elements */
blk_size=head->size*MIN(temp->nelem,new_elem);
diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h
index 35b3555..72e28d8 100644
--- a/src/H5FLprivate.h
+++ b/src/H5FLprivate.h
@@ -66,7 +66,10 @@ typedef struct H5FL_reg_head_t {
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE(t)
/* Allocate an object of type 't' */
-#define H5FL_ALLOC(t,clr) H5FL_reg_alloc(&(t##_free_list),clr)
+#define H5FL_MALLOC(t) H5FL_reg_malloc(&(t##_free_list))
+
+/* Allocate an object of type 't' and clear it to all zeros */
+#define H5FL_CALLOC(t) H5FL_reg_calloc(&(t##_free_list))
/* Free an object of type 't' */
#define H5FL_FREE(t,obj) H5FL_reg_free(&(t##_free_list),obj)
@@ -80,7 +83,8 @@ typedef struct H5FL_reg_head_t {
#define H5FL_DEFINE(t) int t##_reg_free_list_placeholder
#define H5FL_EXTERN(t) extern int t##_reg_free_list_placeholder
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE(t)
-#define H5FL_ALLOC(t,clr) (clr ? H5MM_calloc(sizeof(t)) : H5MM_malloc(sizeof(t)))
+#define H5FL_MALLOC(t) H5MM_malloc(sizeof(t))
+#define H5FL_CALLOC(t) H5MM_calloc(sizeof(t))
#define H5FL_FREE(t,obj) H5MM_xfree(obj)
#endif /* H5_NO_REG_FREE_LISTS */
@@ -124,7 +128,10 @@ typedef struct H5FL_blk_head_t {
#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE(t)
/* Allocate an block of type 't' */
-#define H5FL_BLK_ALLOC(t,size,clr) H5FL_blk_alloc(&(t##_pq),size,clr)
+#define H5FL_BLK_MALLOC(t,size) H5FL_blk_malloc(&(t##_pq),size)
+
+/* Allocate an block of type 't' and clear it to zeros */
+#define H5FL_BLK_CALLOC(t,size) H5FL_blk_calloc(&(t##_pq),size)
/* Free a block of type 't' */
#define H5FL_BLK_FREE(t,blk) H5FL_blk_free(&(t##_pq),blk)
@@ -132,13 +139,18 @@ typedef struct H5FL_blk_head_t {
/* Re-allocate a block of type 't' */
#define H5FL_BLK_REALLOC(t,blk,new_size) H5FL_blk_realloc(&(t##_pq),blk,new_size)
+/* Check if there is a free block available to re-use */
+#define H5FL_BLK_AVAIL(t,size) H5FL_blk_free_block_avail(&(t##_pq),size)
+
#else /* H5_NO_BLK_FREE_LISTS */
#define H5FL_BLK_DEFINE(t) int t##_blk_free_list_placeholder
#define H5FL_BLK_EXTERN(t) extern int t##_blk_free_list_placeholder
#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE(t)
-#define H5FL_BLK_ALLOC(t,size,clr) (clr ? H5MM_calloc(size) : H5MM_malloc(size))
+#define H5FL_BLK_MALLOC(t,size) H5MM_malloc(size)
+#define H5FL_BLK_CALLOC(t,size) H5MM_calloc(size)
#define H5FL_BLK_FREE(t,blk) H5MM_xfree(blk)
#define H5FL_BLK_REALLOC(t,blk,new_size) H5MM_realloc(blk,new_size)
+#define H5FL_BLK_AVAIL(t,size) (FALSE)
#endif /* H5_NO_BLK_FREE_LISTS */
/* Data structure to store each array in free list */
@@ -178,7 +190,10 @@ typedef struct H5FL_arr_head_t {
#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE(t,m)
/* Allocate an array of type 't' */
-#define H5FL_ARR_ALLOC(t,elem,clr) H5FL_arr_alloc(&(t##_arr_free_list),elem,clr)
+#define H5FL_ARR_MALLOC(t,elem) H5FL_arr_malloc(&(t##_arr_free_list),elem)
+
+/* Allocate an array of type 't' and clear it to all zeros */
+#define H5FL_ARR_CALLOC(t,elem) H5FL_arr_calloc(&(t##_arr_free_list),elem)
/* Free an array of type 't' */
#define H5FL_ARR_FREE(t,obj) H5FL_arr_free(&(t##_arr_free_list),obj)
@@ -190,7 +205,8 @@ typedef struct H5FL_arr_head_t {
#define H5FL_ARR_DEFINE(t,m) int t##_arr_free_list_placeholder
#define H5FL_ARR_EXTERN(t) extern int t##_arr_free_list_placeholder
#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE(t,m)
-#define H5FL_ARR_ALLOC(t,elem,clr) (clr ? H5MM_calloc(elem*sizeof(t)) : H5MM_malloc(elem*sizeof(t)))
+#define H5FL_ARR_MALLOC(t,elem) H5MM_malloc(elem*sizeof(t))
+#define H5FL_ARR_CALLOC(t,elem) H5MM_calloc(elem*sizeof(t))
#define H5FL_ARR_FREE(t,obj) H5MM_xfree(obj)
#define H5FL_ARR_REALLOC(t,obj,new_elem) H5MM_realloc(obj,new_elem*sizeof(t))
#endif /* H5_NO_ARR_FREE_LISTS */
@@ -198,12 +214,16 @@ typedef struct H5FL_arr_head_t {
/*
* Library prototypes.
*/
-H5_DLL void * H5FL_blk_alloc(H5FL_blk_head_t *head, size_t size, unsigned clear);
+H5_DLL void * H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size);
+H5_DLL void * H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size);
H5_DLL void * H5FL_blk_free(H5FL_blk_head_t *head, void *block);
H5_DLL void * H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size);
-H5_DLL void * H5FL_reg_alloc(H5FL_reg_head_t *head, unsigned clear);
+H5_DLL htri_t H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size);
+H5_DLL void * H5FL_reg_malloc(H5FL_reg_head_t *head);
+H5_DLL void * H5FL_reg_calloc(H5FL_reg_head_t *head);
H5_DLL void * H5FL_reg_free(H5FL_reg_head_t *head, void *obj);
-H5_DLL void * H5FL_arr_alloc(H5FL_arr_head_t *head, size_t elem, unsigned clear);
+H5_DLL void * H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem);
+H5_DLL void * H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem);
H5_DLL void * H5FL_arr_free(H5FL_arr_head_t *head, void *obj);
H5_DLL void * H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem);
H5_DLL herr_t H5FL_garbage_coll(void);
diff --git a/src/H5FO.c b/src/H5FO.c
new file mode 100644
index 0000000..29f3998
--- /dev/null
+++ b/src/H5FO.c
@@ -0,0 +1,277 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ * Open object info algorithms.
+ *
+ * These are used to track the objects currently open in a file, for various
+ * internal mechanisms which need to be aware of such things.
+ *
+ */
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5FOprivate.h" /* File objects */
+
+#define PABLO_MASK H5FO_mask
+
+/* Interface initialization */
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/* Private typedefs */
+
+/* Information about object objects in a file */
+typedef struct H5FO_open_obj_t {
+ haddr_t addr; /* Address of object header for object */
+ /* THIS MUST BE FIRST FOR TBBT ROUTINES */
+ hid_t id; /* Current ID for object */
+} H5FO_open_obj_t;
+
+/* Declare a free list to manage the H5FO_open_obj_t struct */
+H5FL_DEFINE_STATIC(H5FO_open_obj_t);
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FO_create
+ PURPOSE
+ Create an open object info set
+ USAGE
+ herr_t H5FO_create(f)
+ H5F_t *f; IN/OUT: File to create opened object info set for
+
+ RETURNS
+ Returns non-negative on success, negative on failure
+ DESCRIPTION
+ Create a new open object info set.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5FO_create(H5F_t *f)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FO_create,FAIL);
+
+ /* Sanity check */
+ assert(f);
+ assert(f->shared);
+
+ /* Create TBBT used to store open object info */
+ if((f->shared->open_objs=H5TB_fast_dmake(H5TB_FAST_HADDR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object TBBT");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FO_create() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FO_opened
+ PURPOSE
+ Checks if an object at an address is already open in the file.
+ USAGE
+ hid_t H5FO_opened(f,addr)
+ const H5F_t *f; IN: File to check opened object info set
+ haddr_t addr; IN: Address of object to check
+
+ RETURNS
+ Returns a non-negative ID for the object on success, negative on failure
+ DESCRIPTION
+ Check is an object at an address (the address of the object's object header)
+ is already open in the file and return the ID for that object if it is open.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t
+H5FO_opened(const H5F_t *f, haddr_t addr)
+{
+ H5TB_NODE *obj_node; /* TBBT node holding open object */
+ H5FO_open_obj_t *open_obj; /* Information about open object */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FO_opened,FAIL);
+
+ /* Sanity check */
+ assert(f);
+ assert(f->shared);
+ assert(f->shared->open_objs);
+ assert(H5F_addr_defined(addr));
+
+ /* Get the object node from the TBBT */
+ if((obj_node=H5TB_dfind(f->shared->open_objs,&addr,NULL))!=NULL) {
+ open_obj=H5TB_NODE_DATA(obj_node);
+ assert(open_obj);
+ ret_value=open_obj->id;
+ assert(ret_value>0);
+ } /* end if */
+ else
+ ret_value=FAIL;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FO_opened() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FO_insert
+ PURPOSE
+ Insert a newly opened object/ID pair into the opened object info set
+ USAGE
+ herr_t H5FO_insert(f,addr,id)
+ H5F_t *f; IN/OUT: File's opened object info set
+ haddr_t addr; IN: Address of object to insert
+ hid_t id; IN: ID of object to insert
+
+ RETURNS
+ Returns a non-negative on success, negative on failure
+ DESCRIPTION
+ Insert an object/ID pair into the opened object info set.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5FO_insert(H5F_t *f, haddr_t addr, hid_t id)
+{
+ H5FO_open_obj_t *open_obj; /* Information about open object */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FO_insert,FAIL);
+
+ /* Sanity check */
+ assert(f);
+ assert(f->shared);
+ assert(f->shared->open_objs);
+ assert(H5F_addr_defined(addr));
+ assert(id>0);
+
+ /* Allocate new opened object information structure */
+ if((open_obj=H5FL_MALLOC(H5FO_open_obj_t))==NULL)
+ HGOTO_ERROR(H5E_CACHE,H5E_NOSPACE,NULL,"memory allocation failed");
+
+ /* Assign information */
+ open_obj->addr=addr;
+ open_obj->id=id;
+
+ /* Insert into TBBT */
+ if(H5TB_dins(f->shared->open_objs,open_obj,open_obj)==NULL)
+ HGOTO_ERROR(H5E_CACHE,H5E_CANTINSERT,FAIL,"can't insert object into TBBT");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FO_insert() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FO_delete
+ PURPOSE
+ Remove an opened object/ID pair from the opened object info set
+ USAGE
+ herr_t H5FO_delete(f,addr)
+ H5F_t *f; IN/OUT: File's opened object info set
+ haddr_t addr; IN: Address of object to remove
+
+ RETURNS
+ Returns a non-negative on success, negative on failure
+ DESCRIPTION
+ Remove an object/ID pair from the opened object info.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5FO_delete(H5F_t *f, haddr_t addr)
+{
+ H5TB_NODE *obj_node; /* TBBT node holding open object */
+ H5FO_open_obj_t *open_obj; /* Information about open object */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FO_delete,FAIL);
+
+ /* Sanity check */
+ assert(f);
+ assert(f->shared);
+ assert(f->shared->open_objs);
+ assert(H5F_addr_defined(addr));
+
+ /* Get the object node from the TBBT */
+ if((obj_node=H5TB_dfind(f->shared->open_objs,&addr,NULL))==NULL)
+ HGOTO_ERROR(H5E_CACHE,H5E_NOTFOUND,FAIL,"can't locate object in TBBT");
+
+ /* Remove from TBBT */
+ if((open_obj=H5TB_rem(&f->shared->open_objs->root,obj_node,NULL))==NULL)
+ HGOTO_ERROR(H5E_CACHE,H5E_CANTRELEASE,FAIL,"can't remove object from TBBT");
+
+ /* Release the object information */
+ H5FL_FREE(H5FO_open_obj_t,open_obj);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FO_delete() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FO_dest
+ PURPOSE
+ Destroy an open object info set
+ USAGE
+ herr_t H5FO_create(f)
+ H5F_t *f; IN/OUT: File's opened object info set
+
+ RETURNS
+ Returns a non-negative on success, negative on failure
+ DESCRIPTION
+ Destroy an existing open object info set.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5FO_dest(H5F_t *f)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FO_dest,FAIL);
+
+ /* Sanity check */
+ assert(f);
+ assert(f->shared);
+ assert(f->shared->open_objs);
+
+ /* Check if the object info set is empty */
+ if(H5TB_count(f->shared->open_objs)!=0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "objects still in open object info set");
+
+ /* Release the open object info set TBBT */
+ f->shared->open_objs=H5TB_dfree(f->shared->open_objs,NULL,NULL);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FO_dest() */
+
diff --git a/src/H5FOprivate.h b/src/H5FOprivate.h
new file mode 100644
index 0000000..6f89ec2
--- /dev/null
+++ b/src/H5FOprivate.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ * This file contains library private information about the H5FO module
+ */
+#ifndef _H5FOprivate_H
+#define _H5FOprivate_H
+
+#ifdef LATER
+#include "H5FOpublic.h"
+#endif /* LATER */
+
+/* Private headers needed by this file */
+#include "H5private.h"
+#include "H5TBprivate.h" /* TBBTs */
+
+/* Typedefs */
+
+/* Typedef for open object cache */
+typedef H5TB_TREE H5FO_t; /* Currently, all open objects are stored in TBBT */
+
+/* Macros */
+
+/* Private routines */
+H5_DLL herr_t H5FO_create(H5F_t *f);
+H5_DLL hid_t H5FO_opened(const H5F_t *f, haddr_t addr);
+H5_DLL herr_t H5FO_insert(H5F_t *f, haddr_t addr, hid_t id);
+H5_DLL herr_t H5FO_delete(H5F_t *f, haddr_t addr);
+H5_DLL herr_t H5FO_dest(H5F_t *f);
+
+#endif /* _H5FOprivate_H */
+
diff --git a/src/H5FPclient.c b/src/H5FPclient.c
index cae4c60..7912b4e 100644
--- a/src/H5FPclient.c
+++ b/src/H5FPclient.c
@@ -583,6 +583,7 @@ H5FP_update_file_cache(hid_t file_id, struct SAP_sync *sap_sync, uint8_t *msg)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
switch (sap_sync->action) {
+#ifdef OLD_WAY
case H5FP_ACT_CREATE:
if (sap_sync->obj_type == H5FP_OBJ_DATASET) {
H5O_efl_t efl;
@@ -598,7 +599,7 @@ H5FP_update_file_cache(hid_t file_id, struct SAP_sync *sap_sync, uint8_t *msg)
fmeta->sdim->size, fmeta->sdim->max) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set dimensions");
- if (H5D_update_entry_cache(file, ent, H5G_entof(grp),
+ if (H5D_update_entry_info(file, ent, H5G_entof(grp),
fmeta->dset->s, space,
fmeta->plist, fmeta->layout, fmeta->dtype,
FALSE, fmeta->header) == FAIL)
@@ -607,7 +608,7 @@ H5FP_update_file_cache(hid_t file_id, struct SAP_sync *sap_sync, uint8_t *msg)
if (H5P_get(fmeta->plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
- if (H5D_update_external_storage_cache(file, ent, &efl, fmeta->layout) == FAIL)
+ if (H5D_update_external_storage_info(file, ent, &efl, fmeta->layout) == FAIL)
HGOTO_ERROR(H5E_FPHDF5, H5E_CANTINIT, FAIL,
"can't update external file layout metadata cache");
}
@@ -624,6 +625,7 @@ H5FP_update_file_cache(hid_t file_id, struct SAP_sync *sap_sync, uint8_t *msg)
}
break;
+#endif /* OLD_WAY */
case H5FP_ACT_DELETE:
default:
diff --git a/src/H5Fcontig.c b/src/H5Fcontig.c
index fce1ba9..a63a9ce 100644
--- a/src/H5Fcontig.c
+++ b/src/H5Fcontig.c
@@ -36,8 +36,11 @@ static int interface_initialize_g = 0;
/* Declare a PQ free list to manage the sieve buffer information */
H5FL_BLK_DEFINE(sieve_buf);
-/* Extern the free list to manage blocks of type conversion data */
-H5FL_BLK_EXTERN(type_conv);
+/* Declare the free list to manage blocks of non-zero fill-value data */
+H5FL_BLK_DEFINE_STATIC(non_zero_fill);
+
+/* Declare the free list to manage blocks of zero fill-value data */
+H5FL_BLK_DEFINE_STATIC(zero_fill);
/*-------------------------------------------------------------------------
@@ -56,11 +59,10 @@ H5FL_BLK_EXTERN(type_conv);
*/
herr_t
H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5S_t *space,
- size_t elmt_size)
+ struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
+ const struct H5S_t *space,
+ const struct H5O_fill_t *fill, size_t elmt_size)
{
- H5O_fill_t fill; /* Fill value information */
- H5O_efl_t efl; /* External File List info */
hssize_t snpoints; /* Number of points in space (for error checking) */
size_t npoints; /* Number of points in space */
size_t ptsperbuf; /* Maximum # of points which fit in the buffer */
@@ -77,6 +79,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
unsigned blocks_written=0; /* Flag to indicate that chunk was actually written */
unsigned using_mpi=0; /* Flag to indicate that the file is being accessed with an MPI-capable file driver */
#endif /* H5_HAVE_PARALLEL */
+ int non_zero_fill_f=(-1); /* Indicate that a non-zero fill-value was used */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_contig_fill, FAIL);
@@ -91,12 +94,6 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
assert(space);
assert(elmt_size>0);
- /* Get necessary properties from dataset creation property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "can't get fill value");
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
-
#ifdef H5_HAVE_PARALLEL
/* Retrieve up MPI parameters */
if(IS_H5FD_MPIO(f)) {
@@ -136,46 +133,62 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
assert(snpoints>=0);
H5_ASSIGN_OVERFLOW(npoints,snpoints,hssize_t,size_t);
- /* Don't write default fill-values to external files */
- if(efl.nused>0 && !fill.buf)
- HGOTO_DONE(SUCCEED);
-
- /* If fill value is library default, use the element size */
- if(!fill.buf)
- fill.size=elmt_size;
+ /* If fill value is not library default, use it to set the element size */
+ if(fill->buf)
+ elmt_size=fill->size;
/*
* Fill the entire current extent with the fill value. We can do
* this quite efficiently by making sure we copy the fill value
* in relatively large pieces.
*/
- ptsperbuf = MAX(1, bufsize/fill.size);
- bufsize = ptsperbuf*fill.size;
-
- /* Allocate temporary buffer */
- if ((buf=H5FL_BLK_ALLOC(type_conv,bufsize,0))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer");
-
- /* Fill the buffer with the user's fill value */
- if(fill.buf)
- H5V_array_fill(buf, fill.buf, fill.size, ptsperbuf);
- else /* Fill the buffer with the default fill value */
- HDmemset(buf,0,bufsize);
+ ptsperbuf = MAX(1, bufsize/elmt_size);
+ bufsize = ptsperbuf*elmt_size;
+
+ /* Fill the buffer with the user's fill value */
+ if(fill->buf) {
+ /* Allocate temporary buffer */
+ if ((buf=H5FL_BLK_MALLOC(non_zero_fill,bufsize))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer");
+
+ H5V_array_fill(buf, fill->buf, elmt_size, ptsperbuf);
+
+ /* Indicate that a non-zero fill buffer was used */
+ non_zero_fill_f=1;
+ } /* end if */
+ else { /* Fill the buffer with the default fill value */
+ htri_t buf_avail;
+
+ /* Check if there is an already zeroed out buffer available */
+ buf_avail=H5FL_BLK_AVAIL(zero_fill,bufsize);
+ assert(buf_avail!=FAIL);
+
+ /* Allocate temporary buffer (zeroing it if no buffer is available) */
+ if(!buf_avail)
+ buf=H5FL_BLK_CALLOC(zero_fill,bufsize);
+ else
+ buf=H5FL_BLK_MALLOC(zero_fill,bufsize);
+ if(buf==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer");
+
+ /* Indicate that a zero fill buffer was used */
+ non_zero_fill_f=0;
+ } /* end else */
- /* Start at the beginning of the dataset */
- addr = 0;
+ /* Start at the beginning of the dataset */
+ addr = 0;
- /* Loop through writing the fill value to the dataset */
- while (npoints>0) {
- size = MIN(ptsperbuf, npoints) * fill.size;
+ /* Loop through writing the fill value to the dataset */
+ while (npoints>0) {
+ size = MIN(ptsperbuf, npoints) * elmt_size;
#ifdef H5_HAVE_PARALLEL
/* Check if this file is accessed with an MPI-capable file driver */
if(using_mpi) {
/* Round-robin write the chunks out from only one process */
if(mpi_round==mpi_rank) {
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, space,
- fill.size, size, addr, buf)<0)
+ if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
+ elmt_size, size, addr, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
} /* end if */
mpi_round=(++mpi_round)%mpi_size;
@@ -185,8 +198,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, space,
- fill.size, size, addr, buf)<0)
+ if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
+ elmt_size, size, addr, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -211,8 +224,13 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
done:
/* Free the buffer for fill values */
- if (buf)
- H5FL_BLK_FREE(type_conv,buf);
+ if (buf) {
+ assert(non_zero_fill_f>=0);
+ if(non_zero_fill_f)
+ H5FL_BLK_FREE(non_zero_fill,buf);
+ else
+ H5FL_BLK_FREE(zero_fill,buf);
+ } /* end if */
FUNC_LEAVE(ret_value);
}
@@ -661,7 +679,7 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
} /* end if */
else {
/* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_ALLOC(sieve_buf,f->shared->sieve_buf_size,0)))
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Determine the new sieve buffer size & location */
@@ -1128,7 +1146,7 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
} /* end if */
else {
/* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_ALLOC(sieve_buf,f->shared->sieve_buf_size,0)))
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Determine the new sieve buffer size & location */
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
index ea74165..f617092 100644
--- a/src/H5Fistore.c
+++ b/src/H5Fistore.c
@@ -862,7 +862,7 @@ H5F_istore_init (H5F_t *f)
HDmemset (rdcc, 0, sizeof(H5F_rdcc_t));
if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) {
rdcc->nslots = f->shared->rdcc_nelmts;
- rdcc->slot = H5FL_ARR_ALLOC (H5F_rdcc_ent_ptr_t,rdcc->nslots,1);
+ rdcc->slot = H5FL_ARR_CALLOC (H5F_rdcc_ent_ptr_t,rdcc->nslots);
if (NULL==rdcc->slot)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
}
@@ -1440,7 +1440,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache");
/* Create a new entry */
- ent = H5FL_ALLOC(H5F_rdcc_ent_t,0);
+ ent = H5FL_MALLOC(H5F_rdcc_ent_t);
ent->locked = 0;
ent->dirty = FALSE;
ent->chunk_size = chunk_size;
@@ -1943,8 +1943,9 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
#ifdef H5_HAVE_PARALLEL
/* Additional sanity check when operating in parallel */
- if (chunk_addr==HADDR_UNDEF || pline.nfilters>0)
+ if (chunk_addr==HADDR_UNDEF || pline.nfilters>0) {
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
+ }
#endif /* H5_HAVE_PARALLEL */
/*
@@ -2312,7 +2313,7 @@ done:
*/
herr_t
H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- const hsize_t *space_dim, H5P_genplist_t *dc_plist)
+ const hsize_t *space_dim, H5P_genplist_t *dc_plist, hbool_t full_overwrite)
{
hssize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
hsize_t chunk_size; /* Size of chunk in bytes */
@@ -2407,7 +2408,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
} /* end for */
/* Check if fill values should be written to blocks */
- if(fill_time != H5D_FILL_TIME_NEVER) {
+ if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) {
/* Allocate chunk buffer for processes to use when writing fill values */
H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t);
if (NULL==(chunk = H5MM_malloc((size_t)chunk_size)))
@@ -2484,7 +2485,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk");
/* Check if fill values should be written to blocks */
- if(fill_time != H5D_FILL_TIME_NEVER) {
+ if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) {
#ifdef H5_HAVE_PARALLEL
/* Check if this file is accessed with an MPI-capable file driver */
if(using_mpi) {
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 4c42ced..9326060 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -17,10 +17,13 @@
#define _H5Fpkg_H
#include "H5Fprivate.h"
+#include "H5FOprivate.h" /* File objects */
/* This is a near top-level header! Try not to include much! */
#include "H5private.h"
+#include "H5Bpublic.h" /* B-tree header, for H5B_NUM_BTREE_ID */
+
/*
* Feature: Define this constant to be non-zero if you want to enable code
* that minimizes the number of calls to lseek(). This has a huge
@@ -94,6 +97,13 @@ typedef struct H5F_file_t {
H5FD_t *lf; /* Lower level file handle for I/O */
unsigned nrefs; /* Ref count for times file is opened */
uint32_t consist_flags; /* File Consistency Flags */
+
+ /* Cached values from FCPL */
+ size_t sizeof_addr; /* Size of addresses in file */
+ size_t sizeof_size; /* Size of offsets in file */
+ unsigned sym_leaf_k; /* Size of leaves in symbol tables */
+ int btree_k[H5B_NUM_BTREE_ID]; /* B-tree key values for each type */
+
haddr_t boot_addr; /* Absolute address of boot block */
haddr_t base_addr; /* Absolute base address for rel.addrs. */
haddr_t freespace_addr; /* Relative address of free-space info */
@@ -110,8 +120,9 @@ typedef struct H5F_file_t {
hsize_t alignment; /* Alignment */
unsigned gc_ref; /* Garbage-collect references? */
struct H5G_t *root_grp; /* Open root group */
- int ncwfs; /* Num entries on cwfs list */
+ int ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
+ H5FO_t *open_objs; /* Open objects in file */
/* Data Sieve Buffering fields */
unsigned char *sieve_buf; /* Buffer to hold data sieve buffer */
@@ -121,7 +132,7 @@ typedef struct H5F_file_t {
unsigned sieve_dirty; /* Flag to indicate that the data sieve buffer is dirty */
H5F_rdcc_t rdcc; /* Raw data chunk cache */
- H5F_close_degree_t fc_degree; /* File close behavior degree */
+ H5F_close_degree_t fc_degree; /* File close behavior degree */
} H5F_file_t;
/* A record of the mount table */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 42f174c..395b5e2 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -152,8 +152,10 @@ typedef struct H5F_t H5F_t;
(X)+(haddr_t)(Z)<(X))
#define H5F_addr_hash(X,M) ((unsigned)((X)%(M)))
#define H5F_addr_defined(X) (X!=HADDR_UNDEF)
+/* The H5F_addr_eq() macro guarantees that Y is not HADDR_UNDEF by making
+ * certain that X is not HADDR_UNDEF and then checking that X equals Y
+ */
#define H5F_addr_eq(X,Y) ((X)!=HADDR_UNDEF && \
- (Y)!=HADDR_UNDEF && \
(X)==(Y))
#define H5F_addr_ne(X,Y) (!H5F_addr_eq((X),(Y)))
#define H5F_addr_lt(X,Y) ((X)!=HADDR_UNDEF && \
@@ -174,12 +176,22 @@ typedef struct H5F_t H5F_t;
#define H5F_addr_overlap(O1,L1,O2,L2) ((O1<O2 && (O1+L1)>O2) || \
(O1>=O2 && O1<(O2+L2)))
+/* If the module using this macro is allowed access to the private variables, access them directly */
+#ifdef H5F_PACKAGE
/* size of size_t and off_t as they exist on disk */
+#define H5F_SIZEOF_ADDR(F) ((F)->shared->sizeof_addr)
+#define H5F_SIZEOF_SIZE(F) ((F)->shared->sizeof_size)
+/* Size of symbol table leafs */
+#define H5F_SYM_LEAF_K(F) ((F)->shared->sym_leaf_k)
+/* B-tree key value size */
+#define H5F_KVALUE(F,T) ((F)->shared->btree_k[(T)->id])
+#else /* H5F_PACKAGE */
#define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F))
#define H5F_SIZEOF_SIZE(F) (H5F_sizeof_size(F))
+#define H5F_SYM_LEAF_K(F) (H5F_sym_leaf_k(F))
+#define H5F_KVALUE(F,T) (H5F_Kvalue(F,T))
+#endif /* H5F_PACKAGE */
-H5_DLL size_t H5F_sizeof_addr(const H5F_t *f);
-H5_DLL size_t H5F_sizeof_size(const H5F_t *f);
/* Macros to encode/decode offset/length's for storing in the file */
#ifdef NOT_YET
@@ -344,6 +356,7 @@ struct H5O_pline_t;
struct H5O_fill_t;
struct H5P_genplist_t;
struct H5S_t;
+struct H5B_class_t;
/* Private functions, not part of the publicly documented API */
H5_DLL herr_t H5F_init(void);
@@ -356,6 +369,17 @@ H5_DLL herr_t H5F_get_obj_ids(H5F_t *f, unsigned types, hid_t *obj_id_list);
H5_DLL herr_t H5F_get_vfd_handle(H5F_t *file, hid_t fapl, void** file_handle);
H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
+/* Functions than check file mounting information */
+H5_DLL htri_t H5F_is_mount(const H5F_t *file);
+H5_DLL htri_t H5F_has_mount(const H5F_t *file);
+
+/* Functions than retrieve values set from the FCPL */
+H5_DLL size_t H5F_sizeof_addr(const H5F_t *f);
+H5_DLL size_t H5F_sizeof_size(const H5F_t *f);
+H5_DLL unsigned H5F_sym_leaf_k(const H5F_t *f);
+H5_DLL int H5F_Kvalue(const H5F_t *f, const struct H5B_class_t *type);
+
+
/* Functions that operate on array storage */
H5_DLL herr_t H5F_arr_read (H5F_t *f, hid_t dxpl_id,
const struct H5O_layout_t *layout,
@@ -381,24 +405,24 @@ H5_DLL herr_t H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr,
/* Functions that operate on byte sequences */
H5_DLL herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id,
const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
+ struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
const struct H5S_t *file_space, size_t elmt_size, size_t seq_len,
hsize_t file_offset, void *_buf/*out*/);
H5_DLL herr_t H5F_seq_write (H5F_t *f, hid_t dxpl_id,
struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
+ struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
const struct H5S_t *file_space, size_t elmt_size, size_t seq_len,
hsize_t file_offset, const void *_buf);
/* Functions that operate on vectors of byte sequences */
H5_DLL herr_t H5F_seq_readv(H5F_t *f, hid_t dxpl_id,
const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
+ struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
const struct H5S_t *file_space, size_t elmt_size, size_t nseq,
size_t seq_len[], hsize_t file_offset[], void *_buf/*out*/);
H5_DLL herr_t H5F_seq_writev(H5F_t *f, hid_t dxpl_id,
struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
+ struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
const struct H5S_t *file_space, size_t elmt_size, size_t nseq,
size_t seq_len[], hsize_t file_offset[], const void *_buf);
@@ -406,15 +430,15 @@ H5_DLL herr_t H5F_seq_writev(H5F_t *f, hid_t dxpl_id,
/* Functions that operate on contiguous storage */
H5_DLL herr_t H5F_contig_fill(H5F_t *f, hid_t dxpl_id,
struct H5O_layout_t *layout, struct H5P_genplist_t *dc_plist,
- const struct H5S_t *space, size_t elmt_size);
+ const struct H5O_efl_t *efl, const struct H5S_t *space,
+ const struct H5O_fill_t *fill, size_t elmt_size);
/* Functions that operate on indexed storage */
H5_DLL herr_t H5F_istore_create(H5F_t *f,
struct H5O_layout_t *layout/*in,out*/);
H5_DLL herr_t H5F_istore_allocate (H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
- const hsize_t *space_dim,
- struct H5P_genplist_t *dc_plist);
+ const struct H5O_layout_t *layout, const hsize_t *space_dim,
+ struct H5P_genplist_t *dc_plist, hbool_t full_overwrite);
H5_DLL hsize_t H5F_istore_allocated(H5F_t *f, unsigned ndims, haddr_t addr);
H5_DLL herr_t H5F_istore_dump_btree(H5F_t *f, FILE *stream, unsigned ndims,
haddr_t addr);
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index adddd83..edee20b 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -28,13 +28,25 @@
* which are compatible with the library to which the application is linked.
* We're assuming that these constants are used rather early in the hdf5
* session.
+ *
+ * NOTE: When adding H5F_ACC_* macros, remember to redefine them in H5Fprivate.h
+ *
*/
-#define H5F_ACC_RDONLY (H5check(),0x0000u) /*absence of rdwr => rd-only */
-#define H5F_ACC_RDWR (H5check(),0x0001u) /*open for read and write */
-#define H5F_ACC_TRUNC (H5check(),0x0002u) /*overwrite existing files */
-#define H5F_ACC_EXCL (H5check(),0x0004u) /*fail if file already exists*/
-#define H5F_ACC_DEBUG (H5check(),0x0008u) /*print debug info */
-#define H5F_ACC_CREAT (H5check(),0x0010u) /*create non-existing files */
+
+/* When this header is included from H5Fprivate.h, don't make calls to H5check() */
+#undef H5CHECK
+#ifndef _H5Fprivate_H
+#define H5CHECK H5check(),
+#else /* _H5Fprivate_H */
+#define H5CHECK
+#endif /* _H5Fprivate_H */
+
+#define H5F_ACC_RDONLY (H5CHECK 0x0000u) /*absence of rdwr => rd-only */
+#define H5F_ACC_RDWR (H5CHECK 0x0001u) /*open for read and write */
+#define H5F_ACC_TRUNC (H5CHECK 0x0002u) /*overwrite existing files */
+#define H5F_ACC_EXCL (H5CHECK 0x0004u) /*fail if file already exists*/
+#define H5F_ACC_DEBUG (H5CHECK 0x0008u) /*print debug info */
+#define H5F_ACC_CREAT (H5CHECK 0x0010u) /*create non-existing files */
#define H5F_OBJ_FILE (0x0001u)
#define H5F_OBJ_DATASET (0x0002u)
diff --git a/src/H5Fseq.c b/src/H5Fseq.c
index 6176003..9592725 100644
--- a/src/H5Fseq.c
+++ b/src/H5Fseq.c
@@ -59,9 +59,9 @@ static int interface_initialize_g = 0;
*/
herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const H5S_t *file_space, size_t elmt_size,
- size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ const H5S_t *file_space, size_t elmt_size,
+ size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -70,10 +70,11 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
done:
@@ -104,9 +105,9 @@ done:
*/
herr_t
H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const H5S_t *file_space, size_t elmt_size,
- size_t seq_len, hsize_t dset_offset, const void *buf)
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ const H5S_t *file_space, size_t elmt_size,
+ size_t seq_len, hsize_t dset_offset, const void *buf)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -115,10 +116,11 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -151,7 +153,7 @@ done:
*/
herr_t
H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
const H5S_t *file_space, size_t elmt_size,
size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
void *_buf/*out*/)
@@ -172,7 +174,6 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
unsigned u; /*counters */
size_t v; /*counters */
int i,j; /*counters */
- struct H5O_efl_t efl; /* External File List info */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
H5P_genplist_t *plist=NULL; /* Property list */
@@ -184,6 +185,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(real_buf);
/* Make certain we have the correct type of property list */
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
@@ -221,14 +223,10 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
- /* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get EFL value");
-
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Read directly from file if the dataset is in an external file */
- if (efl.nused>0) {
+ if (efl->nused>0) {
/* Iterate through the sequence vectors */
for(v=0; v<nseq; v++) {
#ifdef H5_HAVE_PARALLEL
@@ -260,7 +258,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
* file offsets, totally mixing up the data sieve buffer information. -QAK
*/
H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_read(f, &efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
+ if (H5O_efl_read(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
/* Increment offset in buffer */
@@ -281,7 +279,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/*
* This method is unable to access external raw data files
*/
- if (efl.nused>0)
+ if (efl->nused>0)
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
/* Compute the file offset coordinates and hyperslab size */
@@ -542,7 +540,7 @@ done:
*/
herr_t
H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
const H5S_t *file_space, size_t elmt_size,
size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
const void *_buf)
@@ -563,7 +561,6 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
unsigned u; /*counters */
size_t v; /*counters */
int i,j; /*counters */
- struct H5O_efl_t efl; /* External File List info */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
H5P_genplist_t *plist=NULL; /* Property list */
@@ -575,6 +572,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/* Check args */
assert(f);
assert(layout);
+ assert(efl);
assert(real_buf);
/* Make certain we have the correct type of property list */
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
@@ -612,14 +610,10 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on chunked datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
- /* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get EFL value");
-
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Write directly to file if the dataset is in an external file */
- if (efl.nused>0) {
+ if (efl->nused>0) {
/* Iterate through the sequence vectors */
for(v=0; v<nseq; v++) {
#ifdef H5_HAVE_PARALLEL
@@ -650,7 +644,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
* file offsets, totally mixing up the data sieve buffer information. -QAK
*/
H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_write(f, &efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
+ if (H5O_efl_write(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
/* Increment offset in buffer */
@@ -671,7 +665,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/*
* This method is unable to access external raw data files
*/
- if (efl.nused>0)
+ if (efl->nused>0)
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
/* Compute the file offset coordinates and hyperslab size */
diff --git a/src/H5G.c b/src/H5G.c
index d6d4ea1..bc63e05 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -111,16 +111,25 @@ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
/* Struct only used by change name callback function */
typedef struct H5G_names_t {
H5G_entry_t *loc;
- const char *src_name;
+ H5RS_str_t *src_name;
H5G_entry_t *src_loc;
- const char *dst_name;
+ H5RS_str_t *dst_name;
H5G_entry_t *dst_loc;
H5G_names_op_t op;
} H5G_names_t;
+/* Enum for H5G_namei actions */
+typedef enum {
+ H5G_NAMEI_TRAVERSE, /* Just traverse groups */
+ H5G_NAMEI_INSERT /* Insert entry in group */
+}H5G_namei_act_t ;
+
/* Declare a free list to manage the H5G_t struct */
H5FL_DEFINE(H5G_t);
+/* Declare extern the PQ free list for the wrapped strings */
+H5FL_BLK_EXTERN(str_buf);
+
/* Private prototypes */
static herr_t H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key);
static herr_t H5G_traverse_slink(H5G_entry_t *grp_ent/*in,out*/,
@@ -1186,21 +1195,28 @@ H5G_basename(const char *name, size_t *size_p)
* Modified to deep copies of symbol table entries
* Added `id to name' support.
*
+ * Quincey Koziol, 2003-01-06
+ * Added "action" and "ent" parameters to allow different actions when
+ * working on the last component of a name. (Specifically, this allows
+ * inserting an entry into a group, instead of trying to look it up)
+ *
*-------------------------------------------------------------------------
*/
static herr_t
H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/,
- unsigned target, int *nlinks/*out*/)
+ unsigned target, int *nlinks/*out*/, H5G_namei_act_t action,
+ H5G_entry_t *ent)
{
H5G_entry_t _grp_ent; /*entry for current group */
H5G_entry_t _obj_ent; /*entry found */
size_t nchars; /*component name length */
int _nlinks = H5G_NLINKS;
const char *s = NULL;
- unsigned null_obj = obj_ent == NULL ? 1 : 0; /* Flag to indicate this function was called with obj_ent set to NULL */
- unsigned null_grp = grp_ent == NULL ? 1 : 0; /* Flag to indicate this function was called with grp_ent set to NULL */
- unsigned group_copy = 0; /* Flag to indicate that the group entry is copied */
+ unsigned null_obj; /* Flag to indicate this function was called with obj_ent set to NULL */
+ unsigned null_grp; /* Flag to indicate this function was called with grp_ent set to NULL */
+ unsigned group_copy = 0; /* Flag to indicate that the group entry is copied */
+ unsigned last_comp = 0; /* Flag to indicate that a component is the last component in the name */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5G_namei);
@@ -1209,13 +1225,17 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
if (rest)
*rest = name;
if (!grp_ent) {
- HDmemset(&_grp_ent,0,sizeof(H5G_entry_t));
grp_ent = &_grp_ent;
+ null_grp = 1;
} /* end if */
+ else
+ null_grp = 0;
if (!obj_ent) {
- HDmemset(&_obj_ent,0,sizeof(H5G_entry_t));
obj_ent = &_obj_ent;
+ null_obj = 1;
} /* end if */
+ else
+ null_obj = 0;
if (!nlinks)
nlinks = &_nlinks;
@@ -1293,21 +1313,46 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
/* Set flag that we've copied a new entry into the group entry */
group_copy =1;
- if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/ )<0) {
- /*
- * Component was not found in the current symbol table, possibly
- * because GRP_ENT isn't a symbol table.
- */
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
- }
+ /* Check if this is the last component of the name */
+ if(!((s=H5G_component(name+nchars, NULL)) && *s))
+ last_comp=1;
+
+ switch(action) {
+ case H5G_NAMEI_TRAVERSE:
+ if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/ )<0) {
+ /*
+ * Component was not found in the current symbol table, possibly
+ * because GRP_ENT isn't a symbol table.
+ */
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
+ }
+ break;
+
+ case H5G_NAMEI_INSERT:
+ if(!last_comp) {
+ if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/ )<0) {
+ /*
+ * Component was not found in the current symbol table, possibly
+ * because GRP_ENT isn't a symbol table.
+ */
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
+ }
+ } /* end if */
+ else {
+ if (H5G_stab_insert(grp_ent, H5G_comp_g, ent) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert name");
+ HGOTO_DONE(SUCCEED);
+ } /* end else */
+ break;
+ } /* end switch */
/*
* If we found a symbolic link then we should follow it. But if this
* is the last component of the name and the H5G_TARGET_SLINK bit of
* TARGET is set then we don't follow it.
*/
- if(H5G_CACHED_SLINK==obj_ent->type && (0==(target & H5G_TARGET_SLINK) ||
- ((s=H5G_component(name+nchars, NULL)) && *s))) {
+ if(H5G_CACHED_SLINK==obj_ent->type &&
+ (0==(target & H5G_TARGET_SLINK) || !last_comp)) {
if ((*nlinks)-- <= 0)
HGOTO_ERROR (H5E_SYM, H5E_SLINK, FAIL, "too many symbolic links");
if (H5G_traverse_slink (grp_ent, obj_ent, nlinks)<0)
@@ -1319,10 +1364,8 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
* the H5G_TARGET_MOUNT bit of TARGET is set and this is the last
* component of the name.
*/
- if (0==(target & H5G_TARGET_MOUNT) ||
- ((s=H5G_component(name+nchars, NULL)) && *s)) {
+ if (0==(target & H5G_TARGET_MOUNT) || !last_comp)
H5F_mountpoint(obj_ent/*in,out*/);
- }
/* next component */
name += nchars;
@@ -1376,7 +1419,7 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
const char *clv = NULL; /*cached link value */
char *linkval = NULL; /*the copied link value */
H5G_entry_t tmp_grp_ent; /* Temporary copy of group entry */
- char *tmp_user_path=NULL, *tmp_canon_path=NULL; /* Temporary pointer to object's user path & canonical path */
+ H5RS_str_t *tmp_user_path_r=NULL, *tmp_canon_path_r=NULL; /* Temporary pointer to object's user path & canonical path */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_traverse_slink, FAIL);
@@ -1393,10 +1436,10 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
linkval = H5MM_xstrdup (clv);
/* Hold the entry's name (& old_name) to restore later */
- tmp_user_path=obj_ent->user_path;
- obj_ent->user_path=NULL;
- tmp_canon_path=obj_ent->canon_path;
- obj_ent->canon_path=NULL;
+ tmp_user_path_r=obj_ent->user_path_r;
+ obj_ent->user_path_r=NULL;
+ tmp_canon_path_r=obj_ent->canon_path_r;
+ obj_ent->canon_path_r=NULL;
/* Free the names for the group entry */
H5G_free_ent_name(grp_ent);
@@ -1405,24 +1448,24 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
H5G_ent_copy(&tmp_grp_ent,grp_ent,H5G_COPY_DEEP);
/* Traverse the link */
- if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks))
+ if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks, H5G_NAMEI_TRAVERSE, NULL))
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link");
/* Free the entry's names, we will use the original name for the object */
H5G_free_ent_name(obj_ent);
/* Restore previous name for object */
- obj_ent->user_path = tmp_user_path;
- tmp_user_path=NULL;
- obj_ent->canon_path = tmp_canon_path;
- tmp_canon_path=NULL;
+ obj_ent->user_path_r = tmp_user_path_r;
+ tmp_user_path_r=NULL;
+ obj_ent->canon_path_r = tmp_canon_path_r;
+ tmp_canon_path_r=NULL;
done:
/* Error cleanup */
- if(tmp_user_path)
- H5MM_xfree(tmp_user_path);
- if(tmp_canon_path)
- H5MM_xfree(tmp_canon_path);
+ if(tmp_user_path_r)
+ H5RS_decr(tmp_user_path_r);
+ if(tmp_canon_path_r)
+ H5RS_decr(tmp_canon_path_r);
/* Release cloned copy of group entry */
H5G_free_ent_name(&tmp_grp_ent);
@@ -1475,6 +1518,7 @@ H5G_mkroot (H5F_t *f, H5G_entry_t *ent)
*/
if (!ent) {
ent = &new_root;
+ HDmemset(ent, 0, sizeof(H5G_entry_t));
if (H5G_stab_create (f, 256, ent/*out*/)<0)
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create root group");
if (1 != H5O_link (ent, 1))
@@ -1493,10 +1537,10 @@ H5G_mkroot (H5F_t *f, H5G_entry_t *ent)
}
/* Create the path names for the root group's entry */
- ent->user_path=HDstrdup("/");
- assert(ent->user_path);
- ent->canon_path=HDstrdup("/");
- assert(ent->canon_path);
+ ent->user_path_r=H5RS_create("/");
+ assert(ent->user_path_r);
+ ent->canon_path_r=H5RS_create("/");
+ assert(ent->canon_path_r);
ent->user_path_hidden=0;
/*
@@ -1504,7 +1548,7 @@ H5G_mkroot (H5F_t *f, H5G_entry_t *ent)
* don't count the root group as an open object. The root group will
* never be closed.
*/
- if (NULL==(f->shared->root_grp = H5FL_ALLOC (H5G_t,1)))
+ if (NULL==(f->shared->root_grp = H5FL_CALLOC (H5G_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
f->shared->root_grp->ent = *ent;
f->shared->root_grp->nref = 1;
@@ -1544,11 +1588,8 @@ done:
H5G_t *
H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint)
{
- const char *rest = NULL; /*the base name */
- H5G_entry_t grp_ent; /*group containing new group */
- char _comp[1024]; /*name component */
- size_t nchars; /*number of characters in compon*/
H5G_t *grp = NULL; /*new group */
+ H5F_t *file; /* File new group will be in */
H5G_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_create, NULL);
@@ -1557,51 +1598,28 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint)
assert(loc);
assert(name && *name);
- /* lookup name */
- if (0 == H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL, NULL))
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "already exists");
- H5E_clear(); /*it's OK that we didn't find it */
- assert(H5F_addr_defined(grp_ent.header));
-
- /* should be one null-terminated component left */
- rest = H5G_component(rest, &nchars);
- assert(rest && *rest);
- if (rest[nchars]) {
- const char *t = H5G_component(rest+nchars, NULL);
- if (t && *t) {
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "missing component");
- } else if (nchars+1 > sizeof _comp) {
- HGOTO_ERROR(H5E_SYM, H5E_COMPLEN, NULL, "component is too long");
- } else {
- /* null terminate */
- HDmemcpy(_comp, rest, nchars);
- _comp[nchars] = '\0';
- rest = _comp;
- }
- }
-
/* create an open group */
- if (NULL==(grp = H5FL_ALLOC(H5G_t,1)))
+ if (NULL==(grp = H5FL_CALLOC(H5G_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (H5G_stab_create(grp_ent.file, size_hint, &(grp->ent)/*out*/) < 0)
+
+ /* What file is the group being added to? */
+ if (NULL==(file=H5G_insertion_file(loc, name)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to locate insertion point");
+
+ /* Create the group entry */
+ if (H5G_stab_create(file, size_hint, &(grp->ent)/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp");
/* insert child name into parent */
- if (1!=H5O_link(&(grp->ent), 1))
- HGOTO_ERROR(H5E_SYM, H5E_LINK, NULL, "link inc failure");
- if (H5G_stab_insert(&grp_ent, rest, &(grp->ent)) < 0) {
- H5O_close(&(grp->ent));
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't insert");
- }
+ if(H5G_insert(loc,name,&(grp->ent))<0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group");
+
grp->nref = 1;
/* Set return value */
ret_value=grp;
done:
- /* Free the group entry created from H5G_namei() */
- H5G_free_ent_name(&grp_ent);
-
if(ret_value==NULL) {
if(grp!=NULL)
H5FL_FREE(H5G_t,grp);
@@ -1733,7 +1751,7 @@ H5G_open_oid(H5G_entry_t *ent)
assert(ent);
/* Open the object, making sure it's a group */
- if (NULL==(grp = H5FL_ALLOC(H5G_t,1)))
+ if (NULL==(grp = H5FL_CALLOC(H5G_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Copy over (take ownership) of the group entry object */
@@ -1894,10 +1912,6 @@ done:
herr_t
H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent)
{
- const char *rest = NULL; /*part of name not existing yet */
- H5G_entry_t grp; /*entry for group to contain obj */
- size_t nchars; /*number of characters in name */
- char _comp[1024]; /*name component */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_insert, FAIL);
@@ -1908,44 +1922,18 @@ H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent)
assert (ent);
/*
- * Look up the name -- it shouldn't exist yet.
+ * Lookup and insert the name -- it shouldn't exist yet.
*/
- if (H5G_namei(loc, name, &rest, &grp, NULL, H5G_TARGET_NORMAL, NULL)>=0)
+ if (H5G_namei(loc, name, NULL, NULL, NULL, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_INSERT, ent)<0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "already exists");
- H5E_clear(); /*it's OK that we didn't find it */
- rest = H5G_component(rest, &nchars);
-
- /*
- * There should be one component left. Make sure it's null
- * terminated.
- */
- if (rest[nchars]) {
- if (H5G_component(rest + nchars, NULL)) {
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
- } else if (nchars + 1 > sizeof _comp) {
- HGOTO_ERROR(H5E_SYM, H5E_COMPLEN, FAIL, "component is too long");
- } else {
- /* null terminate */
- HDmemcpy(_comp, rest, nchars);
- _comp[nchars] = '\0';
- rest = _comp;
- }
- }
/*
* Insert the object into a symbol table.
*/
if (H5O_link(ent, 1) < 0)
HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count");
- if (H5G_stab_insert(&grp, rest, ent) < 0) {
- H5O_link(ent, -1);
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to insert name");
- }
done:
- /*Free the ID to name buffer */
- H5G_free_ent_name(&grp);
-
FUNC_LEAVE(ret_value);
}
@@ -1989,7 +1977,7 @@ H5G_find(H5G_entry_t *loc, const char *name,
assert (loc);
assert (name && *name);
- if (H5G_namei(loc, name, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, NULL)<0)
+ if (H5G_namei(loc, name, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
done:
@@ -2184,8 +2172,8 @@ H5G_link (H5G_entry_t *cur_loc, const char *cur_name, H5G_entry_t *new_loc,
* Lookup the the new_name so we can get the group which will contain
* the new entry. The entry shouldn't exist yet.
*/
- if (H5G_namei (new_loc, new_name, &rest, &grp_ent, NULL,
- H5G_TARGET_NORMAL, NULL)>=0)
+ if (H5G_namei(new_loc, new_name, &rest, &grp_ent, NULL,
+ H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL)>=0)
HGOTO_ERROR (H5E_SYM, H5E_EXISTS, FAIL, "already exists");
H5E_clear (); /*it's okay that we didn't find it*/
rest = H5G_component (rest, &nchars);
@@ -2239,7 +2227,7 @@ H5G_link (H5G_entry_t *cur_loc, const char *cur_name, H5G_entry_t *new_loc,
break;
case H5G_LINK_HARD:
- if (H5G_namei(cur_loc, cur_name, NULL, NULL, &cur_obj, namei_flags, NULL)<0)
+ if (H5G_namei(cur_loc, cur_name, NULL, NULL, &cur_obj, namei_flags, NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found");
if (H5G_insert (new_loc, new_name, &cur_obj)<0)
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object");
@@ -2339,8 +2327,8 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
if (statbuf) HDmemset (statbuf, 0, sizeof *statbuf);
/* Find the object's symbol table entry */
- if (H5G_namei (loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
- (unsigned)(follow_link?H5G_TARGET_NORMAL:H5G_TARGET_SLINK), NULL)<0)
+ if (H5G_namei(loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
+ (unsigned)(follow_link?H5G_TARGET_NORMAL:H5G_TARGET_SLINK), NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to stat object");
/*
@@ -2374,7 +2362,10 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
statbuf->type = H5G_LINK;
if (NULL==H5O_read(&obj_ent, H5O_MTIME, 0, &(statbuf->mtime))) {
H5E_clear();
- statbuf->mtime = 0;
+ if (NULL==H5O_read(&obj_ent, H5O_MTIME_NEW, 0, &(statbuf->mtime))) {
+ H5E_clear();
+ statbuf->mtime = 0;
+ }
}
statbuf->type = H5G_get_type(&obj_ent);
H5E_clear(); /*clear errors resulting from checking type*/
@@ -2450,7 +2441,7 @@ done:
ssize_t
H5G_get_objname_by_idx(H5G_t *grp, hsize_t idx, char* name, size_t size)
{
- ssize_t ret_value = FAIL;
+ ssize_t ret_value;
H5G_bt_ud3_t udata;
FUNC_ENTER_NOAPI(H5G_get_objname_by_idx, FAIL);
@@ -2472,10 +2463,10 @@ H5G_get_objname_by_idx(H5G_t *grp, hsize_t idx, char* name, size_t size)
name[size-1]='\0';
}
- /* Free the duplicated name */
- H5MM_xfree(udata.name);
-
done:
+ /* Free the duplicated name */
+ if(udata.name!=NULL)
+ H5MM_xfree(udata.name);
FUNC_LEAVE(ret_value);
}
@@ -2558,8 +2549,8 @@ H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, char *buf/*out*/)
* Get the symbol table entry for the link head and the symbol table
* entry for the group in which the link head appears.
*/
- if (H5G_namei (loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
- H5G_TARGET_SLINK, NULL)<0)
+ if (H5G_namei(loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
+ H5G_TARGET_SLINK, NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link was not found");
if (H5G_CACHED_SLINK!=obj_ent.type)
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link");
@@ -2615,7 +2606,7 @@ H5G_set_comment(H5G_entry_t *loc, const char *name, const char *buf)
/* Get the symbol table entry for the object */
if (H5G_namei(loc, name, NULL, NULL, &obj_ent/*out*/, H5G_TARGET_NORMAL,
- NULL)<0)
+ NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
/* Remove the previous comment message if any */
@@ -2624,7 +2615,7 @@ H5G_set_comment(H5G_entry_t *loc, const char *name, const char *buf)
/* Add the new message */
if (buf && *buf) {
comment.s = H5MM_xstrdup(buf);
- if (H5O_modify(&obj_ent, H5O_NAME, H5O_NEW_MESG, 0, &comment)<0)
+ if (H5O_modify(&obj_ent, H5O_NAME, H5O_NEW_MESG, 0, 1, &comment)<0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message");
H5O_reset(H5O_NAME, &comment);
}
@@ -2669,7 +2660,7 @@ H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf)
/* Get the symbol table entry for the object */
if (H5G_namei(loc, name, NULL, NULL, &obj_ent/*out*/, H5G_TARGET_NORMAL,
- NULL)<0)
+ NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
/* Get the message */
@@ -2717,6 +2708,7 @@ H5G_unlink(H5G_entry_t *loc, const char *name)
size_t len;
const char *base=NULL;
H5G_stat_t statbuf; /* Info about object to unlink */
+ H5RS_str_t *name_r; /* Ref-counted version of name */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_unlink, FAIL);
@@ -2733,7 +2725,7 @@ H5G_unlink(H5G_entry_t *loc, const char *name)
/* Get the entry for the group that contains the object to be unlinked */
if (H5G_namei(loc, name, NULL, &grp_ent, &obj_ent,
- H5G_TARGET_SLINK|H5G_TARGET_MOUNT, NULL)<0)
+ H5G_TARGET_SLINK|H5G_TARGET_MOUNT, NULL, H5G_NAMEI_TRAVERSE, NULL)<0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
if (!H5F_addr_defined(grp_ent.header))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no containing group specified");
@@ -2745,8 +2737,11 @@ H5G_unlink(H5G_entry_t *loc, const char *name)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink name from symbol table");
/* Search the open IDs and replace names for unlinked object */
- if (H5G_replace_name(statbuf.type, &obj_ent, name, NULL, NULL, NULL, OP_UNLINK )<0)
+ name_r=H5RS_wrap(name);
+ assert(name_r);
+ if (H5G_replace_name(statbuf.type, &obj_ent, name_r, NULL, NULL, NULL, OP_UNLINK )<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name");
+ H5RS_decr(name_r);
done:
/* Free the ID to name buffers */
@@ -2785,6 +2780,8 @@ H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc,
char *linkval=NULL;
size_t lv_size=32;
H5G_entry_t obj_ent; /* Object entry for object being moved */
+ H5RS_str_t *src_name_r; /* Ref-counted version of src name */
+ H5RS_str_t *dst_name_r; /* Ref-counted version of dest name */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_move, FAIL);
@@ -2825,10 +2822,16 @@ H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc,
* This has to be done here because H5G_link and H5G_unlink have
* internal object entries, and do not modify the entries list
*/
- if (H5G_namei (src_loc, src_name, NULL, NULL, &obj_ent, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, NULL))
+ if (H5G_namei(src_loc, src_name, NULL, NULL, &obj_ent, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, NULL, H5G_NAMEI_TRAVERSE, NULL))
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link");
- if (H5G_replace_name(sb.type, &obj_ent, src_name, src_loc, dst_name, dst_loc, OP_MOVE )<0)
+ src_name_r=H5RS_wrap(src_name);
+ assert(src_name_r);
+ dst_name_r=H5RS_wrap(dst_name);
+ assert(dst_name_r);
+ if (H5G_replace_name(sb.type, &obj_ent, src_name_r, src_loc, dst_name_r, dst_loc, OP_MOVE )<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ");
+ H5RS_decr(src_name_r);
+ H5RS_decr(dst_name_r);
H5G_free_ent_name(&obj_ent);
/* Remove the old name */
@@ -2864,37 +2867,53 @@ done:
H5F_t *
H5G_insertion_file(H5G_entry_t *loc, const char *name)
{
- const char *rest;
- H5G_entry_t grp_ent;
- size_t size;
H5F_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_insertion_file, NULL);
+
assert(loc);
assert(name && *name);
- /*
- * Look up the name to get the containing group and to make sure the name
- * doesn't already exist.
+ /* Check if the location the object will be inserted into is part of a
+ * file mounting chain (either a parent or a child) and perform a more
+ * rigorous determination of the location's file (which traverses into
+ * mounted files, etc.).
*/
- if (H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL, NULL)>=0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists");
- H5E_clear();
+ if(H5F_has_mount(loc->file) || H5F_is_mount(loc->file)) {
+ const char *rest;
+ H5G_entry_t grp_ent;
+ size_t size;
+
+ /*
+ * Look up the name to get the containing group and to make sure the name
+ * doesn't already exist.
+ */
+ if (H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL)>=0) {
+ H5G_free_ent_name(&grp_ent);
+ HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists");
+ } /* end if */
+ H5E_clear();
+
+ /* Make sure only the last component wasn't resolved */
+ rest = H5G_component(rest, &size);
+ assert(*rest && size>0);
+ rest = H5G_component(rest+size, NULL);
+ if (*rest) {
+ H5G_free_ent_name(&grp_ent);
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "insertion point not found");
+ } /* end if */
- /* Make sure only the last component wasn't resolved */
- rest = H5G_component(rest, &size);
- assert(*rest && size>0);
- rest = H5G_component(rest+size, NULL);
- if (*rest)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "insertion point not found");
+ /* Set return value */
+ ret_value=grp_ent.file;
- /* Set return value */
- ret_value=grp_ent.file;
+ /* Free the ID to name buffer */
+ H5G_free_ent_name(&grp_ent);
+ } /* end if */
+ else
+ /* Use the location's file */
+ ret_value=loc->file;
done:
- /* Free the ID to name buffer */
- H5G_free_ent_name(&grp_ent);
-
FUNC_LEAVE(ret_value);
}
@@ -2967,10 +2986,14 @@ H5G_free_ent_name(H5G_entry_t *ent)
/* Check args */
assert(ent);
- if(ent->user_path)
- ent->user_path = H5MM_xfree(ent->user_path);
- if(ent->canon_path)
- ent->canon_path = H5MM_xfree(ent->canon_path);
+ if(ent->user_path_r) {
+ H5RS_decr(ent->user_path_r);
+ ent->user_path_r=NULL;
+ } /* end if */
+ if(ent->canon_path_r) {
+ H5RS_decr(ent->canon_path_r);
+ ent->canon_path_r=NULL;
+ } /* end if */
done:
FUNC_LEAVE(ret_value);
@@ -3001,8 +3024,8 @@ done:
*/
herr_t
H5G_replace_name( int type, H5G_entry_t *loc,
- const char *src_name, H5G_entry_t *src_loc,
- const char *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op )
+ H5RS_str_t *src_name, H5G_entry_t *src_loc,
+ H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op )
{
H5G_names_t names; /* Structure to hold operation information for callback */
unsigned search_group=0; /* Flag to indicate that groups are to be searched */
@@ -3095,16 +3118,22 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5G_common_path(const char *fullpath, const char *prefix)
+H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r)
{
+ const char *fullpath; /* Pointer to actual fullpath string */
+ const char *prefix; /* Pointer to actual prefix string */
size_t nchars1,nchars2; /* Number of characters in components */
htri_t ret_value=FALSE; /* Return value */
FUNC_ENTER_NOINIT(H5G_common_path);
/* Get component of each name */
+ fullpath=H5RS_GET_STR(fullpath_r);
+ assert(fullpath);
fullpath=H5G_component(fullpath,&nchars1);
assert(fullpath);
+ prefix=H5RS_GET_STR(prefix_r);
+ assert(prefix);
prefix=H5G_component(prefix,&nchars2);
assert(prefix);
@@ -3199,12 +3228,11 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
*-------------------------------------------------------------------------
*/
case OP_MOUNT:
- if(ent->file->mtab.parent && HDstrcmp(ent->user_path,ent->canon_path)) {
+ if(ent->file->mtab.parent && H5RS_cmp(ent->user_path_r,ent->canon_path_r)) {
/* Find the "top" file in the chain of mounted files */
top_ent_file=ent->file->mtab.parent;
- while(top_ent_file->mtab.parent!=NULL) {
+ while(top_ent_file->mtab.parent!=NULL)
top_ent_file=top_ent_file->mtab.parent;
- } /* end while */
} /* end if */
else
top_ent_file=ent->file;
@@ -3213,8 +3241,8 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
if(top_ent_file->shared == names->loc->file->shared) {
/* Check if the source is along the entry's path */
/* (But not actually the entry itself) */
- if(H5G_common_path(ent->user_path,names->src_name) &&
- HDstrcmp(ent->user_path,names->src_name)!=0) {
+ if(H5G_common_path(ent->user_path_r,names->src_name) &&
+ H5RS_cmp(ent->user_path_r,names->src_name)!=0) {
/* Hide the user path */
ent->user_path_hidden++;
} /* end if */
@@ -3229,9 +3257,8 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
if(ent->file->mtab.parent) {
/* Find the "top" file in the chain of mounted files for the entry */
top_ent_file=ent->file->mtab.parent;
- while(top_ent_file->mtab.parent!=NULL) {
+ while(top_ent_file->mtab.parent!=NULL)
top_ent_file=top_ent_file->mtab.parent;
- } /* end while */
} /* end if */
else
top_ent_file=ent->file;
@@ -3239,9 +3266,8 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
if(names->loc->file->mtab.parent) {
/* Find the "top" file in the chain of mounted files for the location */
top_loc_file=names->loc->file->mtab.parent;
- while(top_loc_file->mtab.parent!=NULL) {
+ while(top_loc_file->mtab.parent!=NULL)
top_loc_file=top_loc_file->mtab.parent;
- } /* end while */
} /* end if */
else
top_loc_file=names->loc->file;
@@ -3249,7 +3275,7 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
if(ent->user_path_hidden) {
/* If the ID's entry is not in the file we operated on, skip it */
if(top_ent_file->shared == top_loc_file->shared) {
- if(H5G_common_path(ent->user_path,names->src_name)) {
+ if(H5G_common_path(ent->user_path_r,names->src_name)) {
/* Un-hide the user path */
ent->user_path_hidden--;
} /* end if */
@@ -3258,9 +3284,12 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
else {
/* If the ID's entry is not in the file we operated on, skip it */
if(top_ent_file->shared == top_loc_file->shared) {
- if(ent->user_path && H5G_common_path(ent->user_path,names->src_name)) {
+ if(ent->user_path_r && H5G_common_path(ent->user_path_r,names->src_name)) {
/* Free user path */
- ent->user_path=H5MM_xfree(ent->user_path);
+ if(ent->user_path_r!=NULL) {
+ H5RS_decr(ent->user_path_r);
+ ent->user_path_r=NULL;
+ } /* end if */
} /* end if */
} /* end if */
} /* end else */
@@ -3276,16 +3305,22 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
/* Check if we are referring to the same object */
if(H5F_addr_eq(ent->header, names->loc->header)) {
/* Check if the object was opened with the same canonical path as the one being moved */
- if(HDstrcmp(ent->canon_path,names->loc->canon_path)==0) {
+ if(H5RS_cmp(ent->canon_path_r,names->loc->canon_path_r)==0) {
/* Free user path */
- ent->user_path=H5MM_xfree(ent->user_path);
+ if(ent->user_path_r!=NULL) {
+ H5RS_decr(ent->user_path_r);
+ ent->user_path_r=NULL;
+ } /* end if */
} /* end if */
} /* end if */
else {
/* Check if the location being unlinked is in the canonical path for the current object */
- if(H5G_common_path(ent->canon_path,names->loc->canon_path)) {
+ if(H5G_common_path(ent->canon_path_r,names->loc->canon_path_r)) {
/* Free user path */
- ent->user_path=H5MM_xfree(ent->user_path);
+ if(ent->user_path_r!=NULL) {
+ H5RS_decr(ent->user_path_r);
+ ent->user_path_r=NULL;
+ } /* end if */
} /* end if */
} /* end else */
} /* end if */
@@ -3298,90 +3333,116 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
case OP_MOVE: /* H5Gmove case, check for relative names case */
/* If the ID's entry is not in the file we operated on, skip it */
if(ent->file->shared == names->loc->file->shared) {
- char *src_path; /* Full user path of source name */
- char *dst_path; /* Full user path of destination name */
- char *canon_src_path; /* Pointer to canonical part of source path */
- char *canon_dst_path; /* Pointer to canonical part of destination path */
+ H5RS_str_t *src_path_r; /* Full user path of source name */
+ H5RS_str_t *dst_path_r; /* Full user path of destination name */
+ H5RS_str_t *canon_src_path_r; /* Copy of canonical part of source path */
+ H5RS_str_t *canon_dst_path_r; /* Copy of canonical part of destination path */
/* Make certain that the source and destination names are full (not relative) paths */
- if(*(names->src_name)!='/') {
+ if(*(H5RS_GET_STR(names->src_name))!='/') {
+ const char *src_name; /* Pointer to raw string of src_name */
+ char *src_path; /* Full user path of source name */
+ const char *src_user_path; /* Pointer to raw string of src path */
size_t src_path_len; /* Length of the source path */
unsigned need_sep; /* Flag to indicate if separator is needed */
+ /* Get the pointer to the raw src user path */
+ src_user_path=H5RS_GET_STR(names->src_loc->user_path_r);
+
/* Get the length of the name for the source group's user path */
- src_path_len=HDstrlen(names->src_loc->user_path);
+ src_path_len=HDstrlen(src_user_path);
/* Determine if there is a trailing separator in the name */
- if(names->src_loc->user_path[src_path_len-1]=='/')
+ if(src_user_path[src_path_len-1]=='/')
need_sep=0;
else
need_sep=1;
+ /* Get the pointer to the raw src user path */
+ src_name=H5RS_GET_STR(names->src_name);
+
/* Add in the length needed for the '/' separator and the relative path */
- src_path_len+=HDstrlen(names->src_name)+need_sep;
+ src_path_len+=HDstrlen(src_name)+need_sep;
/* Allocate space for the path */
- if(NULL==(src_path = H5MM_malloc(src_path_len+1)))
+ if(NULL==(src_path = H5FL_BLK_MALLOC(str_buf,src_path_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(src_path,names->src_loc->user_path);
+ HDstrcpy(src_path,src_user_path);
if(need_sep)
HDstrcat(src_path,"/");
- HDstrcat(src_path,names->src_name);
+ HDstrcat(src_path,src_name);
+
+ /* Create reference counted string for src path */
+ src_path_r=H5RS_own(src_path);
} /* end if */
else
- src_path=HDstrdup(names->src_name);
- if(*(names->dst_name)!='/') {
- size_t dst_path_len; /* Length of the destination path */
+ src_path_r=H5RS_dup(names->src_name);
+ if(*(H5RS_GET_STR(names->dst_name))!='/') {
+ const char *dst_name; /* Pointer to raw string of dst_name */
+ char *dst_path; /* Full user path of destination name */
+ const char *dst_user_path; /* Pointer to raw string of dst path */
+ size_t dst_path_len; /* Length of the destination path */
unsigned need_sep; /* Flag to indicate if separator is needed */
+ /* Get the pointer to the raw dst user path */
+ dst_user_path=H5RS_GET_STR(names->dst_loc->user_path_r);
+
/* Get the length of the name for the destination group's user path */
- dst_path_len=HDstrlen(names->dst_loc->user_path);
+ dst_path_len=HDstrlen(dst_user_path);
/* Determine if there is a trailing separator in the name */
- if(names->dst_loc->user_path[dst_path_len-1]=='/')
+ if(dst_user_path[dst_path_len-1]=='/')
need_sep=0;
else
need_sep=1;
+ /* Get the pointer to the raw dst user path */
+ dst_name=H5RS_GET_STR(names->dst_name);
+
/* Add in the length needed for the '/' separator and the relative path */
- dst_path_len+=HDstrlen(names->dst_name)+need_sep;
+ dst_path_len+=HDstrlen(dst_name)+need_sep;
/* Allocate space for the path */
- if(NULL==(dst_path = H5MM_malloc(dst_path_len+1)))
+ if(NULL==(dst_path = H5FL_BLK_MALLOC(str_buf,dst_path_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(dst_path,names->dst_loc->user_path);
+ HDstrcpy(dst_path,dst_user_path);
if(need_sep)
HDstrcat(dst_path,"/");
- HDstrcat(dst_path,names->dst_name);
+ HDstrcat(dst_path,dst_name);
+
+ /* Create reference counted string for dst path */
+ dst_path_r=H5RS_own(dst_path);
} /* end if */
else
- dst_path=HDstrdup(names->dst_name);
+ dst_path_r=H5RS_dup(names->dst_name);
/* Get the canonical parts of the source and destination names */
/* Check if the object being moved was accessed through a mounted file */
- if(HDstrcmp(names->loc->user_path,names->loc->canon_path)!=0) {
+ if(H5RS_cmp(names->loc->user_path_r,names->loc->canon_path_r)!=0) {
size_t non_canon_name_len; /* Length of non-canonical part of name */
/* Get current string lengths */
- non_canon_name_len=HDstrlen(names->loc->user_path)-HDstrlen(names->loc->canon_path);
+ non_canon_name_len=H5RS_len(names->loc->user_path_r)-H5RS_len(names->loc->canon_path_r);
- canon_src_path=src_path+non_canon_name_len;
- canon_dst_path=dst_path+non_canon_name_len;
+ canon_src_path_r=H5RS_create(H5RS_GET_STR(src_path_r)+non_canon_name_len);
+ canon_dst_path_r=H5RS_create(H5RS_GET_STR(dst_path_r)+non_canon_name_len);
} /* end if */
else {
- canon_src_path=src_path;
- canon_dst_path=dst_path;
+ canon_src_path_r=H5RS_dup(src_path_r);
+ canon_dst_path_r=H5RS_dup(dst_path_r);
} /* end else */
/* Check if the link being changed in the file is along the canonical path for this object */
- if(H5G_common_path(ent->canon_path,canon_src_path)) {
+ if(H5G_common_path(ent->canon_path_r,canon_src_path_r)) {
size_t user_dst_len; /* Length of destination user path */
size_t canon_dst_len; /* Length of destination canonical path */
- char *old_user_path; /* Pointer to previous user path */
- char *tail_path; /* Pointer to "tail" of path */
+ const char *old_user_path; /* Pointer to previous user path */
+ char *new_user_path; /* Pointer to new user path */
+ char *new_canon_path; /* Pointer to new canonical path */
+ const char *tail_path; /* Pointer to "tail" of path */
size_t tail_len; /* Pointer to "tail" of path */
char *src_canon_prefix; /* Pointer to source canonical path prefix of component which is moving */
size_t src_canon_prefix_len;/* Length of the source canonical path prefix */
@@ -3391,6 +3452,12 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
size_t user_prefix_len; /* Length of the user path prefix */
char *src_comp; /* The source name of the component which is actually changing */
char *dst_comp; /* The destination name of the component which is actually changing */
+ const char *canon_src_path; /* pointer to canonical part of source path */
+ const char *canon_dst_path; /* pointer to canonical part of destination path */
+
+ /* Get the pointers to the raw strings */
+ canon_src_path=H5RS_GET_STR(canon_src_path_r);
+ canon_dst_path=H5RS_GET_STR(canon_dst_path_r);
/* Get the source & destination components */
src_comp=HDstrrchr(canon_src_path,'/');
@@ -3411,46 +3478,48 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
HDstrncpy(dst_canon_prefix,canon_dst_path,dst_canon_prefix_len);
dst_canon_prefix[dst_canon_prefix_len]='\0';
+ /* Hold this for later use */
+ old_user_path=H5RS_GET_STR(ent->user_path_r);
+
/* Find the user prefix for the entry */
- user_prefix_len=HDstrlen(ent->user_path)-HDstrlen(ent->canon_path);
+ user_prefix_len=HDstrlen(old_user_path)-H5RS_len(ent->canon_path_r);
if(NULL==(user_prefix = H5MM_malloc(user_prefix_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrncpy(user_prefix,ent->user_path,user_prefix_len);
+ HDstrncpy(user_prefix,old_user_path,user_prefix_len);
user_prefix[user_prefix_len]='\0';
- /* Hold this for later use */
- old_user_path=ent->user_path;
-
/* Set the tail path info */
tail_path=old_user_path+user_prefix_len+src_canon_prefix_len+HDstrlen(src_comp);
tail_len=HDstrlen(tail_path);
- /* Free the old canonical path */
- H5MM_xfree(ent->canon_path);
-
/* Get the length of the destination paths */
user_dst_len=user_prefix_len+dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len;
canon_dst_len=dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len;
/* Allocate space for the new user path */
- if(NULL==(ent->user_path = H5MM_malloc(user_dst_len+1)))
+ if(NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_dst_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Allocate space for the new canonical path */
- if(NULL==(ent->canon_path = H5MM_malloc(canon_dst_len+1)))
+ if(NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_dst_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Create the new names */
- HDstrcpy(ent->user_path,user_prefix);
- HDstrcat(ent->user_path,dst_canon_prefix);
- HDstrcat(ent->user_path,dst_comp);
- HDstrcat(ent->user_path,tail_path);
- HDstrcpy(ent->canon_path,dst_canon_prefix);
- HDstrcat(ent->canon_path,dst_comp);
- HDstrcat(ent->canon_path,tail_path);
-
- /* Free the old user path */
- H5MM_xfree(old_user_path);
+ HDstrcpy(new_user_path,user_prefix);
+ HDstrcat(new_user_path,dst_canon_prefix);
+ HDstrcat(new_user_path,dst_comp);
+ HDstrcat(new_user_path,tail_path);
+ HDstrcpy(new_canon_path,dst_canon_prefix);
+ HDstrcat(new_canon_path,dst_comp);
+ HDstrcat(new_canon_path,tail_path);
+
+ /* Release the old user & canonical paths */
+ H5RS_decr(ent->user_path_r);
+ H5RS_decr(ent->canon_path_r);
+
+ /* Take ownership of the new user & canonical paths */
+ ent->user_path_r=H5RS_own(new_user_path);
+ ent->canon_path_r=H5RS_own(new_canon_path);
/* Free the extra paths allocated */
H5MM_xfree(src_canon_prefix);
@@ -3460,8 +3529,10 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
/* Free the extra paths allocated */
- H5MM_xfree(src_path);
- H5MM_xfree(dst_path);
+ H5RS_decr(src_path_r);
+ H5RS_decr(dst_path_r);
+ H5RS_decr(canon_src_path_r);
+ H5RS_decr(canon_dst_path_r);
} /* end if */
break;
diff --git a/src/H5Gent.c b/src/H5Gent.c
index 4e0a4f9..3bf1a58 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -357,6 +357,9 @@ done:
* of the functions in the library.
* - Added 'depth' parameter to determine how much of the group
* entry structure we want to copy. The new depths are:
+ * H5G_COPY_NULL - Copy all the fields from the
+ * source to the destination, but set the destination's
+ * user path and canonical path to NULL.
* H5G_COPY_LIMITED - Copy all the fields from the
* source to the destination, except for the user path
* field, keeping it the same as its
@@ -373,19 +376,19 @@ done:
herr_t
H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_ent_copy_depth_t depth)
{
- char *tmp_user_path=NULL; /* Temporary string pointers for entry's user path */
+ H5RS_str_t *tmp_user_path_r=NULL; /* Temporary string pointer for entry's user path */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_ent_copy, FAIL);
- /* check arguments */
- assert( src );
- assert( dst );
+ /* Check arguments */
+ assert(src);
+ assert(dst);
/* If the depth is "very shallow", keep the old entry's user path */
if(depth==H5G_COPY_LIMITED) {
- tmp_user_path=dst->user_path;
- H5MM_xfree(dst->canon_path);
+ tmp_user_path_r=dst->user_path_r;
+ H5RS_decr(dst->canon_path_r);
} /* end if */
/* Copy the top level information */
@@ -393,11 +396,14 @@ H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_ent_copy_depth_t dept
/* Deep copy the names */
if(depth==H5G_COPY_DEEP) {
- dst->user_path=H5MM_xstrdup(src->user_path);
- dst->canon_path=H5MM_xstrdup(src->canon_path);
+ dst->user_path_r=H5RS_dup(src->user_path_r);
+ dst->canon_path_r=H5RS_dup(src->canon_path_r);
} else if(depth==H5G_COPY_LIMITED) {
- dst->user_path=tmp_user_path;
- dst->canon_path=H5MM_xstrdup(src->canon_path);
+ dst->user_path_r=tmp_user_path_r;
+ dst->canon_path_r=H5RS_dup(src->canon_path_r);
+ } else if(depth==H5G_COPY_NULL) {
+ dst->user_path_r=NULL;
+ dst->canon_path_r=NULL;
} /* end if */
done:
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 98fde41..d850910 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -224,7 +224,7 @@ H5G_node_size(H5F_t *f)
FUNC_ENTER_NOINIT(H5G_node_size);
FUNC_LEAVE(H5G_NODE_SIZEOF_HDR(f) +
- (2 * H5G_node_k(f)) * H5G_SIZEOF_ENTRY(f));
+ (2 * H5F_SYM_LEAF_K(f)) * H5G_SIZEOF_ENTRY(f));
}
@@ -267,13 +267,13 @@ H5G_node_create(H5F_t *f, H5B_ins_t UNUSED op, void *_lt_key,
assert(f);
assert(H5B_INS_FIRST == op);
- if (NULL==(sym = H5FL_ALLOC(H5G_node_t,1)))
+ if (NULL==(sym = H5FL_CALLOC(H5G_node_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
size = H5G_node_size(f);
if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, size)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space");
sym->dirty = TRUE;
- sym->entry = H5FL_ARR_ALLOC(H5G_entry_t,(2*H5G_node_k(f)),1);
+ sym->entry = H5FL_ARR_CALLOC(H5G_entry_t,(2*H5F_SYM_LEAF_K(f)));
if (NULL==sym->entry)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
if (H5AC_set(f, H5AC_SNODE, *addr_p, sym) < 0)
@@ -366,7 +366,7 @@ H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_
size = H5G_node_size(f);
/* Allocate temporary buffer */
- if ((buf=H5FL_BLK_ALLOC(symbol_node,size, 0))==NULL)
+ if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
p=buf;
@@ -401,10 +401,6 @@ H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_
* preempted from the cache.
*/
if (destroy) {
- /* Free the ID to name buffer */
- for (i=0; i<sym->nsyms; i++)
- H5G_free_ent_name(&(sym->entry[i]));
-
sym->entry = H5FL_ARR_FREE(H5G_entry_t,sym->entry);
H5FL_FREE(H5G_node_t,sym);
}
@@ -460,11 +456,11 @@ H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED _udata1
* Initialize variables.
*/
size = H5G_node_size(f);
- if ((buf=H5FL_BLK_ALLOC(symbol_node,size,0))==NULL)
+ if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for symbol table node");
p=buf;
- if (NULL==(sym = H5FL_ALLOC(H5G_node_t,1)) ||
- NULL==(sym->entry=H5FL_ARR_ALLOC(H5G_entry_t,(2*H5G_node_k(f)),1)))
+ if (NULL==(sym = H5FL_CALLOC(H5G_node_t)) ||
+ NULL==(sym->entry=H5FL_ARR_CALLOC(H5G_entry_t,(2*H5F_SYM_LEAF_K(f)))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node");
@@ -534,6 +530,7 @@ H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key;
H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key;
const char *s1, *s2;
+ const char *base; /* Base of heap */
int ret_value;
FUNC_ENTER_NOAPI(H5G_node_cmp2, FAIL);
@@ -542,11 +539,14 @@ H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
assert(lt_key);
assert(rt_key);
- if (NULL == (s1 = H5HL_peek(f, udata->heap_addr, lt_key->offset)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name");
- if (NULL == (s2 = H5HL_peek(f, udata->heap_addr, rt_key->offset)))
+ /* Get base address of heap */
+ if (NULL == (base = H5HL_peek(f, udata->heap_addr, 0)))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name");
+ /* Get pointers to string names */
+ s1=base+lt_key->offset;
+ s2=base+rt_key->offset;
+
/* Set return value */
ret_value = HDstrcmp(s1, s2);
@@ -585,23 +585,26 @@ done:
static int
H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
{
- H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata;
- H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key;
- H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key;
- const char *s;
- int ret_value=0; /* Return value */
+ H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata;
+ H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key;
+ H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key;
+ const char *s;
+ const char *base; /* Base of heap */
+ int ret_value=0; /* Return value */
FUNC_ENTER_NOAPI(H5G_node_cmp3, FAIL);
- /* left side */
- if (NULL == (s = H5HL_peek(f, udata->heap_addr, lt_key->offset)))
+ /* Get base address of heap */
+ if (NULL == (base = H5HL_peek(f, udata->heap_addr, 0)))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name");
+
+ /* left side */
+ s=base+lt_key->offset;
if (HDstrcmp(udata->name, s) <= 0)
HGOTO_DONE(-1);
/* right side */
- if (NULL == (s = H5HL_peek(f, udata->heap_addr, rt_key->offset)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name");
+ s=base+rt_key->offset;
if (HDstrcmp(udata->name, s) > 0)
HGOTO_DONE(1);
@@ -647,6 +650,7 @@ H5G_node_found(H5F_t *f, haddr_t addr, const void UNUSED *_lt_key,
H5G_node_t *sn = NULL;
int lt = 0, idx = 0, rt, cmp = 1;
const char *s;
+ const char *base; /* Base of heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_node_found, FAIL);
@@ -664,14 +668,17 @@ H5G_node_found(H5F_t *f, haddr_t addr, const void UNUSED *_lt_key,
if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node");
+ /* Get base address of heap */
+ if (NULL == (base = H5HL_peek(f, bt_udata->heap_addr, 0)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name");
+
/*
* Binary search.
*/
rt = sn->nsyms;
while (lt < rt && cmp) {
idx = (lt + rt) / 2;
- if (NULL == (s = H5HL_peek(f, bt_udata->heap_addr, sn->entry[idx].name_off)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name");
+ s=base+sn->entry[idx].name_off;
cmp = HDstrcmp(bt_udata->name, s);
if (cmp < 0) {
@@ -750,10 +757,11 @@ H5G_node_insert(H5F_t *f, haddr_t addr, void UNUSED *_lt_key,
H5G_node_t *sn = NULL, *snrt = NULL;
size_t offset; /*offset of name in heap */
const char *s;
+ const char *base; /* Base of heap */
int idx = -1, cmp = 1;
int lt = 0, rt; /*binary search cntrs */
- H5B_ins_t ret_value = H5B_INS_ERROR;
H5G_node_t *insert_into = NULL; /*node that gets new entry*/
+ H5B_ins_t ret_value = H5B_INS_ERROR;
FUNC_ENTER_NOAPI(H5G_node_insert, H5B_INS_ERROR);
@@ -773,14 +781,17 @@ H5G_node_insert(H5F_t *f, haddr_t addr, void UNUSED *_lt_key,
if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node");
+ /* Get base address of heap */
+ if (NULL == (base = H5HL_peek(f, bt_udata->heap_addr, 0)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to read symbol name");
+
/*
* Where does the new symbol get inserted? We use a binary search.
*/
rt = sn->nsyms;
while (lt < rt) {
idx = (lt + rt) / 2;
- if (NULL == (s = H5HL_peek(f, bt_udata->heap_addr, sn->entry[idx].name_off)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to read symbol name");
+ s=base+sn->entry[idx].name_off;
if (0 == (cmp = HDstrcmp(bt_udata->name, s))) /*already present */
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "symbol is already present in symbol table");
if (cmp < 0) {
@@ -799,7 +810,7 @@ H5G_node_insert(H5F_t *f, haddr_t addr, void UNUSED *_lt_key,
bt_udata->ent.name_off = offset;
if (0==offset || (size_t)(-1)==offset)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap");
- if ((size_t)(sn->nsyms) >= 2*H5G_node_k(f)) {
+ if ((size_t)(sn->nsyms) >= 2*H5F_SYM_LEAF_K(f)) {
/*
* The node is full. Split it into a left and right
* node and return the address of the new right node (the
@@ -811,31 +822,31 @@ H5G_node_insert(H5F_t *f, haddr_t addr, void UNUSED *_lt_key,
if (H5G_node_create(f, H5B_INS_FIRST, NULL, NULL, NULL,
new_node_p/*out*/)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node");
- if (NULL==(snrt=H5AC_find(f, H5AC_SNODE, *new_node_p, NULL, NULL)))
+ if (NULL==(snrt=H5AC_find_f(f, H5AC_SNODE, *new_node_p, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node");
- HDmemcpy(snrt->entry, sn->entry + H5G_node_k(f),
- H5G_node_k(f) * sizeof(H5G_entry_t));
- snrt->nsyms = H5G_node_k(f);
+ HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f),
+ H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t));
+ snrt->nsyms = H5F_SYM_LEAF_K(f);
snrt->dirty = TRUE;
/* The left node */
- HDmemset(sn->entry + H5G_node_k(f), 0,
- H5G_node_k(f) * sizeof(H5G_entry_t));
- sn->nsyms = H5G_node_k(f);
+ HDmemset(sn->entry + H5F_SYM_LEAF_K(f), 0,
+ H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t));
+ sn->nsyms = H5F_SYM_LEAF_K(f);
sn->dirty = TRUE;
/* The middle key */
md_key->offset = sn->entry[sn->nsyms - 1].name_off;
/* Where to insert the new entry? */
- if (idx <= (int)H5G_node_k(f)) {
+ if (idx <= (int)H5F_SYM_LEAF_K(f)) {
insert_into = sn;
- if (idx == (int)H5G_node_k(f))
+ if (idx == (int)H5F_SYM_LEAF_K(f))
md_key->offset = offset;
} else {
- idx -= H5G_node_k(f);
+ idx -= H5F_SYM_LEAF_K(f);
insert_into = snrt;
- if (idx == (int)H5G_node_k (f)) {
+ if (idx == (int)H5F_SYM_LEAF_K (f)) {
rt_key->offset = offset;
*rt_key_changed = TRUE;
}
@@ -856,7 +867,7 @@ H5G_node_insert(H5F_t *f, haddr_t addr, void UNUSED *_lt_key,
HDmemmove(insert_into->entry + idx + 1,
insert_into->entry + idx,
(insert_into->nsyms - idx) * sizeof(H5G_entry_t));
- H5G_ent_copy(&(insert_into->entry[idx]), &(bt_udata->ent),H5G_COPY_DEEP);
+ H5G_ent_copy(&(insert_into->entry[idx]), &(bt_udata->ent),H5G_COPY_NULL);
insert_into->entry[idx].dirty = TRUE;
insert_into->nsyms += 1;
@@ -905,9 +916,10 @@ H5G_node_remove(H5F_t *f, haddr_t addr, void *_lt_key/*in,out*/,
H5G_node_key_t *rt_key = (H5G_node_key_t*)_rt_key;
H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t*)_udata;
H5G_node_t *sn = NULL;
- H5B_ins_t ret_value = H5B_INS_ERROR;
int lt=0, rt, idx=0, cmp=1;
const char *s = NULL;
+ const char *base; /* Base of heap */
+ H5B_ins_t ret_value = H5B_INS_ERROR;
FUNC_ENTER_NOAPI(H5G_node_remove, H5B_INS_ERROR);
@@ -922,13 +934,15 @@ H5G_node_remove(H5F_t *f, haddr_t addr, void *_lt_key/*in,out*/,
if (NULL==(sn=H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node");
+ /* Get base address of heap */
+ if (NULL == (base = H5HL_peek(f, bt_udata->heap_addr, 0)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to read symbol name");
+
/* Find the name with a binary search */
rt = sn->nsyms;
while (lt<rt && cmp) {
idx = (lt+rt)/2;
- if (NULL==(s=H5HL_peek(f, bt_udata->heap_addr,
- sn->entry[idx].name_off)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to read symbol name");
+ s=base+sn->entry[idx].name_off;
cmp = HDstrcmp(bt_udata->name, s);
if (cmp<0) {
rt = idx;
@@ -941,8 +955,7 @@ H5G_node_remove(H5F_t *f, haddr_t addr, void *_lt_key/*in,out*/,
if (H5G_CACHED_SLINK==sn->entry[idx].type) {
/* Remove the symbolic link value */
- if ((s=H5HL_peek(f, bt_udata->heap_addr,
- sn->entry[idx].cache.slink.lval_offset)))
+ if ((s=H5HL_peek(f, bt_udata->heap_addr, sn->entry[idx].cache.slink.lval_offset)))
H5HL_remove(f, bt_udata->heap_addr, sn->entry[idx].cache.slink.lval_offset, HDstrlen(s)+1);
H5E_clear(); /*no big deal*/
} else {
@@ -957,9 +970,6 @@ H5G_node_remove(H5F_t *f, haddr_t addr, void *_lt_key/*in,out*/,
H5HL_remove(f, bt_udata->heap_addr, sn->entry[idx].name_off, HDstrlen(s)+1);
H5E_clear(); /*no big deal*/
- /* Free the ID to name buffer for the entry being squeezed out */
- H5G_free_ent_name(sn->entry+idx);
-
/* Remove the entry from the symbol table node */
if (1==sn->nsyms) {
/*
@@ -1070,7 +1080,7 @@ H5G_node_iterate (H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
* Save information about the symbol table node since we can't lock it
* because we're about to call an application function.
*/
- if (NULL == (sn = H5AC_find(f, H5AC_SNODE, addr, NULL, NULL)))
+ if (NULL == (sn = H5AC_find_f(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node");
nsyms = sn->nsyms;
if (NULL==(name_off = H5MM_malloc (nsyms*sizeof(name_off[0]))))
@@ -1082,12 +1092,11 @@ H5G_node_iterate (H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
/*
* Iterate over the symbol table node entries.
*/
- for (i=0, ret_value=0; i<nsyms && 0==ret_value; i++) {
+ for (i=0, ret_value=H5B_ITER_CONT; i<nsyms && H5B_ITER_CONT==ret_value; i++) {
if (bt_udata->skip>0) {
--bt_udata->skip;
} else {
- name = H5HL_peek (f, bt_udata->group->ent.cache.stab.heap_addr,
- name_off[i]);
+ name = H5HL_peek (f, bt_udata->group->ent.cache.stab.heap_addr, name_off[i]);
assert (name);
n = HDstrlen (name);
if (n+1>sizeof(buf)) {
@@ -1149,7 +1158,7 @@ H5G_node_sumup(H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
assert(num_objs);
/* Find the object node and add the number of symbol entries. */
- if (NULL == (sn = H5AC_find(f, H5AC_SNODE, addr, NULL, NULL)))
+ if (NULL == (sn = H5AC_find_f(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node");
*num_objs += sn->nsyms;
@@ -1195,14 +1204,14 @@ H5G_node_name(H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
assert(bt_udata);
- if (NULL == (sn = H5AC_find(f, H5AC_SNODE, addr, NULL, NULL)))
+ if (NULL == (sn = H5AC_find_f(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node");
/* Find the node, locate the object symbol table entry and retrieve the name */
if(bt_udata->idx >= bt_udata->num_objs && bt_udata->idx < (bt_udata->num_objs+sn->nsyms)) {
loc_idx = bt_udata->idx - bt_udata->num_objs;
name_off = sn->entry[loc_idx].name_off;
- name = (const char*)H5HL_peek (f, bt_udata->group->ent.cache.stab.heap_addr, name_off);
+ name = H5HL_peek (f, bt_udata->group->ent.cache.stab.heap_addr, name_off);
assert (name);
bt_udata->name = H5MM_strdup (name);
HGOTO_DONE(H5B_ITER_STOP);
@@ -1247,7 +1256,7 @@ H5G_node_type(H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
assert(bt_udata);
/* Find the node, locate the object symbol table entry and retrieve the type */
- if (NULL == (sn = H5AC_find(f, H5AC_SNODE, addr, NULL, NULL)))
+ if (NULL == (sn = H5AC_find_f(f, H5AC_SNODE, addr, NULL, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node");
if(bt_udata->idx >= bt_udata->num_objs && bt_udata->idx < (bt_udata->num_objs+sn->nsyms)) {
@@ -1318,7 +1327,7 @@ H5G_node_debug(H5F_t *f, haddr_t addr, FILE * stream, int indent,
"Size of Node (in bytes):", (unsigned)H5G_node_size(f));
fprintf(stream, "%*s%-*s %d of %d\n", indent, "", fwidth,
"Number of Symbols:",
- sn->nsyms, 2 * H5G_node_k(f));
+ sn->nsyms, 2 * H5F_SYM_LEAF_K(f));
indent += 3;
fwidth = MAX(0, fwidth - 3);
@@ -1339,46 +1348,3 @@ done:
FUNC_LEAVE(ret_value);
}
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_k
- *
- * Purpose: Replaced a macro to retrieve the symbol table leaf size,
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-negative, and the symbol table leaf size is
- * returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Raymond Lu
- * slu@ncsa.uiuc.edu
- * Oct 14 2001
- *
- * Modifications:
- * Quincey Koziol, 2001-10-15
- * Added this header and removed unused ret_value variable.
- *-------------------------------------------------------------------------
- */
-unsigned H5G_node_k(const H5F_t *f)
-{
- unsigned sym_leaf_k;
- H5P_genplist_t *plist; /* Property list pointer */
- unsigned ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_node_k, UFAIL);
-
- assert(f);
-
- if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, UFAIL, "not a file access property list");
- if(H5P_get(plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, UFAIL, "can't get rank for symbol table leaf node");
-
- /* Set return value */
- ret_value=sym_leaf_k;
-
-done:
- FUNC_LEAVE(ret_value);
-}
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 3fc8bd3..b058ea3 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -151,7 +151,6 @@ H5_DLL herr_t H5G_ent_encode_vec(H5F_t *f, uint8_t **pp,
const H5G_entry_t *ent, int n);
/* Functions that understand symbol table nodes */
-H5_DLL unsigned H5G_node_k(const H5F_t *f);
H5_DLL H5B_iterate_t H5G_node_iterate (H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
void UNUSED *_rt_key, void *_udata);
H5_DLL H5B_iterate_t H5G_node_sumup(H5F_t *f, void UNUSED *_lt_key, haddr_t addr,
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 8515b2d..be360cb 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -26,6 +26,7 @@
#include "H5private.h"
#include "H5Bprivate.h"
#include "H5Fprivate.h"
+#include "H5RSprivate.h" /* Reference-counted strings */
/*
* Define this to enable debugging.
@@ -95,8 +96,13 @@ typedef struct H5G_entry_t {
H5G_type_t type; /*type of information cached */
H5G_cache_t cache; /*cached data from object header */
H5F_t *file; /*file to which this obj hdr belongs */
+#ifdef OLD_WAY
char *user_path; /* Path to object, as opened by user */
char *canon_path; /* Path to object, as found in file */
+#else /* OLD_WAY */
+ H5RS_str_t *user_path_r; /* Path to object, as opened by user */
+ H5RS_str_t *canon_path_r; /* Path to object, as found in file */
+#endif /* OLD_WAY */
unsigned user_path_hidden; /* Whether the user's path is valid */
} H5G_entry_t;
@@ -123,6 +129,7 @@ typedef enum {
/* Depth of group entry copy */
typedef enum {
+ H5G_COPY_NULL, /* Null destination names */
H5G_COPY_LIMITED, /* Limited copy from source to destination, omitting name & old name fields */
H5G_COPY_SHALLOW, /* Copy from source to destination, including name & old name fields */
H5G_COPY_DEEP /* Deep copy from source to destination, including duplicating name & old name fields */
@@ -174,8 +181,8 @@ H5_DLL herr_t H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent);
H5_DLL herr_t H5G_ent_decode(H5F_t *f, const uint8_t **pp,
H5G_entry_t *ent/*out*/);
H5_DLL herr_t H5G_replace_name(int type, H5G_entry_t *loc,
- const char *src_name, H5G_entry_t *src_loc,
- const char *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op);
+ H5RS_str_t *src_name, H5G_entry_t *src_loc,
+ H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op);
H5_DLL herr_t H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src,
H5G_ent_copy_depth_t depth);
H5_DLL herr_t H5G_free_grp_name(H5G_t *grp);
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index 12d0ccb..e5e2535 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -12,6 +12,7 @@
#include "H5private.h"
#include "H5Eprivate.h"
#include "H5Fpkg.h" /*file access */
+#include "H5FLprivate.h" /*Free Lists */
#include "H5Gpkg.h"
#include "H5HLprivate.h"
#include "H5MMprivate.h"
@@ -21,6 +22,9 @@
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare extern the PQ free list for the wrapped strings */
+H5FL_BLK_EXTERN(str_buf);
+
/* Private prototypes */
static herr_t H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj,
const char *name);
@@ -95,7 +99,7 @@ H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/)
* Insert the symbol table message into the object header and the symbol
* table entry.
*/
- if (H5O_modify(self, H5O_STAB, H5O_NEW_MESG, H5O_FLAG_CONSTANT, &stab)<0) {
+ if (H5O_modify(self, H5O_STAB, H5O_NEW_MESG, H5O_FLAG_CONSTANT, 1, &stab)<0) {
H5O_close(self);
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message");
}
@@ -160,8 +164,8 @@ H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
/* change OBJ_ENT only if found */
else {
if (obj_ent) {
- /* do a deep copy */
- if (H5G_ent_copy(obj_ent, &(udata.ent),H5G_COPY_DEEP)<0)
+ /* do a NULL copy, since the obj_ent name will be constructed in H5G_insert_name() */
+ if (H5G_ent_copy(obj_ent, &(udata.ent),H5G_COPY_NULL)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
/* insert the name into the symbol entry OBJ_ENT */
@@ -224,7 +228,7 @@ H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent)
udata.operation = H5G_OPER_INSERT;
udata.name = name;
udata.heap_addr = stab.heap_addr;
- H5G_ent_copy(&(udata.ent),obj_ent,H5G_COPY_SHALLOW); /* Shallow copy here, deep copy happens in H5G_node_insert() callback() */
+ H5G_ent_copy(&(udata.ent),obj_ent,H5G_COPY_NULL); /* NULL copy here, no copies happens in H5G_node_insert() callback() */
/* insert */
if (H5B_insert(grp_ent->file, H5B_SNODE, stab.btree_addr, split_ratios, &udata) < 0)
@@ -301,6 +305,8 @@ done:
static herr_t
H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
{
+ char *new_user_path; /* Pointer to new user path */
+ char *new_canon_path; /* Pointer to new canonical path */
size_t name_len; /* Length of name to append */
size_t user_path_len; /* Length of location's user path name */
size_t canon_path_len; /* Length of location's canonical path name */
@@ -313,55 +319,79 @@ H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
assert(name);
/* Only attempt to build a new name if the location's name exists */
- if(loc->canon_path) {
+ if(loc->canon_path_r) {
+ const char *loc_user_path; /* Pointer to raw string for user path */
+ const char *loc_canon_path; /* Pointer to raw string for canonical path */
/* Reset the object's previous names, if they exist */
- H5MM_xfree(obj->user_path);
- H5MM_xfree(obj->canon_path);
+ if(obj->user_path_r) {
+ H5RS_decr(obj->user_path_r);
+ obj->user_path_r=NULL;
+ } /* end if */
+ if(obj->canon_path_r) {
+ H5RS_decr(obj->canon_path_r);
+ obj->canon_path_r=NULL;
+ } /* end if */
obj->user_path_hidden=0;
/* Get the length of the strings involved */
- user_path_len = HDstrlen(loc->user_path);
- canon_path_len = HDstrlen(loc->canon_path);
+ user_path_len = H5RS_len(loc->user_path_r);
+ canon_path_len = H5RS_len(loc->canon_path_r);
name_len = HDstrlen(name);
/* Modify the object's user path */
+ /* Get the raw string for the user path */
+ loc_user_path=H5RS_GET_STR(loc->user_path_r);
+ assert(loc_user_path);
+
/* The location's user path already ends in a '/' separator */
- if ('/'==loc->user_path[user_path_len-1]) {
- if (NULL==(obj->user_path = H5MM_malloc (user_path_len+name_len+1)))
+ if ('/'==loc_user_path[user_path_len-1]) {
+ if (NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_path_len+name_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(obj->user_path, loc->user_path);
+ HDstrcpy(new_user_path, loc_user_path);
} /* end if */
/* The location's user path needs a separator */
else {
- if (NULL==(obj->user_path = H5MM_malloc (user_path_len+1+name_len+1)))
+ if (NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_path_len+1+name_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(obj->user_path, loc->user_path);
- HDstrcat(obj->user_path, "/");
+ HDstrcpy(new_user_path, loc_user_path);
+ HDstrcat(new_user_path, "/");
} /* end else */
/* Append the component's name */
- HDstrcat(obj->user_path, name);
+ HDstrcat(new_user_path, name);
+
+ /* Give ownership of the user path to the entry */
+ obj->user_path_r=H5RS_own(new_user_path);
+ assert(obj->user_path_r);
/* Modify the object's canonical path */
+ /* Get the raw string for the canonical path */
+ loc_canon_path=H5RS_GET_STR(loc->canon_path_r);
+ assert(loc_canon_path);
+
/* The location's canonical path already ends in a '/' separator */
- if ('/'==loc->canon_path[canon_path_len-1]) {
- if (NULL==(obj->canon_path = H5MM_malloc (canon_path_len+name_len+1)))
+ if ('/'==loc_canon_path[canon_path_len-1]) {
+ if (NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_path_len+name_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(obj->canon_path, loc->canon_path);
+ HDstrcpy(new_canon_path, loc_canon_path);
} /* end if */
/* The location's canonical path needs a separator */
else {
- if (NULL==(obj->canon_path = H5MM_malloc (canon_path_len+1+name_len+1)))
+ if (NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_path_len+1+name_len+1)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(obj->canon_path, loc->canon_path);
- HDstrcat(obj->canon_path, "/");
+ HDstrcpy(new_canon_path, loc_canon_path);
+ HDstrcat(new_canon_path, "/");
} /* end else */
/* Append the component's name */
- HDstrcat(obj->canon_path, name);
+ HDstrcat(new_canon_path, name);
+
+ /* Give ownership of the canonical path to the entry */
+ obj->canon_path_r=H5RS_own(new_canon_path);
+ assert(obj->canon_path_r);
} /* end if */
done:
diff --git a/src/H5HG.c b/src/H5HG.c
index bc4a6de..27a5f6d 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -127,19 +127,19 @@ H5HG_create (H5F_t *f, size_t size)
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, NULL,
"unable to allocate file space for global heap");
}
- if (NULL==(heap = H5FL_ALLOC (H5HG_heap_t,1))) {
+ if (NULL==(heap = H5FL_CALLOC (H5HG_heap_t))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
heap->addr = addr;
heap->size = size;
heap->dirty = TRUE;
- if (NULL==(heap->chunk = H5FL_BLK_ALLOC (heap_chunk,size,0))) {
+ if (NULL==(heap->chunk = H5FL_BLK_MALLOC (heap_chunk,size))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
heap->nalloc = H5HG_NOBJS (f, size);
- if (NULL==(heap->obj = H5FL_ARR_ALLOC (H5HG_obj_t,heap->nalloc,1))) {
+ if (NULL==(heap->obj = H5FL_ARR_CALLOC (H5HG_obj_t,heap->nalloc))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -246,12 +246,12 @@ H5HG_load (H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED udata1,
assert (!udata2);
/* Read the initial 4k page */
- if (NULL==(heap = H5FL_ALLOC (H5HG_heap_t,1))) {
+ if (NULL==(heap = H5FL_CALLOC (H5HG_heap_t))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
heap->addr = addr;
- if (NULL==(heap->chunk = H5FL_BLK_ALLOC (heap_chunk,H5HG_MINSIZE,0))) {
+ if (NULL==(heap->chunk = H5FL_BLK_MALLOC (heap_chunk,H5HG_MINSIZE))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -301,7 +301,7 @@ H5HG_load (H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED udata1,
/* Decode each object */
p = heap->chunk + H5HG_SIZEOF_HDR (f);
nalloc = H5HG_NOBJS (f, heap->size);
- if (NULL==(heap->obj = H5FL_ARR_ALLOC (H5HG_obj_t,nalloc,1))) {
+ if (NULL==(heap->obj = H5FL_ARR_CALLOC (H5HG_obj_t,nalloc))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -671,7 +671,7 @@ H5HG_peek (H5F_t *f, H5HG_t *hobj)
assert (hobj);
/* Load the heap and return a pointer to the object */
- if (NULL==(heap=H5AC_find (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
+ if (NULL==(heap=H5AC_find_f (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap");
assert (hobj->idx>0 && hobj->idx<heap->nalloc);
ret_value = heap->obj[hobj->idx].begin + H5HG_SIZEOF_OBJHDR (f);
@@ -679,7 +679,7 @@ H5HG_peek (H5F_t *f, H5HG_t *hobj)
/*
* Advance the heap in the CWFS list. We might have done this already
- * with the H5AC_find(), but it won't hurt to do it twice.
+ * with the H5AC_find_f(), but it won't hurt to do it twice.
*/
if (heap->obj[0].begin) {
for (i=0; i<f->shared->ncwfs; i++) {
@@ -733,7 +733,7 @@ H5HG_read (H5F_t *f, H5HG_t *hobj, void *object/*out*/)
assert (hobj);
/* Load the heap */
- if (NULL==(heap=H5AC_find (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
+ if (NULL==(heap=H5AC_find_f (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap");
assert (hobj->idx>0 && hobj->idx<heap->nalloc);
assert (heap->obj[hobj->idx].begin);
@@ -745,7 +745,7 @@ H5HG_read (H5F_t *f, H5HG_t *hobj, void *object/*out*/)
/*
* Advance the heap in the CWFS list. We might have done this already
- * with the H5AC_find(), but it won't hurt to do it twice.
+ * with the H5AC_find_f(), but it won't hurt to do it twice.
*/
if (heap->obj[0].begin) {
for (i=0; i<f->shared->ncwfs; i++) {
@@ -802,7 +802,7 @@ H5HG_link (H5F_t *f, H5HG_t *hobj, int adjust)
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
/* Load the heap */
- if (NULL==(heap=H5AC_find (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
+ if (NULL==(heap=H5AC_find_f (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
assert (hobj->idx>0 && hobj->idx<heap->nalloc);
assert (heap->obj[hobj->idx].begin);
@@ -855,7 +855,7 @@ H5HG_remove (H5F_t *f, H5HG_t *hobj)
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
/* Load the heap */
- if (NULL==(heap=H5AC_find (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
+ if (NULL==(heap=H5AC_find_f (f, H5AC_GHEAP, hobj->addr, NULL, NULL)))
HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
assert (hobj->idx>0 && hobj->idx<heap->nalloc);
assert (heap->obj[hobj->idx].begin);
@@ -899,7 +899,7 @@ H5HG_remove (H5F_t *f, H5HG_t *hobj)
} else {
/*
* If the heap is in the CWFS list then advance it one position. The
- * H5AC_find() might have done that too, but that's okay. If the
+ * H5AC_find_f() might have done that too, but that's okay. If the
* heap isn't on the CWFS list then add it to the end.
*/
for (i=0; i<f->shared->ncwfs; i++) {
@@ -959,7 +959,7 @@ H5HG_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent,
assert(indent >= 0);
assert(fwidth >= 0);
- if (NULL == (h = H5AC_find(f, H5AC_GHEAP, addr, NULL, NULL)))
+ if (NULL == (h = H5AC_find_f(f, H5AC_GHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load global heap collection");
fprintf(stream, "%*sGlobal Heap Collection...\n", indent, "");
fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
diff --git a/src/H5HL.c b/src/H5HL.c
index d9e5d9c..e4b117c 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -111,6 +111,7 @@ H5HL_create(H5F_t *f, size_t size_hint, haddr_t *addr_p/*out*/)
{
H5HL_t *heap = NULL;
hsize_t total_size; /*total heap size on disk */
+ size_t sizeof_hdr; /* Cache H5HL header size for file */
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI(H5HL_create, FAIL);
@@ -124,29 +125,32 @@ H5HL_create(H5F_t *f, size_t size_hint, haddr_t *addr_p/*out*/)
}
size_hint = H5HL_ALIGN(size_hint);
+ /* Cache this for later */
+ sizeof_hdr= H5HL_SIZEOF_HDR(f);
+
/* allocate file version */
- total_size = H5HL_SIZEOF_HDR(f) + size_hint;
+ total_size = sizeof_hdr + size_hint;
if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_LHEAP, total_size))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"unable to allocate file memory");
}
/* allocate memory version */
- if (NULL==(heap = H5FL_ALLOC(H5HL_t,1))) {
+ if (NULL==(heap = H5FL_CALLOC(H5HL_t))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
- heap->addr = *addr_p + (hsize_t)H5HL_SIZEOF_HDR(f);
+ heap->addr = *addr_p + (hsize_t)sizeof_hdr;
heap->disk_alloc = size_hint;
heap->mem_alloc = size_hint;
- if (NULL==(heap->chunk = H5FL_BLK_ALLOC(heap_chunk,(H5HL_SIZEOF_HDR(f) + size_hint),1))) {
+ if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + size_hint)))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
/* free list */
if (size_hint) {
- if (NULL==(heap->freelist = H5FL_ALLOC(H5HL_free_t,0))) {
+ if (NULL==(heap->freelist = H5FL_MALLOC(H5HL_free_t))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -206,6 +210,7 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED udata1,
void * UNUSED udata2)
{
uint8_t hdr[52];
+ size_t sizeof_hdr; /* Cache H5HL header size for file */
const uint8_t *p = NULL;
H5HL_t *heap = NULL;
H5HL_free_t *fl = NULL, *tail = NULL;
@@ -214,17 +219,20 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED udata1,
FUNC_ENTER_NOAPI(H5HL_load, NULL);
+ /* Cache this for later */
+ sizeof_hdr= H5HL_SIZEOF_HDR(f);
+
/* check arguments */
assert(f);
assert(H5F_addr_defined(addr));
- assert(H5HL_SIZEOF_HDR(f) <= sizeof hdr);
+ assert(sizeof_hdr <= sizeof(hdr));
assert(!udata1);
assert(!udata2);
- if (H5F_block_read(f, H5FD_MEM_LHEAP, addr, H5HL_SIZEOF_HDR(f), dxpl_id, hdr) < 0)
+ if (H5F_block_read(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header");
p = hdr;
- if (NULL==(heap = H5FL_ALLOC(H5HL_t,1)))
+ if (NULL==(heap = H5FL_CALLOC(H5HL_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* magic number */
@@ -246,19 +254,19 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED udata1,
/* data */
H5F_addr_decode(f, &p, &(heap->addr));
- heap->chunk = H5FL_BLK_ALLOC(heap_chunk,(H5HL_SIZEOF_HDR(f) + heap->mem_alloc),1);
+ heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + heap->mem_alloc));
if (NULL==heap->chunk)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if (heap->disk_alloc &&
H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc,
- dxpl_id, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0)
+ dxpl_id, heap->chunk + sizeof_hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data");
/* free list */
while (H5HL_FREE_NULL != free_block) {
if (free_block >= heap->disk_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
- if (NULL==(fl = H5FL_ALLOC(H5HL_free_t,0)))
+ if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
fl->offset = free_block;
fl->prev = tail;
@@ -267,7 +275,7 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED udata1,
tail = fl;
if (!heap->freelist) heap->freelist = fl;
- p = heap->chunk + H5HL_SIZEOF_HDR(f) + free_block;
+ p = heap->chunk + sizeof_hdr + free_block;
H5F_DECODE_LENGTH(f, p, free_block);
H5F_DECODE_LENGTH(f, p, fl->size);
@@ -323,6 +331,7 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
uint8_t *p = heap->chunk;
H5HL_free_t *fl = heap->freelist;
haddr_t hdr_end_addr;
+ size_t sizeof_hdr; /* Cache H5HL header size for file */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HL_flush, FAIL);
@@ -333,6 +342,9 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
assert(heap);
if (heap->dirty) {
+ /* Cache this for later */
+ sizeof_hdr= H5HL_SIZEOF_HDR(f);
+
/*
* If the heap grew larger than disk storage then move the
* data segment of the heap to a larger contiguous block of
@@ -367,7 +379,7 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
*/
while (fl) {
assert (fl->offset == H5HL_ALIGN (fl->offset));
- p = heap->chunk + H5HL_SIZEOF_HDR(f) + fl->offset;
+ p = heap->chunk + sizeof_hdr + fl->offset;
if (fl->next) {
H5F_ENCODE_LENGTH(f, p, fl->next->offset);
} else {
@@ -380,19 +392,19 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
/*
* Copy buffer to disk.
*/
- hdr_end_addr = addr + (hsize_t)H5HL_SIZEOF_HDR(f);
+ hdr_end_addr = addr + (hsize_t)sizeof_hdr;
if (H5F_addr_eq(heap->addr, hdr_end_addr)) {
/* The header and data are contiguous */
if (H5F_block_write(f, H5FD_MEM_LHEAP, addr,
- (H5HL_SIZEOF_HDR(f)+heap->disk_alloc),
+ (sizeof_hdr+heap->disk_alloc),
dxpl_id, heap->chunk) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file");
} else {
- if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, H5HL_SIZEOF_HDR(f),
+ if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr,
dxpl_id, heap->chunk)<0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file");
if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc,
- dxpl_id, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0)
+ dxpl_id, heap->chunk + sizeof_hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file");
}
@@ -456,7 +468,7 @@ H5HL_read(H5F_t *f, haddr_t addr, size_t offset, size_t size, void *buf)
assert(f);
assert (H5F_addr_defined(addr));
- if (NULL == (heap = H5AC_find(f, H5AC_LHEAP, addr, NULL, NULL)))
+ if (NULL == (heap = H5AC_find_f(f, H5AC_LHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap");
assert(offset < heap->mem_alloc);
assert(offset + size <= heap->mem_alloc);
@@ -507,8 +519,8 @@ done:
const void *
H5HL_peek(H5F_t *f, haddr_t addr, size_t offset)
{
- H5HL_t *heap = NULL;
- const void *ret_value = NULL;
+ H5HL_t *heap;
+ const void *ret_value;
FUNC_ENTER_NOAPI(H5HL_peek, NULL);
@@ -516,7 +528,7 @@ H5HL_peek(H5F_t *f, haddr_t addr, size_t offset)
assert(f);
assert(H5F_addr_defined(addr));
- if (NULL == (heap = H5AC_find(f, H5AC_LHEAP, addr, NULL, NULL)))
+ if (NULL == (heap = H5AC_find_f(f, H5AC_LHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap");
assert(offset < heap->mem_alloc);
@@ -584,6 +596,7 @@ H5HL_insert(H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
size_t offset = 0;
size_t need_size, old_size, need_more;
hbool_t found;
+ size_t sizeof_hdr; /* Cache H5HL header size for file */
size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5HL_insert, (size_t)(-1));
@@ -596,10 +609,13 @@ H5HL_insert(H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
if (0==(f->intent & H5F_ACC_RDWR))
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, (size_t)(-1), "no write intent on file");
- if (NULL == (heap = H5AC_find(f, H5AC_LHEAP, addr, NULL, NULL)))
+ if (NULL == (heap = H5AC_find_f(f, H5AC_LHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, (size_t)(-1), "unable to load heap");
heap->dirty += 1;
+ /* Cache this for later */
+ sizeof_hdr= H5HL_SIZEOF_HDR(f);
+
/*
* In order to keep the free list descriptors aligned on word boundaries,
* whatever that might mean, we round the size up to the next multiple of
@@ -669,7 +685,7 @@ H5HL_insert(H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
*/
offset = heap->mem_alloc;
if (need_more - need_size >= H5HL_SIZEOF_FREE(f)) {
- if (NULL==(fl = H5FL_ALLOC(H5HL_free_t,0)))
+ if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed");
fl->offset = heap->mem_alloc + need_size;
fl->size = need_more - need_size;
@@ -699,17 +715,17 @@ H5HL_insert(H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
old_size = heap->mem_alloc;
heap->mem_alloc += need_more;
heap->chunk = H5FL_BLK_REALLOC(heap_chunk,heap->chunk,
- (H5HL_SIZEOF_HDR(f) + heap->mem_alloc));
+ (sizeof_hdr + heap->mem_alloc));
if (NULL==heap->chunk)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed");
/* clear new section so junk doesn't appear in the file */
- HDmemset(heap->chunk + H5HL_SIZEOF_HDR(f) + old_size, 0, need_more);
+ HDmemset(heap->chunk + sizeof_hdr + old_size, 0, need_more);
}
/*
* Copy the data into the heap
*/
- HDmemcpy(heap->chunk + H5HL_SIZEOF_HDR(f) + offset, buf, buf_size);
+ HDmemcpy(heap->chunk + sizeof_hdr + offset, buf, buf_size);
/* Set return value */
ret_value=offset;
@@ -757,7 +773,7 @@ H5HL_write(H5F_t *f, haddr_t addr, size_t offset, size_t size, const void *buf)
if (0==(f->intent & H5F_ACC_RDWR))
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
- if (NULL == (heap = H5AC_find(f, H5AC_LHEAP, addr, NULL, NULL)))
+ if (NULL == (heap = H5AC_find_f(f, H5AC_LHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
assert(offset < heap->mem_alloc);
assert(offset + size <= heap->mem_alloc);
@@ -815,7 +831,7 @@ H5HL_remove(H5F_t *f, haddr_t addr, size_t offset, size_t size)
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
size = H5HL_ALIGN (size);
- if (NULL == (heap = H5AC_find(f, H5AC_LHEAP, addr, NULL, NULL)))
+ if (NULL == (heap = H5AC_find_f(f, H5AC_LHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
assert(offset < heap->mem_alloc);
assert(offset + size <= heap->mem_alloc);
@@ -883,7 +899,7 @@ H5HL_remove(H5F_t *f, haddr_t addr, size_t offset, size_t size)
/*
* Add an entry to the free list.
*/
- if (NULL==(fl = H5FL_ALLOC(H5HL_free_t,0)))
+ if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
fl->offset = offset;
fl->size = size;
@@ -936,7 +952,7 @@ H5HL_debug(H5F_t *f, haddr_t addr, FILE * stream, int indent, int fwidth)
assert(indent >= 0);
assert(fwidth >= 0);
- if (NULL == (h = H5AC_find(f, H5AC_LHEAP, addr, NULL, NULL)))
+ if (NULL == (h = H5AC_find_f(f, H5AC_LHEAP, addr, NULL, NULL)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
fprintf(stream, "%*sLocal Heap...\n", indent, "");
fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
diff --git a/src/H5I.c b/src/H5I.c
index b2a0eac..fa92bf9 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -359,8 +359,10 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
* Do nothing to the object if the reference count is larger than
* one and forcing is off.
*/
- if (!force && cur->count>1)
+ if (!force && cur->count>1) {
+ next=cur->next;
continue;
+ } /* end if */
/* Check for a 'free' function and call it, if it exists */
if (grp_ptr->free_func && (grp_ptr->free_func)(cur->obj_ptr)<0) {
@@ -540,7 +542,7 @@ H5I_register(H5I_type_t grp, void *object)
grp_ptr = H5I_id_group_list_g[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
- if ((id_ptr = H5FL_ALLOC(H5I_id_info_t,0)) == NULL)
+ if ((id_ptr = H5FL_MALLOC(H5I_id_info_t)) == NULL)
HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Create the struct & it's ID */
@@ -1156,11 +1158,11 @@ H5Iget_name(hid_t id, char *name/*out*/, size_t size)
/* get symbol table entry */
if(NULL!=(ent = H5G_loc(id))) {
- if (ent->user_path != NULL && ent->user_path_hidden==0) {
- len = HDstrlen(ent->user_path);
+ if (ent->user_path_r != NULL && ent->user_path_hidden==0) {
+ len = H5RS_len(ent->user_path_r);
if(name) {
- HDstrncpy(name, ent->user_path, MIN(len+1,size));
+ HDstrncpy(name, H5RS_GET_STR(ent->user_path_r), MIN(len+1,size));
if(len >= size)
name[size-1]='\0';
} /* end if */
diff --git a/src/H5MMprivate.h b/src/H5MMprivate.h
index 1dac78e..5e98b0e 100644
--- a/src/H5MMprivate.h
+++ b/src/H5MMprivate.h
@@ -15,7 +15,7 @@
*-------------------------------------------------------------------------
*/
#ifndef _H5MMprivate_H
-#define _H5MMprivate_h
+#define _H5MMprivate_H
#include "H5MMpublic.h"
@@ -29,7 +29,7 @@
#define H5MM_malloc(Z) HDmalloc(MAX(1,Z))
#define H5MM_calloc(Z) HDcalloc(1,MAX(1,Z))
#endif /* H5_MALLOC_WORKS */
-#define H5MM_free(Z) HDfree(1,Z)
+#define H5MM_free(Z) HDfree(Z)
/*
* Library prototypes...
diff --git a/src/H5O.c b/src/H5O.c
index 7817b55..e266b86 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -27,6 +27,10 @@
#include "H5Oprivate.h"
#include "H5Pprivate.h"
+#ifdef H5_HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif /* H5_HAVE_GETTIMEOFDAY */
+
#define PABLO_MASK H5O_mask
/* PRIVATE PROTOTYPES */
@@ -39,7 +43,6 @@ static unsigned H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type,
size_t size);
static unsigned H5O_alloc_extend_chunk(H5O_t *oh, unsigned chunkno, size_t size);
static unsigned H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size);
-static herr_t H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force);
/* H5O inherits cache-like properties from H5AC */
static const H5AC_class_t H5AC_OHDR[1] = {{
@@ -73,6 +76,7 @@ static const H5O_class_t *const message_type_g[] = {
NULL, /*0x000F Shared header message */
H5O_CONT, /*0x0010 Object header continuation */
H5O_STAB, /*0x0011 Symbol table */
+ H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
};
/*
@@ -168,7 +172,6 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/)
assert(f);
assert(ent);
- HDmemset(ent, 0, sizeof(H5G_entry_t));
size_hint = H5O_ALIGN (MAX (H5O_MIN_SIZE, size_hint));
/* allocate disk space for header and first chunk */
@@ -224,7 +227,7 @@ H5O_init(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header)
ent->header = header;
/* allocate the object header and fill in header fields */
- if (NULL == (oh = H5FL_ALLOC(H5O_t, 1)))
+ if (NULL == (oh = H5FL_MALLOC(H5O_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
oh->dirty = TRUE;
@@ -235,7 +238,7 @@ H5O_init(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header)
oh->nchunks = 1;
oh->alloc_nchunks = H5O_NCHUNKS;
- if (NULL == (oh->chunk = H5FL_ARR_ALLOC(H5O_chunk_t, oh->alloc_nchunks, 0)))
+ if (NULL == (oh->chunk = H5FL_ARR_MALLOC(H5O_chunk_t, oh->alloc_nchunks)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
tmp_addr = ent->header + (hsize_t)H5O_SIZEOF_HDR(f);
@@ -243,14 +246,14 @@ H5O_init(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header)
oh->chunk[0].addr = tmp_addr;
oh->chunk[0].size = size_hint;
- if (NULL == (oh->chunk[0].image = H5FL_BLK_ALLOC(chunk_image, size_hint, 1)))
+ if (NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, size_hint)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* create the message list and initialize the first message */
oh->nmesgs = 1;
oh->alloc_nmesgs = H5O_NMESGS;
- if (NULL == (oh->mesg = H5FL_ARR_ALLOC(H5O_mesg_t, oh->alloc_nmesgs, 1)))
+ if (NULL == (oh->mesg = H5FL_ARR_CALLOC(H5O_mesg_t, oh->alloc_nmesgs)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
oh->mesg[0].type = H5O_NULL;
@@ -431,7 +434,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED _udata1,
assert(!_udata2);
/* allocate ohdr and init chunk list */
- if (NULL==(oh = H5FL_ALLOC(H5O_t,1)))
+ if (NULL==(oh = H5FL_CALLOC(H5O_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* read fixed-lenth part of object header */
@@ -461,7 +464,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED _udata1,
/* build the message array */
oh->alloc_nmesgs = MAX(H5O_NMESGS, nmesgs);
- if (NULL==(oh->mesg=H5FL_ARR_ALLOC(H5O_mesg_t,oh->alloc_nmesgs,1)))
+ if (NULL==(oh->mesg=H5FL_ARR_CALLOC(H5O_mesg_t,oh->alloc_nmesgs)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* read each chunk from disk */
@@ -483,7 +486,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED _udata1,
oh->chunk[chunkno].dirty = FALSE;
oh->chunk[chunkno].addr = chunk_addr;
oh->chunk[chunkno].size = chunk_size;
- if (NULL==(oh->chunk[chunkno].image = H5FL_BLK_ALLOC(chunk_image,chunk_size,0)))
+ if (NULL==(oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image,chunk_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if (H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, chunk_size, dxpl_id,
oh->chunk[chunkno].image) < 0)
@@ -595,6 +598,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
uint8_t buf[16], *p;
int id;
unsigned u;
+ H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
H5O_cont_t *cont = NULL;
herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL;
unsigned combine=0; /* Whether to combine the object header prefix & the first chunk */
@@ -642,26 +646,26 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
} /* end else */
/* encode messages */
- for (u = 0; u < oh->nmesgs; u++) {
- if (oh->mesg[u].dirty) {
- p = oh->mesg[u].raw - H5O_SIZEOF_MSGHDR(f);
+ for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ if (curr_msg->dirty) {
+ p = curr_msg->raw - H5O_SIZEOF_MSGHDR(f);
- id = oh->mesg[u].type->id;
+ id = curr_msg->type->id;
UINT16ENCODE(p, id);
- assert (oh->mesg[u].raw_size<H5O_MAX_SIZE);
- UINT16ENCODE(p, oh->mesg[u].raw_size);
- *p++ = oh->mesg[u].flags;
+ assert (curr_msg->raw_size<H5O_MAX_SIZE);
+ UINT16ENCODE(p, curr_msg->raw_size);
+ *p++ = curr_msg->flags;
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
- if (oh->mesg[u].native) {
- assert(oh->mesg[u].type->encode);
+ if (curr_msg->native) {
+ assert(curr_msg->type->encode);
/* allocate file space for chunks that have none yet */
- if (H5O_CONT_ID == oh->mesg[u].type->id &&
- !H5F_addr_defined(((H5O_cont_t *)(oh->mesg[u].native))->addr)) {
- cont = (H5O_cont_t *) (oh->mesg[u].native);
+ if (H5O_CONT_ID == curr_msg->type->id &&
+ !H5F_addr_defined(((H5O_cont_t *)(curr_msg->native))->addr)) {
+ cont = (H5O_cont_t *) (curr_msg->native);
assert(cont->chunkno < oh->nchunks);
assert(!H5F_addr_defined(oh->chunk[cont->chunkno].addr));
cont->size = oh->chunk[cont->chunkno].size;
@@ -676,23 +680,23 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
* encode a Shared Object message instead of the object
* which is being shared.
*/
- assert(oh->mesg[u].raw >=
- oh->chunk[oh->mesg[u].chunkno].image);
- assert (oh->mesg[u].raw_size ==
- H5O_ALIGN (oh->mesg[u].raw_size));
- assert(oh->mesg[u].raw + oh->mesg[u].raw_size <=
- oh->chunk[oh->mesg[u].chunkno].image +
- oh->chunk[oh->mesg[u].chunkno].size);
- if (oh->mesg[u].flags & H5O_FLAG_SHARED) {
+ assert(curr_msg->raw >=
+ oh->chunk[curr_msg->chunkno].image);
+ assert (curr_msg->raw_size ==
+ H5O_ALIGN (curr_msg->raw_size));
+ assert(curr_msg->raw + curr_msg->raw_size <=
+ oh->chunk[curr_msg->chunkno].image +
+ oh->chunk[curr_msg->chunkno].size);
+ if (curr_msg->flags & H5O_FLAG_SHARED) {
encode = H5O_SHARED->encode;
} else {
- encode = oh->mesg[u].type->encode;
+ encode = curr_msg->type->encode;
}
- if ((encode)(f, oh->mesg[u].raw, oh->mesg[u].native)<0)
+ if ((encode)(f, curr_msg->raw, curr_msg->native)<0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message");
}
- oh->mesg[u].dirty = FALSE;
- oh->chunk[oh->mesg[u].chunkno].dirty = TRUE;
+ curr_msg->dirty = FALSE;
+ oh->chunk[curr_msg->chunkno].dirty = TRUE;
}
}
@@ -702,7 +706,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
assert(H5F_addr_defined(oh->chunk[u].addr));
if(u==0 && combine) {
/* Allocate space for the combined prefix and first chunk */
- if((p=H5FL_BLK_ALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[u].size),0))==NULL)
+ if((p=H5FL_BLK_MALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[u].size)))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Copy in the prefix */
@@ -739,11 +743,11 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
oh->chunk = H5FL_ARR_FREE(H5O_chunk_t,oh->chunk);
/* destroy messages */
- for (u = 0; u < oh->nmesgs; u++) {
- if (oh->mesg[u].flags & H5O_FLAG_SHARED) {
- H5O_free(H5O_SHARED, oh->mesg[u].native);
+ for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ if (curr_msg->flags & H5O_FLAG_SHARED) {
+ H5O_free(H5O_SHARED, curr_msg->native);
} else {
- H5O_free(oh->mesg[u].type, oh->mesg[u].native);
+ H5O_free(curr_msg->type, curr_msg->native);
}
}
oh->mesg = H5FL_ARR_FREE(H5O_mesg_t,oh->mesg);
@@ -969,7 +973,7 @@ H5O_count (H5G_entry_t *ent, const H5O_class_t *type)
assert (type);
/* Load the object header */
- if (NULL==(oh=H5AC_find (ent->file, H5AC_OHDR, ent->header, NULL, NULL)))
+ if (NULL==(oh=H5AC_find_f (ent->file, H5AC_OHDR, ent->header, NULL, NULL)))
HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
for (u=acc=0; u<oh->nmesgs; u++) {
@@ -1020,7 +1024,7 @@ H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, int sequence)
assert(sequence>=0);
/* Load the object header */
- if (NULL==(oh=H5AC_find(ent->file, H5AC_OHDR, ent->header, NULL, NULL)))
+ if (NULL==(oh=H5AC_find_f(ent->file, H5AC_OHDR, ent->header, NULL, NULL)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
/* Scan through the messages looking for the right one */
@@ -1182,7 +1186,7 @@ H5O_find_in_ohdr(H5F_t *f, haddr_t addr, const H5O_class_t **type_p,
assert(type_p);
/* Load the object header */
- if (NULL == (oh = H5AC_find(f, H5AC_OHDR, addr, NULL, NULL)))
+ if (NULL == (oh = H5AC_find_f(f, H5AC_OHDR, addr, NULL, NULL)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, UFAIL, "unable to load object header");
/* Scan through the messages looking for the right one */
@@ -1244,6 +1248,10 @@ done:
* the sequence number 5 if there is no message with sequence
* number 4).
*
+ * The UPDATE_TIME argument is a boolean that allows the caller
+ * to skip updating the modification time. This is useful when
+ * several calls to H5O_modify will be made in a sequence.
+ *
* Return: Success: The sequence number of the message that
* was modified or created.
*
@@ -1264,14 +1272,15 @@ done:
*/
int
H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
- unsigned flags, const void *mesg)
+ unsigned flags, unsigned update_time, const void *mesg)
{
- H5O_t *oh = NULL;
+ H5O_t *oh=NULL;
int sequence;
- unsigned idx;
+ unsigned idx; /* Index of message to modify */
+ H5O_mesg_t *idx_msg; /* Pointer to message to modify */
int ret_value = FAIL;
- size_t size = 0;
- H5O_shared_t sh_mesg = {0,{{0,0}}};
+ size_t size=0;
+ H5O_shared_t sh_mesg;
FUNC_ENTER_NOAPI(H5O_modify, FAIL);
@@ -1290,8 +1299,8 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
/* Count similar messages */
- for (idx = 0, sequence = -1; idx < oh->nmesgs; idx++) {
- if (type->id != oh->mesg[idx].type->id)
+ for (idx = 0, sequence = -1, idx_msg=&oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
+ if (type->id != idx_msg->type->id)
continue;
if (++sequence == overwrite)
break;
@@ -1311,6 +1320,8 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
if (overwrite < 0) {
/* Allocate space for the new message */
if (flags & H5O_FLAG_SHARED) {
+ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+
if (NULL==type->get_share)
HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable");
if ((type->get_share)(ent->file, mesg, &sh_mesg/*out*/)<0) {
@@ -1342,7 +1353,8 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
}
}
- if (0==(flags & H5O_FLAG_SHARED)) {
+ /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */
+ if (0== (flags & H5O_FLAG_SHARED)) {
size = (type->raw_size) (ent->file, mesg);
if (size>=H5O_MAX_SIZE)
HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)");
@@ -1358,25 +1370,28 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message");
}
+ /* Set pointer to the correct message */
+ idx_msg=&oh->mesg[idx];
/* Copy the native value into the object header */
if (flags & H5O_FLAG_SHARED) {
- if (NULL==(oh->mesg[idx].native = H5MM_malloc (sizeof (H5O_shared_t))))
+ if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDmemcpy(oh->mesg[idx].native,&sh_mesg,sizeof(H5O_shared_t));
+ HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t));
} else {
- if (oh->mesg[idx].native)
- H5O_reset (oh->mesg[idx].type, oh->mesg[idx].native);
- oh->mesg[idx].native = (type->copy) (mesg, oh->mesg[idx].native);
- if (NULL == oh->mesg[idx].native)
+ if (idx_msg->native)
+ H5O_reset (idx_msg->type, idx_msg->native);
+ idx_msg->native = (type->copy) (mesg, idx_msg->native);
+ if (NULL == idx_msg->native)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
}
/* Update the modification time message if any */
- H5O_touch_oh(ent->file, oh, FALSE);
+ if(update_time)
+ H5O_touch_oh(ent->file, oh, FALSE);
- oh->mesg[idx].flags = flags;
- oh->mesg[idx].dirty = TRUE;
+ idx_msg->flags = flags;
+ idx_msg->dirty = TRUE;
oh->dirty = TRUE;
/* Set return value */
@@ -1391,6 +1406,206 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_protect
+ *
+ * Purpose: Wrapper around H5AC_protect for use during a H5O_protect->
+ * H5O_append->...->H5O_append->H5O_unprotect sequence of calls
+ * during an object's creation.
+ *
+ * Return: Success: Pointer to the object header structure for the
+ * object.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Dec 31 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5O_t *
+H5O_protect(H5G_entry_t *ent)
+{
+ H5O_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_protect, NULL);
+
+ /* check args */
+ assert(ent);
+ assert(ent->file);
+ assert(H5F_addr_defined(ent->header));
+
+ if (0==(ent->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file");
+
+ if (NULL == (ret_value = H5AC_protect(ent->file, H5AC_OHDR, ent->header, NULL, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_unprotect
+ *
+ * Purpose: Wrapper around H5AC_unprotect for use during a H5O_protect->
+ * H5O_append->...->H5O_append->H5O_unprotect sequence of calls
+ * during an object's creation.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Dec 31 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_unprotect(H5G_entry_t *ent, H5O_t *oh)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_unprotect, FAIL);
+
+ /* check args */
+ assert(ent);
+ assert(ent->file);
+ assert(H5F_addr_defined(ent->header));
+ assert(oh);
+
+ if (H5AC_unprotect(ent->file, H5AC_OHDR, ent->header, oh) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_append
+ *
+ * Purpose: Simplified version of H5O_modify, used when creating a new
+ * object header message (usually during object creation)
+ *
+ * Modifies an existing message or creates a new message.
+ * The cache fields in that symbol table entry ENT are *not*
+ * updated, you must do that separately because they often
+ * depend on multiple object header messages. Besides, we
+ * don't know which messages will be constant and which will
+ * not.
+ *
+ * Return: Success: The sequence number of the message that
+ * was created.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Dec 31 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5O_append(H5F_t *f, H5O_t *oh, const H5O_class_t *type,
+ unsigned flags, const void *mesg)
+{
+ unsigned idx; /* Index of message to modify */
+ H5O_mesg_t *idx_msg; /* Pointer to message to modify */
+ int ret_value = FAIL;
+ size_t size=0;
+ H5O_shared_t sh_mesg;
+
+ FUNC_ENTER_NOAPI(H5O_append, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(oh);
+ assert(type);
+ assert(0==(flags & ~H5O_FLAG_BITS));
+ assert(mesg);
+
+ /* Allocate space for the new message */
+ if (flags & H5O_FLAG_SHARED) {
+ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+
+ if (NULL==type->get_share)
+ HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable");
+ if ((type->get_share)(f, mesg, &sh_mesg/*out*/)<0) {
+ /*
+ * If the message isn't shared then turn off the shared bit
+ * and treat it as an unshared message.
+ */
+ H5E_clear ();
+ flags &= ~H5O_FLAG_SHARED;
+ } else if (sh_mesg.in_gh) {
+ /*
+ * The shared message is stored in the global heap.
+ * Increment the reference count on the global heap message.
+ */
+ if (H5HG_link (f, &(sh_mesg.u.gh), 1)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ size = (H5O_SHARED->raw_size)(f, &sh_mesg);
+ } else {
+ /*
+ * The shared message is stored in some other object header.
+ * The other object header must be in the same file as the
+ * new object header. Increment the reference count on that
+ * object header.
+ */
+ if (sh_mesg.u.ent.file->shared != f->shared)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
+ if (H5O_link (&(sh_mesg.u.ent), 1)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ size = (H5O_SHARED->raw_size)(f, &sh_mesg);
+ }
+ }
+ /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */
+ if (0== (flags & H5O_FLAG_SHARED)) {
+ size = (type->raw_size) (f, mesg);
+ if (size>=H5O_MAX_SIZE)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)");
+ }
+ if ((idx = H5O_alloc(f, oh, type, size)) == UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message");
+
+ /* Set pointer to the correct message */
+ idx_msg=&oh->mesg[idx];
+
+ /* Copy the native value into the object header */
+ if (flags & H5O_FLAG_SHARED) {
+ if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t));
+ } else {
+ if (idx_msg->native)
+ H5O_reset (idx_msg->type, idx_msg->native);
+ idx_msg->native = (type->copy) (mesg, idx_msg->native);
+ if (NULL == idx_msg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
+ }
+
+ idx_msg->flags = flags;
+ idx_msg->dirty = TRUE;
+ oh->dirty = TRUE;
+
+ /* Set return value */
+ ret_value = idx;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_append() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_touch_oh
*
* Purpose: If FORCE is non-zero then create a modification time message
@@ -1406,11 +1621,14 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force)
{
unsigned idx;
- time_t now = HDtime(NULL);
+#ifdef H5_HAVE_GETTIMEOFDAY
+ struct timeval now_tv;
+#endif /* H5_HAVE_GETTIMEOFDAY */
+ time_t now;
size_t size;
herr_t ret_value=SUCCEED; /* Return value */
@@ -1420,22 +1638,29 @@ H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force)
/* Look for existing message */
for (idx=0; idx<oh->nmesgs; idx++) {
- if (H5O_MTIME==oh->mesg[idx].type)
+ if (H5O_MTIME==oh->mesg[idx].type || H5O_MTIME_NEW==oh->mesg[idx].type)
break;
}
+#ifdef H5_HAVE_GETTIMEOFDAY
+ HDgettimeofday(&now_tv,NULL);
+ now=now_tv.tv_sec;
+#else /* H5_HAVE_GETTIMEOFDAY */
+ now = HDtime(NULL);
+#endif /* H5_HAVE_GETTIMEOFDAY */
+
/* Create a new message */
if (idx==oh->nmesgs) {
if (!force)
HGOTO_DONE(SUCCEED); /*nothing to do*/
- size = (H5O_MTIME->raw_size)(f, &now);
- if ((idx=H5O_alloc(f, oh, H5O_MTIME, size))==UFAIL)
+ size = (H5O_MTIME_NEW->raw_size)(f, &now);
+ if ((idx=H5O_alloc(f, oh, H5O_MTIME_NEW, size))==UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message");
}
/* Update the native part */
if (NULL==oh->mesg[idx].native) {
- if (NULL==(oh->mesg[idx].native = H5FL_ALLOC(time_t,0)))
+ if (NULL==(oh->mesg[idx].native = H5FL_MALLOC(time_t)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for modification time message");
}
*((time_t*)(oh->mesg[idx].native)) = now;
@@ -1833,7 +2058,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
oh->chunk[chunkno].dirty = TRUE;
oh->chunk[chunkno].addr = HADDR_UNDEF;
oh->chunk[chunkno].size = size;
- if (NULL==(oh->chunk[chunkno].image = p = H5FL_BLK_ALLOC(chunk_image,size,1)))
+ if (NULL==(oh->chunk[chunkno].image = p = H5FL_BLK_CALLOC(chunk_image,size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
/*
@@ -1944,9 +2169,8 @@ done:
static unsigned
H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
{
- unsigned chunkno;
unsigned idx;
- unsigned null_idx;
+ H5O_mesg_t *msg; /* Pointer to newly allocated message */
size_t aligned_size = H5O_ALIGN(size);
unsigned ret_value; /* Return value */
@@ -1975,6 +2199,8 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
/* if we didn't find one, then allocate more header space */
if (idx >= oh->nmesgs) {
+ unsigned chunkno;
+
/*
* Look for a chunk which hasn't had disk space allocated yet
* since we can just increase the size of that chunk.
@@ -1995,9 +2221,15 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
}
}
+ /* Set pointer to newly allocated message */
+ msg=&oh->mesg[idx];
+
/* do we need to split the null message? */
- if (oh->mesg[idx].raw_size > aligned_size) {
- assert(oh->mesg[idx].raw_size - aligned_size >= H5O_SIZEOF_MSGHDR(f));
+ if (msg->raw_size > aligned_size) {
+ H5O_mesg_t *null_msg; /* Pointer to null message */
+ size_t mesg_size = aligned_size+ H5O_SIZEOF_MSGHDR(f); /* Total size of newly allocated message */
+
+ assert(msg->raw_size - aligned_size >= H5O_SIZEOF_MSGHDR(f));
if (oh->nmesgs >= oh->alloc_nmesgs) {
int old_alloc=oh->alloc_nmesgs;
@@ -2013,23 +2245,20 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
HDmemset(&oh->mesg[old_alloc],0,
(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
}
- null_idx = oh->nmesgs++;
- oh->mesg[null_idx].type = H5O_NULL;
- oh->mesg[null_idx].dirty = TRUE;
- oh->mesg[null_idx].native = NULL;
- oh->mesg[null_idx].raw = oh->mesg[idx].raw +
- aligned_size +
- H5O_SIZEOF_MSGHDR(f);
- oh->mesg[null_idx].raw_size = oh->mesg[idx].raw_size -
- (aligned_size + H5O_SIZEOF_MSGHDR(f));
- oh->mesg[null_idx].chunkno = oh->mesg[idx].chunkno;
- oh->mesg[idx].raw_size = aligned_size;
+ null_msg=&oh->mesg[oh->nmesgs++];
+ null_msg->type = H5O_NULL;
+ null_msg->dirty = TRUE;
+ null_msg->native = NULL;
+ null_msg->raw = msg->raw + mesg_size;
+ null_msg->raw_size = msg->raw_size - mesg_size;
+ null_msg->chunkno = msg->chunkno;
+ msg->raw_size = aligned_size;
}
/* initialize the new message */
- oh->mesg[idx].type = type;
- oh->mesg[idx].dirty = TRUE;
- oh->mesg[idx].native = NULL;
+ msg->type = type;
+ msg->dirty = TRUE;
+ msg->native = NULL;
oh->dirty = TRUE;
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 40da90a..34e209a 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -134,14 +134,23 @@ H5O_attr_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
p += H5O_ALIGN(attr->dt_size);
/* decode the attribute dataspace */
- if (NULL==(attr->ds = H5FL_ALLOC(H5S_t,1)))
+ if (NULL==(attr->ds = H5FL_CALLOC(H5S_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if((simple=(H5O_SDSPACE->decode)(f,p,NULL))!=NULL) {
+ hsize_t nelem; /* Number of elements in extent */
+ unsigned u; /* Local index variable */
+
attr->ds->extent.type = H5S_SIMPLE;
HDmemcpy(&(attr->ds->extent.u.simple),simple, sizeof(H5S_simple_t));
H5FL_FREE(H5S_simple_t,simple);
+
+ /* Compute the number of elements in the extent */
+ for(u=0, nelem=1; u<attr->ds->extent.u.simple.rank; u++)
+ nelem*=attr->ds->extent.u.simple.size[u];
+ attr->ds->extent.nelem = nelem;
} else {
attr->ds->extent.type = H5S_SCALAR;
+ attr->ds->extent.nelem = 1;
}
/* Default to entire dataspace being selected */
if(H5S_select_all(attr->ds,0)<0)
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 1d8b254..4244c41 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -48,7 +48,7 @@ const H5O_class_t H5O_DTYPE[1] = {{
H5O_dtype_copy, /* copy the native value */
H5O_dtype_size, /* size of raw message */
H5O_dtype_reset, /* reset method */
- H5O_dtype_free, /* free method */
+ H5O_dtype_free, /* free method */
H5O_dtype_get_share, /* get share method */
H5O_dtype_set_share, /* set share method */
H5O_dtype_debug, /* debug the message */
@@ -227,7 +227,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
} /* end if */
/* Allocate space for the field's datatype */
- temp_type = H5FL_ALLOC (H5T_t,1);
+ temp_type = H5FL_CALLOC (H5T_t);
if (NULL==temp_type)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
temp_type->ent.header = HADDR_UNDEF;
@@ -289,7 +289,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
*/
dt->u.enumer.nmembs = dt->u.enumer.nalloc = flags & 0xffff;
assert(dt->u.enumer.nmembs>=0);
- if (NULL==(dt->parent=H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt->parent=H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->parent->ent.header = HADDR_UNDEF;
if (H5O_dtype_decode_helper(f, pp, dt->parent)<0)
@@ -343,7 +343,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
} /* end if */
/* Decode base type of VL information */
- if (NULL==(dt->parent = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt->parent = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->parent->ent.header = HADDR_UNDEF;
if (H5O_dtype_decode_helper(f, pp, dt->parent)<0)
@@ -381,7 +381,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
UINT32DECODE(*pp, dt->u.array.perm[j]);
/* Decode base type of array */
- if (NULL==(dt->parent = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt->parent = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->parent->ent.header = HADDR_UNDEF;
if (H5O_dtype_decode_helper(f, pp, dt->parent)<0)
@@ -794,7 +794,7 @@ H5O_dtype_decode(H5F_t *f, const uint8_t *p,
/* check args */
assert(p);
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
dt->ent.header = HADDR_UNDEF;
@@ -1009,18 +1009,12 @@ static herr_t
H5O_dtype_reset(void *_mesg)
{
H5T_t *dt = (H5T_t *) _mesg;
- H5T_t *tmp = NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_dtype_reset, FAIL);
- if (dt) {
- if (NULL==(tmp = H5FL_ALLOC(H5T_t,0)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- *tmp = *dt;
- H5T_close(tmp);
- HDmemset(dt, 0, sizeof(H5T_t));
- }
+ if (dt)
+ H5T_free(dt);
done:
FUNC_LEAVE(ret_value);
@@ -1130,8 +1124,8 @@ H5O_dtype_set_share (H5F_t UNUSED *f, void *_mesg/*in,out*/,
H5G_ent_copy(&(dt->ent),&(sh->u.ent),H5G_COPY_SHALLOW);
/* Reset the names of the copied symbol table entry */
- dt->ent.user_path = NULL;
- dt->ent.canon_path = NULL;
+ dt->ent.user_path_r = NULL;
+ dt->ent.canon_path_r = NULL;
/* Note that the datatype is a named datatype */
dt->state = H5T_STATE_NAMED;
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 388aa4a..c81002b 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -341,7 +341,8 @@ H5O_efl_reset(void *_mesg)
mesg->slot[i].name = H5MM_xfree (mesg->slot[i].name);
mesg->heap_addr = HADDR_UNDEF;
mesg->nused = mesg->nalloc = 0;
- mesg->slot = H5MM_xfree(mesg->slot);
+ if(mesg->slot)
+ mesg->slot = H5MM_xfree(mesg->slot);
done:
FUNC_LEAVE(ret_value);
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index dd734b9..92d2000 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -10,6 +10,7 @@
*/
#include "H5private.h"
#include "H5Eprivate.h"
+#include "H5FLprivate.h" /*Free Lists */
#include "H5Iprivate.h"
#include "H5MMprivate.h"
#include "H5Oprivate.h"
@@ -22,6 +23,7 @@ static herr_t H5O_fill_new_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_fill_new_copy(const void *_mesg, void *_dest);
static size_t H5O_fill_new_size(H5F_t *f, const void *_mesg);
static herr_t H5O_fill_new_reset(void *_mesg);
+static herr_t H5O_fill_new_free(void *_mesg);
static herr_t H5O_fill_new_debug(H5F_t *f, const void *_mesg, FILE *stream,
int indent, int fwidth);
@@ -30,6 +32,7 @@ static herr_t H5O_fill_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_fill_copy(const void *_mesg, void *_dest);
static size_t H5O_fill_size(H5F_t *f, const void *_mesg);
static herr_t H5O_fill_reset(void *_mesg);
+static herr_t H5O_fill_free(void *_mesg);
static herr_t H5O_fill_debug(H5F_t *f, const void *_mesg, FILE *stream,
int indent, int fwidth);
@@ -43,7 +46,7 @@ const H5O_class_t H5O_FILL[1] = {{
H5O_fill_copy, /*copy the native value */
H5O_fill_size, /*raw message size */
H5O_fill_reset, /*free internal memory */
- NULL, /* free method */
+ H5O_fill_free, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_fill_debug, /*debug the message */
@@ -59,7 +62,7 @@ const H5O_class_t H5O_FILL_NEW[1] = {{
H5O_fill_new_copy, /*copy the native value */
H5O_fill_new_size, /*raw message size */
H5O_fill_new_reset, /*free internal memory */
- NULL, /* free method */
+ H5O_fill_new_free, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_fill_new_debug, /*debug the message */
@@ -71,6 +74,12 @@ const H5O_class_t H5O_FILL_NEW[1] = {{
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare a free list to manage the H5O_fill_new_t struct */
+H5FL_DEFINE(H5O_fill_new_t);
+
+/* Declare a free list to manage the H5O_fill_t struct */
+H5FL_DEFINE(H5O_fill_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_fill_new_decode
@@ -104,7 +113,7 @@ H5O_fill_new_decode(H5F_t UNUSED *f, const uint8_t *p,
assert(p);
assert(!sh);
- if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_new_t))))
+ if (NULL==(mesg=H5FL_CALLOC(H5O_fill_new_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message");
/* Version */
@@ -137,7 +146,7 @@ done:
if (!ret_value && mesg) {
if(mesg->buf)
H5MM_xfree(mesg->buf);
- H5MM_xfree(mesg);
+ H5FL_FREE(H5O_fill_new_t,mesg);
}
FUNC_LEAVE(ret_value);
@@ -173,7 +182,7 @@ H5O_fill_decode(H5F_t UNUSED *f, const uint8_t *p,
assert(p);
assert(!sh);
- if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_t))))
+ if (NULL==(mesg=H5FL_CALLOC(H5O_fill_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message");
UINT32DECODE(p, mesg->size);
if (mesg->size>0) {
@@ -189,7 +198,7 @@ done:
if (!ret_value && mesg) {
if(mesg->buf)
H5MM_xfree(mesg->buf);
- H5MM_xfree(mesg);
+ H5FL_FREE(H5O_fill_t,mesg);
}
FUNC_LEAVE(ret_value);
@@ -311,13 +320,16 @@ H5O_fill_new_copy(const void *_mesg, void *_dest)
assert(mesg);
- if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_new_t))))
+ if (!dest && NULL==(dest=H5FL_MALLOC(H5O_fill_new_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill message");
/* Copy data type of fill value */
- if (mesg->type &&
- NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy fill value data type");
+ if (mesg->type) {
+ if(NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy fill value data type");
+ } /* end if */
+ else
+ dest->type=NULL;
/* Copy fill value and its size */
if (mesg->buf) {
@@ -326,7 +338,11 @@ H5O_fill_new_copy(const void *_mesg, void *_dest)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value");
dest->size = mesg->size;
HDmemcpy(dest->buf, mesg->buf, (size_t)mesg->size);
- }
+ } /* end if */
+ else {
+ dest->buf=NULL;
+ dest->size=0;
+ } /* end else */
/* Copy three fill value attributes */
dest->alloc_time = mesg->alloc_time;
@@ -343,7 +359,7 @@ done:
if (dest->type)
H5T_close(dest->type);
if (!_dest)
- H5MM_xfree(dest);
+ H5FL_FREE(H5O_fill_new_t,dest);
}
FUNC_LEAVE(ret_value);
@@ -378,17 +394,24 @@ H5O_fill_copy(const void *_mesg, void *_dest)
assert(mesg);
- if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_t))))
+ if (!dest && NULL==(dest=H5FL_CALLOC(H5O_fill_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill message");
- if (mesg->type &&
- NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy fill value data type");
+
+ if (mesg->type) {
+ if(NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy fill value data type");
+ } /* end if */
+ else
+ dest->type=NULL;
+
if (mesg->buf) {
if (NULL==(dest->buf=H5MM_malloc(mesg->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value");
dest->size = mesg->size;
HDmemcpy(dest->buf, mesg->buf, mesg->size);
- }
+ } /* end if */
+ else
+ dest->buf=NULL;
/* Set return value */
ret_value = dest;
@@ -400,7 +423,7 @@ done:
if (dest->type)
H5T_close(dest->type);
if (!_dest)
- H5MM_xfree(dest);
+ H5FL_FREE(H5O_fill_t,dest);
}
FUNC_LEAVE(ret_value);
@@ -567,6 +590,66 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_fill_new_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 5, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fill_new_free (void *mesg)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_fill_new_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(H5O_fill_new_t,mesg);
+
+done:
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 5, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fill_free (void *mesg)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_fill_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(H5O_fill_t,mesg);
+
+done:
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_fill_new_debug
*
* Purpose: Prints debugging info for the message.
@@ -721,7 +804,7 @@ H5O_fill_convert(void *_fill, H5T_t *dset_type)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
/* Do the conversion */
- if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, buf, bkg, H5P_DEFAULT)<0)
+ if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, buf, bkg, H5P_DATASET_XFER_DEFAULT)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
/* Update the fill message */
diff --git a/src/H5Ofphdf5.c b/src/H5Ofphdf5.c
index 5b4afb3..a35d001 100644
--- a/src/H5Ofphdf5.c
+++ b/src/H5Ofphdf5.c
@@ -107,7 +107,7 @@ H5O_fphdf5_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
assert(!sh);
/* decode */
- fmeta = H5FL_ALLOC(H5O_fphdf5_t, 1);
+ fmeta = H5FL_CALLOC(H5O_fphdf5_t);
/* decode the OID first */
NBYTEDECODE(p, fmeta->oid, sizeof(fmeta->oid));
@@ -333,7 +333,7 @@ H5O_fphdf5_copy(const void *mesg, void *dest)
/* check args */
assert(src);
- if (!dst && NULL == (dst = H5FL_ALLOC(H5O_fphdf5_t, 0)))
+ if (!dst && NULL == (dst = H5FL_MALLOC(H5O_fphdf5_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* copy the individual metadata*/
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 8be6627..41c173e 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -93,7 +93,7 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
assert (!sh);
/* decode */
- if (NULL==(mesg = H5FL_ALLOC(H5O_layout_t,1)))
+ if (NULL==(mesg = H5FL_CALLOC(H5O_layout_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Version. 1 when space allocated; 2 when space allocation is delayed */
@@ -248,7 +248,7 @@ H5O_layout_copy(const void *_mesg, void *_dest)
/* check args */
assert(mesg);
- if (!dest && NULL==(dest=H5FL_ALLOC(H5O_layout_t,0)))
+ if (!dest && NULL==(dest=H5FL_MALLOC(H5O_layout_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* copy */
@@ -387,7 +387,7 @@ H5O_layout_reset (void *_mesg)
mesg->buf=H5MM_xfree(mesg->buf);
/* Reset the message */
- HDmemset(mesg, 0, sizeof(H5O_layout_t));
+ mesg->type=H5D_CONTIGUOUS;
} /* end if */
done:
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index e31dece..ff3eb5a 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -20,11 +20,16 @@
#define PABLO_MASK H5O_mtime_mask
+static void *H5O_mtime_new_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
+static herr_t H5O_mtime_new_encode(H5F_t *f, uint8_t *p, const void *_mesg);
+static size_t H5O_mtime_new_size(H5F_t *f, const void *_mesg);
+
static void *H5O_mtime_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
static herr_t H5O_mtime_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_mtime_copy(const void *_mesg, void *_dest);
static size_t H5O_mtime_size(H5F_t *f, const void *_mesg);
-static herr_t H5O_mtime_free (void *_mesg);
+static herr_t H5O_mtime_reset(void *_mesg);
+static herr_t H5O_mtime_free(void *_mesg);
static herr_t H5O_mtime_debug(H5F_t *f, const void *_mesg, FILE *stream,
int indent, int fwidth);
@@ -37,8 +42,25 @@ const H5O_class_t H5O_MTIME[1] = {{
H5O_mtime_encode, /*encode message */
H5O_mtime_copy, /*copy the native value */
H5O_mtime_size, /*raw message size */
- NULL, /*free internal memory */
- H5O_mtime_free, /* free method */
+ H5O_mtime_reset, /* reset method */
+ H5O_mtime_free, /* free method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_mtime_debug, /*debug the message */
+}};
+
+/* This message derives from H5O */
+/* (Only encode, decode & size routines are different from old mtime routines) */
+const H5O_class_t H5O_MTIME_NEW[1] = {{
+ H5O_MTIME_NEW_ID, /*message id number */
+ "mtime_new", /*message name for debugging */
+ sizeof(time_t), /*native message size */
+ H5O_mtime_new_decode, /*decode message */
+ H5O_mtime_new_encode, /*encode message */
+ H5O_mtime_copy, /*copy the native value */
+ H5O_mtime_new_size, /*raw message size */
+ H5O_mtime_reset, /* reset method */
+ H5O_mtime_free, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_mtime_debug, /*debug the message */
@@ -48,11 +70,74 @@ const H5O_class_t H5O_MTIME[1] = {{
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Current version of new mtime information */
+#define H5O_MTIME_VERSION 1
+
+/* Track whether tzset routine was called */
+static int ntzset=0;
+
/* Declare a free list to manage the time_t struct */
H5FL_DEFINE(time_t);
/*-------------------------------------------------------------------------
+ * Function: H5O_mtime_new_decode
+ *
+ * Purpose: Decode a new modification time message and return a pointer to a
+ * new time_t value.
+ *
+ * Return: Success: Ptr to new message in native struct.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 3 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_mtime_new_decode(H5F_t UNUSED *f, const uint8_t *p,
+ H5O_shared_t UNUSED *sh)
+{
+ time_t *mesg, the_time;
+ int version; /* Version of mtime information */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_mtime_new_decode, NULL);
+
+ /* check args */
+ assert(f);
+ assert(p);
+ assert (!sh);
+
+ /* decode */
+ version = *p++;
+ if(version!=H5O_MTIME_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for mtime message");
+
+ /* Skip reserved bytes */
+ p+=3;
+
+ /* Get the time_t from the file */
+ UINT32DECODE(p, the_time);
+
+ /* The return value */
+ if (NULL==(mesg = H5FL_MALLOC(time_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ *mesg = the_time;
+
+ /* Set return value */
+ ret_value=mesg;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_mtime_new_decode() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_mtime_decode
*
* Purpose: Decode a modification time message and return a pointer to a
@@ -77,7 +162,6 @@ H5O_mtime_decode(H5F_t UNUSED *f, const uint8_t *p,
time_t *mesg, the_time;
int i;
struct tm tm;
- static int ncalls=0;
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_mtime_decode, NULL);
@@ -88,7 +172,10 @@ H5O_mtime_decode(H5F_t UNUSED *f, const uint8_t *p,
assert (!sh);
/* Initialize time zone information */
- if (0==ncalls++) HDtzset();
+ if (!ntzset) {
+ HDtzset();
+ ntzset=1;
+ } /* end if */
/* decode */
for (i=0; i<14; i++) {
@@ -166,7 +253,7 @@ H5O_mtime_decode(H5F_t UNUSED *f, const uint8_t *p,
#endif
/* The return value */
- if (NULL==(mesg = H5FL_ALLOC(time_t,1)))
+ if (NULL==(mesg = H5FL_MALLOC(time_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
*mesg = the_time;
@@ -179,6 +266,50 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_mtime_new_encode
+ *
+ * Purpose: Encodes a new modification time message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 3 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_mtime_new_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg)
+{
+ const time_t *mesg = (const time_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_mtime_new_encode, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(p);
+ assert(mesg);
+
+ /* Version */
+ *p++ = H5O_MTIME_VERSION;
+
+ /* Reserved bytes */
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+
+ /* Encode time */
+ UINT32ENCODE(p, *mesg);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_mtime_new_encode() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_mtime_encode
*
* Purpose: Encodes a modification time message.
@@ -247,7 +378,7 @@ H5O_mtime_copy(const void *_mesg, void *_dest)
/* check args */
assert(mesg);
- if (!dest && NULL==(dest = H5FL_ALLOC(time_t,0)))
+ if (!dest && NULL==(dest = H5FL_MALLOC(time_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* copy */
@@ -262,6 +393,42 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_mtime_new_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not
+ * counting the message type or size fields, but only the data
+ * fields. This function doesn't take into account
+ * alignment.
+ *
+ * Return: Success: Message data size in bytes w/o alignment.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 3 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_mtime_new_size(H5F_t * UNUSED f, const void * UNUSED mesg)
+{
+ size_t ret_value=8; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_mtime_new_size, 0);
+
+ /* check args */
+ assert(f);
+ assert(mesg);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_mtime_new_size() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_mtime_size
*
* Purpose: Returns the size of the raw message in bytes not
@@ -298,6 +465,33 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_mtime_reset
+ *
+ * Purpose: Frees resources within a modification time message, but doesn't free
+ * the message itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Mondey, December 23, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_mtime_reset(void UNUSED *_mesg)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_mtime_reset, FAIL);
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_mtime_free
*
* Purpose: Free's the message
diff --git a/src/H5Ocomp.c b/src/H5Opline.c
index 8899c34..eb42f5b 100644
--- a/src/H5Ocomp.c
+++ b/src/H5Opline.c
@@ -81,7 +81,7 @@ H5O_pline_decode(H5F_t UNUSED *f, const uint8_t *p,
assert(p);
/* Decode */
- if (NULL==(pline = H5FL_ALLOC(H5O_pline_t,1)))
+ if (NULL==(pline = H5FL_CALLOC(H5O_pline_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
version = *p++;
if (version!=H5O_PLINE_VERSION)
@@ -244,7 +244,7 @@ H5O_pline_copy (const void *_src, void *_dst/*out*/)
FUNC_ENTER_NOAPI(H5O_pline_copy, NULL);
- if (!dst && NULL==(dst = H5FL_ALLOC (H5O_pline_t,0)))
+ if (!dst && NULL==(dst = H5FL_MALLOC (H5O_pline_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
*dst = *src;
@@ -381,7 +381,8 @@ H5O_pline_reset (void *mesg)
H5MM_xfree(pline->filter[i].name);
H5MM_xfree(pline->filter[i].cd_values);
}
- H5MM_xfree(pline->filter);
+ if(pline->filter)
+ H5MM_xfree(pline->filter);
HDmemset(pline, 0, sizeof *pline);
done:
diff --git a/src/H5Oplist.c b/src/H5Oplist.c
index 554d0b7..352df06 100644
--- a/src/H5Oplist.c
+++ b/src/H5Oplist.c
@@ -65,6 +65,12 @@ static int interface_initialize_g = 0;
/* Declare external the free list for hsize_t arrays */
H5FL_ARR_EXTERN(hsize_t);
+/* Declare the external free list for the H5P_genprop_t struct */
+H5FL_EXTERN(H5P_genprop_t);
+
+/* Declare the external free list for the H5P_genplist_t struct */
+H5FL_EXTERN(H5P_genplist_t);
+
#define UINT_ENCODE(dst, src) \
if (sizeof(src) == 2) { \
UINT16ENCODE(dst, src); \
@@ -131,7 +137,7 @@ H5O_plist_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
H5P_genclass_t *pclass; /* property list class to modify */
hid_t new_plist_id; /* property list ID of new list created */
int version; /* message version number */
- unsigned int i, nprops, hashsize;
+ unsigned int i, nprops;
void *ret_value;
FUNC_ENTER_NOAPI(H5O_plist_decode, NULL);
@@ -169,11 +175,9 @@ H5O_plist_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
++p;
UINT_DECODE(p, nprops);
- UINT_DECODE(p, hashsize);
/* Allocate new property list */
- if ((new_plist = H5MM_calloc(sizeof(H5P_genplist_t) +
- ((hashsize - 1) * sizeof(H5P_genprop_t *)))) == NULL)
+ if ((new_plist = H5FL_CALLOC(H5P_genplist_t)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Initialize new property list */
@@ -183,7 +187,11 @@ H5O_plist_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
new_plist->class_init = 0; /* Initially, wait until the class
callback finishes to set */
- /* Create new property list */
+ /* Initialize the TBBT to hold the properties */
+ if((new_plist->props=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for properties");
+
+ /* Insert properties into property list */
for (i = 0; i < nprops; ++i) {
H5P_genprop_t *tprop;
unsigned str_len;
@@ -192,35 +200,19 @@ H5O_plist_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
* Allocate and initialize the property structure which is going
* to hold the information we're reading in.
*/
- if (NULL == (tprop = H5MM_malloc(sizeof(H5P_genprop_t))))
+ if (NULL == (tprop = H5FL_CALLOC(H5P_genprop_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- tprop->create = NULL;
- tprop->def_value = NULL;
- tprop->set = NULL;
- tprop->get = NULL;
- tprop->del = NULL;
- tprop->copy = NULL;
- tprop->close = NULL;
- tprop->next = NULL;
-
- /* Grab the XORed value of the name and get the length of the name */
- UINT_DECODE(p, tprop->xor_val);
+ /* Grab the length of the name */
UINT_DECODE(p, str_len);
- if (str_len) {
- /* If there is a name, allocate space for it and copy */
- if (NULL == (tprop->name = H5MM_malloc(str_len + 1))) {
- H5MM_xfree(tprop);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- }
-
- HDmemcpy(tprop->name, p, str_len + 1);
- p += str_len + 1;
- } else {
- tprop->name = NULL;
- ++p;
+ /* Allocate space for the name and copy it */
+ if (NULL == (tprop->name = H5MM_malloc(str_len + 1))) {
+ H5FL_FREE(H5P_genprop_t,tprop);
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
}
+ HDmemcpy(tprop->name, p, str_len + 1);
+ p += str_len + 1;
/* Grab the size of the "value" data */
UINT_DECODE(p, tprop->size);
@@ -228,18 +220,21 @@ H5O_plist_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
/* Allocate and memcpy the value part of the property. */
if ((tprop->value = H5MM_malloc(tprop->size)) == NULL) {
H5MM_xfree(tprop->name);
- H5MM_xfree(tprop);
+ H5FL_FREE(H5P_genprop_t,tprop);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
}
HDmemcpy(tprop->value, p, tprop->size);
p += tprop->size;
+ /* Set the property's type */
+ tprop->type=H5P_PROP_WITHIN_LIST;
+
/* Insert the initialized property into the property list */
- if (H5P_add_prop(new_plist->props, new_plist->pclass->hashsize, tprop) < 0) {
+ if (H5P_add_prop(new_plist->props, tprop) < 0) {
H5MM_xfree(tprop->value);
H5MM_xfree(tprop->name);
- H5MM_xfree(tprop);
+ H5FL_FREE(H5P_genprop_t,tprop);
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, NULL, "Can't insert property into list");
}
@@ -292,9 +287,8 @@ static herr_t
H5O_plist_encode(H5F_t UNUSED *f, uint8_t *p, const void *mesg)
{
const H5P_genplist_t *plist = (const H5P_genplist_t *)mesg;
+ char *class_path; /* Pointer to class path generated for property list */
herr_t ret_value = SUCCEED;
- unsigned int i;
- char *class_path;
FUNC_ENTER_NOAPI(H5O_plist_encode, FAIL);
@@ -333,45 +327,47 @@ H5O_plist_encode(H5F_t UNUSED *f, uint8_t *p, const void *mesg)
HDfree(class_path);
UINT_ENCODE(p, plist->nprops);
- UINT_ENCODE(p, plist->pclass->hashsize);
- for (i = 0; i < plist->pclass->hashsize; ++i) {
- H5P_genprop_t *tprop = plist->props[i];
+ /* Encode the properties for this property list */
+ if(plist->nprops>0) {
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ H5P_genprop_t *tprop; /* Pointer to property */
+
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(plist->props->root);
+ while(curr_node!=NULL) {
+ size_t s; /* Length of property name */
- /* Walk through the list of properties at each hash location */
- while (tprop) {
- const char *n = tprop->name;
+ /* Get a pointer to the property from the node */
+ tprop=curr_node->data;
+ assert(tprop->name); /* Properties are guaranteed to have names */
/*
* Copy the meat of the generic property:
*
- * 1. The XORed version of the name
+ * 1. The length of the property name
* 2. The name of the property
* 3. The size of the property value
* 4. The property value
*/
- UINT_ENCODE(p, tprop->xor_val);
- if (n && *n) {
- size_t s = HDstrlen(n);
+ /* Get the name's length & encode it */
+ s = HDstrlen(tprop->name);
+ UINT_ENCODE(p, s);
- UINT_ENCODE(p, s);
- HDmemcpy(p, n, s + 1);
- p += s + 1;
- } else {
- /* if there isn't a name, put a NULL there */
- UINT_ENCODE(p, 0u);
- *p++ = '\0';
- }
+ /* Encode the name itself */
+ HDmemcpy(p, tprop->name, s + 1);
+ p += s + 1;
+ /* Encode the property value's size & data */
UINT_ENCODE(p, tprop->size);
HDmemcpy(p, tprop->value, tprop->size);
p += tprop->size;
- /* Go to next registered property in class */
- tprop = tprop->next;
- }
- }
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
done:
FUNC_LEAVE(ret_value);
@@ -398,37 +394,17 @@ static size_t
H5O_plist_size(H5F_t UNUSED *f, const void *mesg)
{
const H5P_genplist_t *plist = (const H5P_genplist_t *)mesg;
- const H5P_genclass_t *pclass;
+ char *class_path=NULL; /* Pointer to class path generated for property list */
size_t ret_value;
- char *class_path = NULL;
- unsigned i;
FUNC_ENTER_NOAPI(H5O_plist_size, 0);
/* check args */
assert(plist);
- ret_value = 2 + /*version info */
+ ret_value = 1 + /*version info */
1; /*reserved */
- /*
- * Loop through the class and its parent(s) to gather the complete
- * length of the name. The class name encoded will look like:
- *
- * DerivedClass/ParentClass/.../BaseClass
- */
- pclass = plist->pclass;
-
- while (pclass) {
- if (pclass->name)
- ret_value += HDstrlen(pclass->name);/*length of class name */
-
- if ((pclass = pclass->parent) != NULL)
- ++ret_value; /*separating "/" */
- }
-
- ++ret_value; /*terminating NULL */
-
class_path = H5P_get_class_path(plist->pclass);
if (class_path)
@@ -437,31 +413,29 @@ H5O_plist_size(H5F_t UNUSED *f, const void *mesg)
++ret_value;
HDfree(class_path);
- ret_value += sizeof(plist->nprops) + /*num properties */
- sizeof(plist->pclass->hashsize); /*hash size */
- for (i = 0; i < plist->pclass->hashsize; ++i) {
- H5P_genprop_t *tprop = plist->props[i];
+ ret_value += sizeof(plist->nprops); /*num properties */
- /* Walk through the list of properties at each hash location */
- while (tprop) {
- const char *n = tprop->name;
+ /* Calculate the size of the properties for this property list */
+ if(plist->nprops>0) {
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ H5P_genprop_t *tprop; /* Pointer to property */
- ret_value += sizeof(tprop->xor_val) + /*xored value */
- sizeof(size_t); /*length of the name */
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(plist->props->root);
+ while(curr_node!=NULL) {
+ /* Get a pointer to the property from the node */
+ tprop=curr_node->data;
- if (n && *n)
- ret_value += HDstrlen(n) + 1; /*the name */
- else
- ++ret_value; /*the name: NULL */
+ ret_value += sizeof(size_t); /*length of the name */
+ ret_value += HDstrlen(tprop->name) + 1; /*the name */
+ ret_value += sizeof(tprop->size) + /*size of data size */
+ tprop->size; /*the data */
- ret_value += sizeof(tprop->size) + /*size of data size */
- tprop->size; /*the data */
-
- /* Go to next registered property in class */
- tprop = tprop->next;
- }
- }
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
done:
FUNC_LEAVE(ret_value);
@@ -513,8 +487,7 @@ H5O_plist_debug(H5F_t UNUSED *f, const void *mesg, FILE *stream,
int indent, int fwidth)
{
const H5P_genplist_t *plist = (const H5P_genplist_t *)mesg;
- herr_t ret_value = SUCCEED;
- unsigned int i;
+ herr_t ret_value=SUCCEED;
FUNC_ENTER_NOAPI(H5O_plist_debug, FAIL);
@@ -531,27 +504,30 @@ H5O_plist_debug(H5F_t UNUSED *f, const void *mesg, FILE *stream,
HDfprintf(stream, "%*sProperties {\n", indent, "");
indent += 2;
- for (i = 0; i < plist->pclass->hashsize; ++i) {
- H5P_genprop_t *tprop = plist->props[i];
+ /* Calculate the size of the properties for this property list */
+ if(plist->nprops>0) {
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ H5P_genprop_t *tprop; /* Pointer to property */
- /* Walk through the list of properties at each hash location */
- while (tprop) {
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(plist->props->root);
+ while(curr_node!=NULL) {
register unsigned int j;
+ /* Get a pointer to the property from the node */
+ tprop=curr_node->data;
+
HDfprintf(stream, "%*sProperty {\n", indent, "");
indent += 2;
/*
- * Copy the meat of the generic property:
+ * Print the meat of the generic property:
*
* 1. The name of the property
- * 2. The XORed version of the name
- * 3. The size of the property value
- * 4. The property value
+ * 2. The size of the property value
+ * 3. The property value
*/
- HDfprintf(stream, "%*sName: ", indent, "");
- HDfprintf(stream, "%s\n", tprop->name ? tprop->name : "(null)");
- HDfprintf(stream, "%*sXOR Value: %d\n", indent, "", tprop->xor_val);
+ HDfprintf(stream, "%*sName: %s\n", indent, "", tprop->name);
HDfprintf(stream, "%*sValue Size: %d\n", indent, "", tprop->size);
HDfprintf(stream, "%*sValue: ", indent, "");
@@ -561,10 +537,10 @@ H5O_plist_debug(H5F_t UNUSED *f, const void *mesg, FILE *stream,
indent -= 2;
HDfprintf(stream, "\n%*s}\n", indent, "");
- /* Go to next registered property in class */
- tprop = tprop->next;
- }
- }
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
indent -= 2;
HDfprintf(stream, "%*s}\n", indent, "");
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 00b9e8f..651dbca 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -91,7 +91,7 @@ typedef struct H5O_class_t {
herr_t (*reset)(void *); /*free nested data structs */
herr_t (*free)(void *); /*free main data struct */
herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*);
- herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*);
+ herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*);
herr_t (*debug)(H5F_t*, const void*, FILE*, int, int);
} H5O_class_t;
@@ -116,14 +116,14 @@ typedef struct H5O_t {
H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
/* first field in structure */
hbool_t dirty; /*out of data wrt disk */
- int version; /*version number */
- int nlink; /*link count */
+ int version; /*version number */
+ int nlink; /*link count */
unsigned nmesgs; /*number of messages */
- unsigned alloc_nmesgs; /*number of message slots */
- H5O_mesg_t *mesg; /*array of messages */
+ unsigned alloc_nmesgs; /*number of message slots */
+ H5O_mesg_t *mesg; /*array of messages */
unsigned nchunks; /*number of chunks */
- unsigned alloc_nchunks; /*chunks allocated */
- H5O_chunk_t *chunk; /*array of chunks */
+ unsigned alloc_nchunks; /*chunks allocated */
+ H5O_chunk_t *chunk; /*array of chunks */
} H5O_t;
/*
@@ -194,9 +194,9 @@ typedef struct H5O_efl_entry_t {
typedef struct H5O_efl_t {
haddr_t heap_addr; /*address of name heap */
- int nalloc; /*number of slots allocated */
- int nused; /*number of slots used */
- H5O_efl_entry_t *slot; /*array of external file entries */
+ int nalloc; /*number of slots allocated */
+ int nused; /*number of slots used */
+ H5O_efl_entry_t *slot; /*array of external file entries */
} H5O_efl_t;
/*
@@ -227,10 +227,10 @@ typedef struct H5O_pline_t {
size_t nalloc; /*num elements in `filter' array */
struct {
H5Z_filter_t id; /*filter identification number */
- unsigned flags; /*defn and invocation flags */
+ unsigned flags; /*defn and invocation flags */
char *name; /*optional filter name */
size_t cd_nelmts; /*number of elements in cd_values[] */
- unsigned *cd_values; /*client data values */
+ unsigned *cd_values; /*client data values */
} *filter; /*array of filters */
} H5O_pline_t;
@@ -303,9 +303,15 @@ typedef struct H5O_stab_t {
} H5O_stab_t;
/*
+ * Modification time message (new format on disk). The message is just a `time_t'.
+ */
+#define H5O_MTIME_NEW_ID 0x0012
+H5_DLLVAR const H5O_class_t H5O_MTIME_NEW[1];
+
+/*
* Generic property list message.
*/
-#define H5O_PLIST_ID 0x0012
+#define H5O_PLIST_ID 0x0013
H5_DLLVAR const H5O_class_t H5O_PLIST[1];
/* operates on an H5P_genplist_t struct */
@@ -314,7 +320,7 @@ H5_DLLVAR const H5O_class_t H5O_PLIST[1];
/*
* Flexible parallel message
*/
-#define H5O_FPHDF5_ID 0x0013
+#define H5O_FPHDF5_ID 0x0014
H5_DLLVAR const H5O_class_t H5O_FPHDF5[1];
struct H5S_simple_t;
@@ -349,8 +355,13 @@ H5_DLL htri_t H5O_exists(H5G_entry_t *ent, const H5O_class_t *type,
H5_DLL void *H5O_read(H5G_entry_t *ent, const H5O_class_t *type,
int sequence, void *mesg);
H5_DLL int H5O_modify(H5G_entry_t *ent, const H5O_class_t *type,
- int overwrite, unsigned flags, const void *mesg);
+ int overwrite, unsigned flags, unsigned update_time, const void *mesg);
+H5_DLL H5O_t * H5O_protect(H5G_entry_t *ent);
+H5_DLL herr_t H5O_unprotect(H5G_entry_t *ent, H5O_t *oh);
+H5_DLL int H5O_append(H5F_t *f, H5O_t *oh, const H5O_class_t *type,
+ unsigned flags, const void *mesg);
H5_DLL herr_t H5O_touch(H5G_entry_t *ent, hbool_t force);
+H5_DLL herr_t H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force);
H5_DLL herr_t H5O_remove(H5G_entry_t *ent, const H5O_class_t *type,
int sequence);
H5_DLL herr_t H5O_reset(const H5O_class_t *type, void *native);
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 1ff3a18..6114e51 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -44,7 +44,7 @@ const H5O_class_t H5O_SDSPACE[1] = {{
H5O_sdspace_copy, /* copy the native value */
H5O_sdspace_size, /* size of symbol table entry */
H5O_sdspace_reset, /* default reset method */
- H5O_sdspace_free, /* free method */
+ H5O_sdspace_free, /* free method */
NULL, /* get share method */
NULL, /* set share method */
H5O_sdspace_debug, /* debug the message */
@@ -105,7 +105,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
assert (!sh);
/* decode */
- if ((sdim = H5FL_ALLOC(H5S_simple_t,1)) != NULL) {
+ if ((sdim = H5FL_CALLOC(H5S_simple_t)) != NULL) {
version = *p++;
if (version!=H5O_SDSPACE_VERSION)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "wrong version number in data space message");
@@ -116,19 +116,19 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
p += 5; /*reserved*/
if (sdim->rank > 0) {
- if (NULL==(sdim->size=H5FL_ARR_ALLOC(hsize_t,sdim->rank,0)))
+ if (NULL==(sdim->size=H5FL_ARR_MALLOC(hsize_t,sdim->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
for (u = 0; u < sdim->rank; u++)
H5F_DECODE_LENGTH (f, p, sdim->size[u]);
if (flags & H5S_VALID_MAX) {
- if (NULL==(sdim->max=H5FL_ARR_ALLOC(hsize_t,sdim->rank,0)))
+ if (NULL==(sdim->max=H5FL_ARR_MALLOC(hsize_t,sdim->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
for (u = 0; u < sdim->rank; u++)
H5F_DECODE_LENGTH (f, p, sdim->max[u]);
}
#ifdef LATER
if (flags & H5S_VALID_PERM) {
- if (NULL==(sdim->perm=H5FL_ARR_ALLOC(hsize_t,sdim->rank,0)))
+ if (NULL==(sdim->perm=H5FL_ARR_MALLOC(hsize_t,sdim->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
for (u = 0; u < sdim->rank; u++)
UINT32DECODE(p, sdim->perm[u]);
@@ -254,25 +254,25 @@ H5O_sdspace_copy(const void *mesg, void *dest)
/* check args */
assert(src);
- if (!dst && NULL==(dst = H5FL_ALLOC(H5S_simple_t,0)))
+ if (!dst && NULL==(dst = H5FL_MALLOC(H5S_simple_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* deep copy -- pointed-to values are copied also */
HDmemcpy(dst, src, sizeof(H5S_simple_t));
if (src->size) {
- if (NULL==(dst->size = H5FL_ARR_ALLOC(hsize_t,src->rank,0)))
+ if (NULL==(dst->size = H5FL_ARR_MALLOC(hsize_t,src->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
HDmemcpy (dst->size, src->size, src->rank*sizeof(src->size[0]));
}
if (src->max) {
- if (NULL==(dst->max=H5FL_ARR_ALLOC(hsize_t,src->rank,0)))
+ if (NULL==(dst->max=H5FL_ARR_MALLOC(hsize_t,src->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
HDmemcpy (dst->max, src->max, src->rank*sizeof(src->max[0]));
}
#ifdef LATER
if (src->perm) {
- if (NULL==(dst->perm=H5FL_ARR_ALLOC(hsize_t,src->rank,0)))
+ if (NULL==(dst->perm=H5FL_ARR_MALLOC(hsize_t,src->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
HDmemcpy (dst->perm, src->perm, src->rank*sizeof(src->perm[0]));
}
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 1675c51..182f280 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -88,7 +88,7 @@ H5O_stab_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
assert (!sh);
/* decode */
- if (NULL==(stab = H5FL_ALLOC(H5O_stab_t,1)))
+ if (NULL==(stab = H5FL_CALLOC(H5O_stab_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
H5F_addr_decode(f, &p, &(stab->btree_addr));
H5F_addr_decode(f, &p, &(stab->heap_addr));
@@ -177,7 +177,7 @@ H5O_stab_fast(const H5G_cache_t *cache, const H5O_class_t *type, void *_mesg)
if (H5O_STAB == type) {
if (_mesg) {
stab = (H5O_stab_t *) _mesg;
- } else if (NULL==(stab = H5FL_ALLOC(H5O_stab_t,1))) {
+ } else if (NULL==(stab = H5FL_CALLOC(H5O_stab_t))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
}
stab->btree_addr = cache->stab.btree_addr;
@@ -221,7 +221,7 @@ H5O_stab_copy(const void *_mesg, void *_dest)
/* check args */
assert(stab);
- if (!dest && NULL==(dest = H5FL_ALLOC(H5O_stab_t,1)))
+ if (!dest && NULL==(dest = H5FL_MALLOC(H5O_stab_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* copy */
diff --git a/src/H5P.c b/src/H5P.c
index 7913b78..a7341cb 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -21,7 +21,8 @@
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* Files */
+#include "H5Fprivate.h" /* Files */
+#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
@@ -34,6 +35,8 @@ static int interface_initialize_g = 0;
#define INTERFACE_INIT H5P_init_interface
static herr_t H5P_init_interface(void);
+/* Local variables */
+
/*
* Predefined property list classes. These are initialized at runtime by
* H5P_init_interface() in this source file.
@@ -56,6 +59,19 @@ hid_t H5P_LST_DATASET_CREATE_g = FAIL;
hid_t H5P_LST_DATASET_XFER_g = FAIL;
hid_t H5P_LST_MOUNT_g = FAIL;
+/* Track the revision count of a class, to make comparisons faster */
+static unsigned H5P_next_rev=0;
+#define H5P_GET_NEXT_REV (H5P_next_rev++)
+
+/* Declare a free list to manage the H5P_genprop_t struct */
+H5FL_DEFINE(H5P_genprop_t);
+
+/* Declare a free list to manage the H5P_genplist_t struct */
+H5FL_DEFINE(H5P_genplist_t);
+
+/* Declare a free list to manage the H5P_genclass_t struct */
+H5FL_DEFINE_STATIC(H5P_genclass_t);
+
/* Local typedefs */
/* Typedef for checking for duplicate class names in parent class */
@@ -66,15 +82,84 @@ typedef struct {
/* Local static functions */
static H5P_genclass_t *H5P_create_class(H5P_genclass_t *par_class,
- const char *name, unsigned hashsize, unsigned internal,
+ const char *name, unsigned internal,
H5P_cls_create_func_t cls_create, void *create_data,
H5P_cls_copy_func_t cls_copy, void *copy_data,
H5P_cls_close_func_t cls_close, void *close_data);
static herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name);
-static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop);
+static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type);
static herr_t H5P_free_prop(H5P_genprop_t *prop);
+/*--------------------------------------------------------------------------
+ NAME
+ H5P_do_prop_cb1
+ PURPOSE
+ Internal routine to call a property list callback routine and update
+ the property list accordingly.
+ USAGE
+ herr_t H5P_do_prop_cb1(tree,prop,cb)
+ H5TB_TREE *tree; IN/OUT: TBBT to hold changed properties
+ H5P_genprop_t *prop; IN: Property to call callback for
+ H5P_prp_cb1_t *cb; IN: Callback routine to call
+ RETURNS
+ Returns non-negative on success, negative on failure.
+ DESCRIPTION
+ Calls the callback routine passed in. If the callback routine changes
+ the property value, then the property is duplicated and added to TBBT.
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5P_do_prop_cb1(H5TB_TREE *tree, H5P_genprop_t *prop, H5P_prp_cb1_t cb)
+{
+ void *tmp_value=NULL; /* Temporary value buffer */
+ H5P_genprop_t *pcopy=NULL; /* Copy of property to insert into TBBT */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5P_do_prop_cb1);
+
+ /* Allocate space for a temporary copy of the property value */
+ if (NULL==(tmp_value=H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for temporary property value");
+ HDmemcpy(tmp_value,prop->value,prop->size);
+
+ /* Call "type 1" callback ('create', 'copy' or 'close') */
+ if(cb(prop->name,prop->size,tmp_value)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Property callback failed");
+
+ /* Check if the property value changed */
+ if(HDmemcmp(tmp_value,prop->value,prop->size)) {
+ /* Make a copy of the class's property */
+ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
+
+ /* Copy the changed value into the new property */
+ HDmemcpy(pcopy->value,tmp_value,prop->size);
+
+ /* Insert the changed property into the property list */
+ if(H5P_add_prop(tree,pcopy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into TBBT");
+ } /* end if */
+
+done:
+ /* Release the temporary value buffer */
+ if(tmp_value!=NULL)
+ H5MM_xfree(tmp_value);
+
+ /* Cleanup on failure */
+ if(ret_value<0) {
+ if(pcopy!=NULL)
+ H5P_free_prop(pcopy);
+ } /* end if */
+
+ FUNC_LEAVE(ret_value);
+} /* end H5P_do_prop_cb1() */
+
+
/*-------------------------------------------------------------------------
* Function: H5P_init
*
@@ -106,60 +191,6 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5P_xor_name -- Generate an xor'ed value for a string
-USAGE
- unsigned H5P_xor_name(s)
- const char *s; IN: String to operate over
-RETURNS
- Always returns valid value
-DESCRIPTION
- Generates an xor'ed value for a string
---------------------------------------------------------------------------*/
-static unsigned
-H5P_xor_name(const char *s)
-{
- unsigned ret=0;
- unsigned char temp;
-
- /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
- FUNC_ENTER_NOINIT(H5P_xor_name);
-
- if(s!=NULL)
- while(*s!='\0') {
- temp=(ret>>24)&0xff;
- ret <<= 8;
- ret |= temp;
- ret ^= *s++;
- }
-
- FUNC_LEAVE(ret);
-} /* end H5P_xor_name() */
-
-
-/*--------------------------------------------------------------------------
-NAME
- H5P_hash_name -- Generate a hash value for a string
-USAGE
- unsigned H5P_hash_name(s, hashsize)
- const char *s; IN: String to operate over
- unsigned; IN: Size of hash table to clip against
-RETURNS
- Always returns valid value
-DESCRIPTION
- Generates a hash location based on an xor'ed value for a string
---------------------------------------------------------------------------*/
-static unsigned
-H5P_hash_name(const char *s, unsigned hashsize)
-{
- /* Use FUNC_ENTER_NOINIT here to avoid performance issues */
- FUNC_ENTER_NOINIT(H5P_hash_name);
-
- FUNC_LEAVE(H5P_xor_name(s)%hashsize);
-} /* end H5P_hash_name() */
-
-
-/*--------------------------------------------------------------------------
-NAME
H5P_init_interface -- Initialize interface-specific information
USAGE
herr_t H5P_init_interface()
@@ -195,7 +226,7 @@ H5P_init_interface(void)
/* Allocate the root class */
assert(H5P_CLS_NO_CLASS_g==(-1));
- if (NULL==(root_class = H5P_create_class (NULL,"root",H5P_NO_CLASS_HASH_SIZE,1,NULL,NULL,NULL,NULL,NULL,NULL)))
+ if (NULL==(root_class = H5P_create_class (NULL,"root",1,NULL,NULL,NULL,NULL,NULL,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the root class */
@@ -206,7 +237,7 @@ H5P_init_interface(void)
/* Allocate the file creation class */
assert(H5P_CLS_FILE_CREATE_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"file create",H5P_FILE_CREATE_HASH_SIZE,1,NULL,NULL,NULL,NULL,NULL,NULL)))
+ if (NULL==(pclass = H5P_create_class (root_class,"file create",1,NULL,NULL,NULL,NULL,NULL,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the file creation class */
@@ -215,7 +246,7 @@ H5P_init_interface(void)
/* Allocate the file access class */
assert(H5P_CLS_FILE_ACCESS_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"file access",H5P_FILE_ACCESS_HASH_SIZE,1,H5F_acs_create,NULL,H5F_acs_copy,NULL,H5F_acs_close,NULL)))
+ if (NULL==(pclass = H5P_create_class (root_class,"file access",1,H5F_acs_create,NULL,H5F_acs_copy,NULL,H5F_acs_close,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the file access class */
@@ -226,7 +257,7 @@ H5P_init_interface(void)
/* Allocate the dataset creation class */
assert(H5P_CLS_DATASET_CREATE_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"dataset create",H5P_DATASET_CREATE_HASH_SIZE,1,NULL,NULL,H5D_crt_copy,NULL,H5D_crt_close,NULL)))
+ if (NULL==(pclass = H5P_create_class (root_class,"dataset create",1,NULL,NULL,H5D_crt_copy,NULL,H5D_crt_close,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the dataset creation class */
@@ -235,7 +266,7 @@ H5P_init_interface(void)
/* Allocate the data xfer class */
assert(H5P_CLS_DATASET_XFER_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"data xfer",H5P_DATASET_XFER_HASH_SIZE,1,H5D_xfer_create,NULL,H5D_xfer_copy,NULL,H5D_xfer_close,NULL)))
+ if (NULL==(pclass = H5P_create_class (root_class,"data xfer",1,H5D_xfer_create,NULL,H5D_xfer_copy,NULL,H5D_xfer_close,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the data xfer class */
@@ -244,7 +275,7 @@ H5P_init_interface(void)
/* Allocate the mount class */
assert(H5P_CLS_MOUNT_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"file mount",H5P_MOUNT_HASH_SIZE,1,NULL,NULL,NULL,NULL,NULL,NULL)))
+ if (NULL==(pclass = H5P_create_class (root_class,"file mount",1,NULL,NULL,NULL,NULL,NULL,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the mount class */
@@ -357,10 +388,8 @@ H5P_term_interface(void)
static H5P_genclass_t *
H5P_copy_pclass(H5P_genclass_t *pclass)
{
- H5P_genclass_t *new_pclass = NULL; /* Property list class copied */
- H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */
- H5P_genprop_t *pcopy; /* Copy of property to insert into class */
- unsigned u; /* Local index variable */
+ H5P_genclass_t *new_pclass = NULL; /* Property list class copied */
+ H5P_genprop_t *pcopy; /* Copy of property to insert into class */
H5P_genclass_t *ret_value=NULL; /* return value */
FUNC_ENTER_NOINIT(H5P_copy_pclass);
@@ -372,32 +401,30 @@ H5P_copy_pclass(H5P_genclass_t *pclass)
*/
/* Create the new property list class */
- if (NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, pclass->hashsize, 0, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data)))
+ if (NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, 0, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class");
/* Copy the properties registered for this class */
if(pclass->nprops>0) {
- /* Walk through the hash table */
- for(u=0; u<pclass->hashsize; u++) {
- tmp=pclass->props[u];
+ H5TB_NODE *curr_node; /* Current node in TBBT */
- /* Walk through the list of properties at each hash location */
- while(tmp!=NULL) {
- /* Make a copy of the class's property */
- if((pcopy=H5P_dup_prop(tmp))==NULL)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(pclass->props->root);
+ while(curr_node!=NULL) {
+ /* Make a copy of the class's property */
+ if((pcopy=H5P_dup_prop(curr_node->data,H5P_PROP_WITHIN_CLASS))==NULL)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
- /* Insert the initialized property into the property list */
- if(H5P_add_prop(new_pclass->props,new_pclass->hashsize,pcopy)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class");
+ /* Insert the initialized property into the property list */
+ if(H5P_add_prop(new_pclass->props,pcopy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class");
- /* Increment property count for class */
- new_pclass->nprops++;
+ /* Increment property count for class */
+ new_pclass->nprops++;
- /* Go to next registered property in class */
- tmp=tmp->next;
- } /* end while */
- } /* end for */
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
} /* end if */
/* Set the return value */
@@ -432,13 +459,16 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5P_copy_plist(H5P_genplist_t *old_plist)
+hid_t
+H5P_copy_plist(H5P_genplist_t *old_plist)
{
+ H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */
- H5P_genprop_t *tprop; /* Temporary pointer to properties */
+ H5P_genprop_t *tmp; /* Temporary pointer to properties */
H5P_genprop_t *new_prop; /* New property created for copy */
hid_t new_plist_id; /* Property list ID of new list created */
- unsigned u; /* Local index variable */
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ H5TB_TREE *seen=NULL; /* TBBT containing properties already seen */
hid_t ret_value=FAIL; /* return value */
FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL);
@@ -449,8 +479,8 @@ hid_t H5P_copy_plist(H5P_genplist_t *old_plist)
* Create new property list object
*/
- /* Allocate room for the property list & it's hash table of properties */
- if (NULL==(new_plist = H5MM_calloc (sizeof(H5P_genplist_t)+((old_plist->pclass->hashsize-1)*sizeof(H5P_genprop_t *)))))
+ /* Allocate room for the property list */
+ if (NULL==(new_plist = H5FL_CALLOC(H5P_genplist_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed");
/* Set class state */
@@ -458,14 +488,54 @@ hid_t H5P_copy_plist(H5P_genplist_t *old_plist)
new_plist->nprops = 0; /* Initially the plist has the same number of properties as the class */
new_plist->class_init = 0; /* Initially, wait until the class callback finishes to set */
+ /* Initialize the TBBT to hold the changed properties */
+ if((new_plist->props=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,FAIL,"can't create TBBT for changed properties");
+
+ /* Create the TBBT for deleted properties */
+ if((new_plist->del=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for deleted properties");
+
+ /* Create the TBBT to hold names of properties already seen
+ * (This prevents a property in the class hierarchy from having it's
+ * 'create' callback called, if a property in the class hierarchy has
+ * already been seen)
+ */
+ if((seen=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for seen properties");
+
+ /* Cycle through the deleted properties & copy them into the new list's deleted section */
+ if(old_plist->del->root) {
+ curr_node=H5TB_first(old_plist->del->root);
+ while(curr_node) {
+ char *new_name; /* Pointer to new name */
+
+ /* Duplicate string for insertion into new deleted property TBBT */
+ if((new_name=H5MM_xstrdup(curr_node->data))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
+
+ /* Insert property name into deleted list */
+ if(H5TB_dins(new_plist->del,new_name,new_name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into deleted TBBT");
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,new_name,new_name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
+
/* Cycle through the properties and copy them also */
- for(u=0; u<old_plist->pclass->hashsize; u++) {
- tprop=old_plist->props[u];
+ if(old_plist->props->root) {
+ curr_node=H5TB_first(old_plist->props->root);
+ while(curr_node) {
+ /* Get a pointer to the node's property */
+ tmp=curr_node->data;
- /* Walk through the list of properties at each hash location */
- while(tprop!=NULL) {
/* Make a copy of the list's property */
- if((new_prop=H5P_dup_prop(tprop))==NULL)
+ if((new_prop=H5P_dup_prop(tmp,H5P_PROP_WITHIN_LIST))==NULL)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
/* Call property copy callback, if it exists */
@@ -477,16 +547,61 @@ hid_t H5P_copy_plist(H5P_genplist_t *old_plist)
} /* end if */
/* Insert the initialized property into the property list */
- if(H5P_add_prop(new_plist->props,new_plist->pclass->hashsize,new_prop)<0)
+ if(H5P_add_prop(new_plist->props,new_prop)<0) {
+ H5P_free_prop(new_prop);
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list");
+ } /* end if */
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,new_prop->name,new_prop->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
/* Increment the number of properties in list */
new_plist->nprops++;
- /* Go to next registered property in class */
- tprop=tprop->next;
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
} /* end while */
- } /* end for */
+ } /* end if */
+
+ /*
+ * Check for copying class properties (up through list of parent classes also),
+ * initialize each with default value & make property 'copy' callback.
+ */
+ tclass=old_plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(tclass->props->root);
+ while(curr_node!=NULL) {
+ /* Get pointer to property from node */
+ tmp=curr_node->data;
+
+ /* Only "copy" properties we haven't seen before */
+ if(H5TB_dfind(seen,tmp->name,NULL)==NULL) {
+ /* Call property creation callback, if it exists */
+ if(tmp->copy) {
+ /* Call the callback & insert changed value into tree (if necessary) */
+ if(H5P_do_prop_cb1(new_plist->props,tmp,tmp->copy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property");
+ } /* end if */
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,tmp->name,tmp->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
+
+ /* Increment the number of properties in list */
+ new_plist->nprops++;
+ } /* end if */
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
/* Increment the number of property lists derived from class */
if(H5P_access_class(new_plist->pclass,H5P_MOD_INC_LST)<0)
@@ -515,6 +630,10 @@ hid_t H5P_copy_plist(H5P_genplist_t *old_plist)
ret_value=new_plist_id;
done:
+ /* Release the tree of 'seen' properties */
+ if(seen!=NULL)
+ H5TB_dfree(seen,NULL,NULL);
+
if (ret_value<0 && new_plist)
H5P_close(new_plist);
@@ -543,7 +662,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5Pcopy(hid_t id)
+hid_t
+H5Pcopy(hid_t id)
{
void *obj; /* Property object to copy */
hid_t ret_value=FALSE; /* return value */
@@ -592,6 +712,7 @@ done:
USAGE
H5P_genprop_t *H5P_dup_prop(oprop)
H5P_genprop_t *oprop; IN: Pointer to property to copy
+ H5P_prop_within_t type; IN: Type of object the property will be inserted into
RETURNS
Returns a pointer to the newly created duplicate of a property on success,
NULL on failure.
@@ -603,7 +724,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static H5P_genprop_t *
-H5P_dup_prop(H5P_genprop_t *oprop)
+H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
{
H5P_genprop_t *prop=NULL; /* Pointer to new property copied */
H5P_genprop_t *ret_value; /* Return value */
@@ -611,16 +732,47 @@ H5P_dup_prop(H5P_genprop_t *oprop)
FUNC_ENTER_NOINIT(H5P_dup_prop);
assert(oprop);
+ assert(type!=H5P_PROP_WITHIN_UNKNOWN);
/* Allocate the new property */
- if (NULL==(prop = H5MM_malloc (sizeof(H5P_genprop_t))))
+ if (NULL==(prop = H5FL_MALLOC (H5P_genprop_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Copy basic property information */
HDmemcpy(prop,oprop,sizeof(H5P_genprop_t));
- /* Duplicate name */
- prop->name = H5MM_xstrdup(oprop->name);
+ /* Check if we should duplicate the name or share it */
+
+ /* Duplicating property for a class */
+ if(type==H5P_PROP_WITHIN_CLASS) {
+ assert(oprop->type==H5P_PROP_WITHIN_CLASS);
+ assert(oprop->shared_name==0);
+
+ /* Duplicate name */
+ prop->name = H5MM_xstrdup(oprop->name);
+ } /* end if */
+ /* Duplicating property for a list */
+ else {
+ /* Check if we are duplicating a property from a list or a class */
+
+ /* Duplicating a property from a list */
+ if(oprop->type==H5P_PROP_WITHIN_LIST) {
+ /* If the old property's name wasn't shared, we have to copy it here also */
+ if(!oprop->shared_name)
+ prop->name = H5MM_xstrdup(oprop->name);
+ } /* end if */
+ /* Duplicating a property from a class */
+ else {
+ assert(oprop->type==H5P_PROP_WITHIN_CLASS);
+ assert(oprop->shared_name==0);
+
+ /* Share the name */
+ prop->shared_name=1;
+
+ /* Set the type */
+ prop->type=type;
+ } /* end else */
+ } /* end else */
/* Duplicate current value, if it exists */
if(oprop->value!=NULL) {
@@ -630,17 +782,6 @@ H5P_dup_prop(H5P_genprop_t *oprop)
HDmemcpy(prop->value,oprop->value,prop->size);
} /* end if */
- /* Duplicate default value, if it exists */
- if(oprop->def_value!=NULL) {
- assert(prop->size>0);
- if (NULL==(prop->def_value = H5MM_malloc (prop->size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- HDmemcpy(prop->def_value,oprop->def_value,prop->size);
- } /* end if */
-
- /* Reset the link to the next property */
- prop->next=NULL;
-
/* Set return value */
ret_value=prop;
@@ -652,9 +793,7 @@ done:
H5MM_xfree(prop->name);
if(prop->value!=NULL)
H5MM_xfree(prop->value);
- if(prop->def_value!=NULL)
- H5MM_xfree(prop->def_value);
- H5MM_xfree(prop);
+ H5FL_FREE(H5P_genprop_t,prop);
} /* end if */
} /* end if */
@@ -668,12 +807,12 @@ done:
PURPOSE
Internal routine to create a new property
USAGE
- H5P_genprop_t *H5P_create_prop(name,size,def_value,prp_create,prp_set,
+ H5P_genprop_t *H5P_create_prop(name,size,type,value,prp_create,prp_set,
prp_get,prp_delete,prp_close)
const char *name; IN: Name of property to register
size_t size; IN: Size of property in bytes
- void *def_value; IN: Pointer to buffer containing default value
- for property in newly created property lists
+ H5P_prop_within_t type; IN: Type of object the property will be inserted into
+ void *value; IN: Pointer to buffer containing value for property
H5P_prp_create_func_t prp_create; IN: Function pointer to property
creation callback
H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
@@ -693,7 +832,8 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static H5P_genprop_t *
-H5P_create_prop(const char *name, size_t size, void *def_value, void *value,
+H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type,
+ void *value,
H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close)
@@ -704,16 +844,18 @@ H5P_create_prop(const char *name, size_t size, void *def_value, void *value,
FUNC_ENTER_NOINIT(H5P_create_prop);
assert(name);
- assert((size>0 && (def_value!=NULL || value!=NULL)) || (size==0));
+ assert((size>0 && value!=NULL) || (size==0));
+ assert(type!=H5P_PROP_WITHIN_UNKNOWN);
/* Allocate the new property */
- if (NULL==(prop = H5MM_malloc (sizeof(H5P_genprop_t))))
+ if (NULL==(prop = H5FL_MALLOC (H5P_genprop_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Set the property initial values */
- prop->xor_val = H5P_xor_name(name); /* Generate the XOR'd value for the name */
prop->name = H5MM_xstrdup(name); /* Duplicate name */
+ prop->shared_name=0;
prop->size=size;
+ prop->type=type;
/* Duplicate value, if it exists */
if(value!=NULL) {
@@ -724,15 +866,6 @@ H5P_create_prop(const char *name, size_t size, void *def_value, void *value,
else
prop->value=NULL;
- /* Duplicate default value, if it exists */
- if(def_value!=NULL) {
- if (NULL==(prop->def_value = H5MM_malloc (prop->size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- HDmemcpy(prop->def_value,def_value,prop->size);
- } /* end if */
- else
- prop->def_value=NULL;
-
/* Set the function pointers */
prop->create=prp_create;
prop->set=prp_set;
@@ -741,9 +874,6 @@ H5P_create_prop(const char *name, size_t size, void *def_value, void *value,
prop->copy=prp_copy;
prop->close=prp_close;
- /* Reset the link to the next property */
- prop->next=NULL;
-
/* Set return value */
ret_value=prop;
@@ -755,9 +885,7 @@ done:
H5MM_xfree(prop->name);
if(prop->value!=NULL)
H5MM_xfree(prop->value);
- if(prop->def_value!=NULL)
- H5MM_xfree(prop->def_value);
- H5MM_xfree(prop);
+ H5FL_FREE(H5P_genprop_t,prop);
} /* end if */
} /* end if */
@@ -769,95 +897,142 @@ done:
NAME
H5P_add_prop
PURPOSE
- Internal routine to insert a property into a property hash table
+ Internal routine to insert a property into a property TBBT
USAGE
- herr_t H5P_add_prop(hash, hashsize, prop)
- H5P_gen_prop_t *hash[]; IN/OUT: Pointer to array of properties for hash table
- unsigned hashsize; IN: Size of hash table
+ herr_t H5P_add_prop(tree, prop)
+ H5TB_TREE *tree; IN/OUT: Pointer to TBBT of properties
H5P_genprop_t *prop; IN: Pointer to property to insert
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
- Inserts a property into a hash table of properties, using the hashed
- property name.
+ Inserts a property into a TBBT of properties.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5P_add_prop(H5P_genprop_t *hash[], unsigned hashsize, H5P_genprop_t *prop)
+H5P_add_prop(H5TB_TREE *tree, H5P_genprop_t *prop)
{
- unsigned loc; /* Hash table location */
+ herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOINIT(H5P_add_prop);
+ FUNC_ENTER_NOAPI(H5P_add_prop,FAIL);
- assert(hash);
- assert(hashsize>0);
+ assert(tree);
assert(prop);
+ assert(prop->type!=H5P_PROP_WITHIN_UNKNOWN);
- /* Get correct hash table location */
- loc=H5P_hash_name(prop->name,hashsize);
-
- /* Insert property into hash table */
- prop->next=hash[loc];
- hash[loc]=prop;
+ /* Insert property into TBBT */
+ if(H5TB_dins(tree,prop,prop->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into TBBT");
- FUNC_LEAVE (SUCCEED);
+done:
+ FUNC_LEAVE(ret_value);
} /* H5P_add_prop() */
/*--------------------------------------------------------------------------
NAME
- H5P_find_prop
+ H5P_find_prop_plist
PURPOSE
- Internal routine to check for a property in a hash table
+ Internal routine to check for a property in a property list's TBBT
USAGE
- H5P_genprop_t *H5P_find_prop(hash, hashsize, name)
- H5P_genprop_t *hash[]; IN: Pointer to array of properties for hash table
- unsigned hashsize; IN: Size of hash table
+ H5P_genprop_t *H5P_find_prop(plist, name)
+ H5P_genplist_t *plist; IN: Pointer to property list to check
const char *name; IN: Name of property to check for
RETURNS
Returns pointer to property on success, NULL on failure.
DESCRIPTION
- Checks for a property in a hash table of properties.
+ Checks for a property in a property list's TBBT of properties.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static H5P_genprop_t *
-H5P_find_prop(H5P_genprop_t *hash[], unsigned hashsize, const char *name)
+H5P_find_prop_plist(H5P_genplist_t *plist, const char *name)
{
+ H5TB_NODE *prop_node; /* TBBT node holding property */
H5P_genprop_t *ret_value; /* Property pointer return value */
- unsigned loc; /* Hash table location */
- unsigned xor_val; /* XOR'ed value of the name to look for */
- FUNC_ENTER_NOINIT(H5P_find_prop);
+ FUNC_ENTER_NOINIT(H5P_find_prop_plist);
- assert(hash);
- assert(hashsize>0);
+ assert(plist);
assert(name);
- /* Get correct hash table location */
- loc=H5P_hash_name(name,hashsize);
-
- /* Get the XOR'ed value for the name to search for, to speed up comparisons */
- xor_val=H5P_xor_name(name);
-
- /* Locate property in list */
- ret_value=hash[loc];
- while(ret_value!=NULL) {
- /* Check for name matching */
- if(ret_value->xor_val==xor_val && HDstrcmp(ret_value->name,name)==0)
- break;
-
- /* Advance to the next property */
- ret_value=ret_value->next;
- } /* end while */
+ /* Check if the property has been deleted from list */
+ if(H5TB_dfind(plist->del,name,NULL)!=NULL) {
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in TBBT");
+ } /* end if */
+ else {
+ /* Get the property node from the TBBT */
+ if((prop_node=H5TB_dfind(plist->props,name,NULL))!=NULL) {
+ /* Get the property from the node */
+ ret_value=prop_node->data;
+ } /* end if */
+ else {
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ /* Find the property in the class */
+ if((prop_node=H5TB_dfind(tclass->props,name,NULL))!=NULL)
+ /* Get pointer to actual property & leave */
+ HGOTO_DONE(prop_node->data);
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
+
+ /* If we've gotten this far, we haven't found the property */
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in TBBT");
+ } /* end else */
+ } /* end else */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5P_find_prop_plist() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5P_find_prop_pclass
+ PURPOSE
+ Internal routine to check for a property in a class TBBT
+ USAGE
+ H5P_genprop_t *H5P_find_prop_class(tree, name)
+ H5P_genclass *pclass; IN: Pointer generic property class to check
+ const char *name; IN: Name of property to check for
+ RETURNS
+ Returns pointer to property on success, NULL on failure.
+ DESCRIPTION
+ Checks for a property in a class' TBBT of properties.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static H5P_genprop_t *
+H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name)
+{
+ H5TB_NODE *prop_node; /* TBBT node holding property */
+ H5P_genprop_t *ret_value; /* Property pointer return value */
+
+ FUNC_ENTER_NOINIT(H5P_find_prop_pclass);
+
+ assert(pclass);
+ assert(name);
+
+ /* Get the property node from the TBBT */
+ if((prop_node=H5TB_dfind(pclass->props,name,NULL))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in TBBT");
+
+ /* Get the property from the node */
+ ret_value=prop_node->data;
+done:
FUNC_LEAVE (ret_value);
-} /* H5P_find_prop() */
+} /* H5P_find_prop_pclass() */
/*--------------------------------------------------------------------------
@@ -885,15 +1060,15 @@ H5P_free_prop(H5P_genprop_t *prop)
assert(prop);
- /* Release the property value and default value if they exist */
- if(prop->size>0) {
- if(prop->value)
- H5MM_xfree(prop->value);
- if(prop->def_value)
- H5MM_xfree(prop->def_value);
- } /* end if */
- H5MM_xfree(prop->name);
- H5MM_xfree(prop);
+ /* Release the property value if it exists */
+ if(prop->value)
+ H5MM_xfree(prop->value);
+
+ /* Only free the name if we own it */
+ if(prop->shared_name==0)
+ H5MM_xfree(prop->name);
+
+ H5FL_FREE(H5P_genprop_t,prop);
FUNC_LEAVE (SUCCEED);
} /* H5P_free_prop() */
@@ -903,11 +1078,10 @@ H5P_free_prop(H5P_genprop_t *prop)
NAME
H5P_free_all_prop
PURPOSE
- Internal routine to remove all properties from a property hash table
+ Internal routine to remove all properties from a property TBBT
USAGE
- herr_t H5P_free_all_prop(hash, hashsize, make_cb)
- H5P_gen_prop_t *hash[]; IN/OUT: Pointer to array of properties for hash table
- unsigned hashsize; IN: Size of hash table
+ herr_t H5P_free_all_prop(tree, make_cb)
+ H5TB_TREE *tree; IN/OUT: Pointer to property TBBT
unsigned make_cb; IN: Whether to make property callbacks or not
RETURNS
Returns non-negative on success, negative on failure.
@@ -920,35 +1094,39 @@ H5P_free_prop(H5P_genprop_t *prop)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5P_free_all_prop(H5P_genprop_t *hash[], unsigned hashsize, unsigned make_cb)
+H5P_free_all_prop(H5TB_TREE *tree,unsigned make_cb)
{
- H5P_genprop_t *tprop, *next;/* Temporary pointer to properties */
- unsigned u; /* Local index variable */
+ H5P_genprop_t *tprop; /* Temporary pointer to properties */
+ H5TB_NODE *curr_node, *next_node; /* Current & next nodes in TBBT */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5P_free_all_prop);
- assert(hash);
- assert(hashsize>0);
+ assert(tree);
/* Work through all the properties... */
- for(u=0; u<hashsize; u++) {
- tprop=hash[u];
- while(tprop!=NULL) {
- /* Find next node right away, to avoid accessing the current node after it's been free'd */
- next=tprop->next;
+ curr_node=H5TB_first(tree->root);
+ while(curr_node!=NULL) {
+ /* Get the next node in the TBBT */
+ next_node=H5TB_next(curr_node);
- /* Call the close callback and ignore the return value, there's nothing we can do about it */
- if(make_cb && tprop->close!=NULL)
- (tprop->close)(tprop->name,tprop->size,tprop->value);
+ /* Remove the node from the TBBT */
+ if((tprop=H5TB_rem(&tree->root,curr_node,NULL))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from TBBT");
- /* Free the property, ignoring return value, nothing we can do */
- H5P_free_prop(tprop);
+ /* Call the close callback and ignore the return value, there's nothing we can do about it */
+ if(make_cb && tprop->close!=NULL)
+ (tprop->close)(tprop->name,tprop->size,tprop->value);
- tprop=next;
- } /* end while */
- } /* end for */
+ /* Free the property, ignoring return value, nothing we can do */
+ H5P_free_prop(tprop);
- FUNC_LEAVE (SUCCEED);
+ /* Advance to the next property node in the TBBT */
+ curr_node=next_node;
+ } /* end while */
+
+done:
+ FUNC_LEAVE (ret_value);
} /* H5P_free_all_prop() */
@@ -1027,9 +1205,13 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
H5MM_xfree(pclass->name);
/* Free the class properties without making callbacks */
- H5P_free_all_prop(pclass->props,pclass->hashsize,0);
+ if(pclass->nprops>0)
+ H5P_free_all_prop(pclass->props,0);
- H5MM_xfree(pclass);
+ /* Free the property tree itself */
+ H5TB_dfree(pclass->props,NULL,NULL);
+
+ H5FL_FREE(H5P_genclass_t,pclass);
/* Reduce the number of dependent classes on parent class also */
if(par_class!=NULL)
@@ -1091,11 +1273,10 @@ H5P_check_class(void *_obj, hid_t id, const void *_key)
PURPOSE
Internal routine to create a new property list class.
USAGE
- H5P_genclass_t H5P_create_class(par_class, name, hashsize, internal,
+ H5P_genclass_t H5P_create_class(par_class, name, internal,
cls_create, create_data, cls_close, close_data)
H5P_genclass_t *par_class; IN: Pointer to parent class
const char *name; IN: Name of class we are creating
- unsigned hashsize; IN: Number of buckets in hash table
unsigned internal; IN: Whether this is an internal class or not
H5P_cls_create_func_t; IN: The callback function to call when each
property list in this class is created.
@@ -1120,7 +1301,7 @@ H5P_check_class(void *_obj, hid_t id, const void *_key)
REVISION LOG
--------------------------------------------------------------------------*/
static H5P_genclass_t *
-H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned hashsize, unsigned internal,
+H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal,
H5P_cls_create_func_t cls_create, void *create_data,
H5P_cls_copy_func_t cls_copy, void *copy_data,
H5P_cls_close_func_t cls_close, void *close_data
@@ -1136,23 +1317,26 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned hashsize,
/* (This allows the root of the tree to be created with this routine -QAK) */
if(!internal) {
assert(par_class);
- assert(hashsize>0);
}
- /* Allocate room for the class & it's hash table of properties */
- if (NULL==(pclass = H5MM_calloc (sizeof(H5P_genclass_t)+((hashsize-1)*sizeof(H5P_genprop_t *)))))
+ /* Allocate room for the class */
+ if (NULL==(pclass = H5FL_CALLOC(H5P_genclass_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed");
/* Set class state */
pclass->parent = par_class;
pclass->name = H5MM_xstrdup(name);
pclass->nprops = 0; /* Classes are created without properties initially */
- pclass->hashsize = hashsize;
pclass->plists = 0; /* No properties lists of this class yet */
pclass->classes = 0; /* No classes derived from this class yet */
pclass->ref_count = 1; /* This is the first reference to the new class */
pclass->internal = internal;
pclass->deleted = 0; /* Not deleted yet... :-) */
+ pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */
+
+ /* Create the TBBT for properties */
+ if((pclass->props=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for properties");
/* Set callback functions and pass-along data */
pclass->create_func = cls_create;
@@ -1175,7 +1359,7 @@ done:
/* Free any resources allocated */
if(ret_value==NULL) {
if(pclass!=NULL)
- H5MM_xfree(pclass);
+ H5FL_FREE(H5P_genclass_t,pclass);
}
FUNC_LEAVE (ret_value);
@@ -1188,11 +1372,10 @@ done:
PURPOSE
Create a new property list class.
USAGE
- hid_t H5Pcreate_class(parent, name, hashsize, cls_create, create_data,
+ hid_t H5Pcreate_class(parent, name, cls_create, create_data,
cls_close, close_data)
hid_t parent; IN: Property list class ID of parent class
const char *name; IN: Name of class we are creating
- unsigned hashsize; IN: Number of buckets in hash table
H5P_cls_create_func_t cls_create; IN: The callback function to call
when each property list in this class is
created.
@@ -1218,7 +1401,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
hid_t
-H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize,
+H5Pcreate_class(hid_t parent, const char *name,
H5P_cls_create_func_t cls_create, void *create_data,
H5P_cls_copy_func_t cls_copy, void *copy_data,
H5P_cls_close_func_t cls_close, void *close_data
@@ -1229,7 +1412,7 @@ H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize,
hid_t ret_value; /* Return value */
FUNC_ENTER_API(H5Pcreate_class, FAIL);
- H5TRACE9("i","isIuxxxxxx",parent,name,hashsize,cls_create,create_data,
+ H5TRACE8("i","isxxxxxx",parent,name,cls_create,create_data,
cls_copy,copy_data,cls_close,close_data);
/* Check arguments. */
@@ -1237,8 +1420,6 @@ H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
if (!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name");
- if (hashsize==0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hashsize too small");
if ((create_data!=NULL && cls_create==NULL)
|| (copy_data!=NULL && cls_copy==NULL)
|| (close_data!=NULL && cls_close==NULL))
@@ -1251,7 +1432,7 @@ H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class");
/* Create the new property list class */
- if (NULL==(pclass=H5P_create_class(par_class, name, hashsize, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data)))
+ if (NULL==(pclass=H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class");
/* Get an atom for the class */
@@ -1291,14 +1472,14 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static H5P_genplist_t *H5P_create(H5P_genclass_t *pclass)
+static H5P_genplist_t *
+H5P_create(H5P_genclass_t *pclass)
{
- H5P_genclass_t *tclass=NULL; /* Temporary class pointer */
- H5P_genplist_t *plist=NULL; /* New property list created */
- H5P_genplist_t *ret_value; /* return value */
- H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */
- H5P_genprop_t *pcopy; /* Copy of property to insert into class */
- unsigned u; /* Local index variable */
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+ H5P_genplist_t *plist=NULL; /* New property list created */
+ H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */
+ H5TB_TREE *seen=NULL; /* TBBT to hold names of properties already seen */
+ H5P_genplist_t *ret_value; /* Return value */
FUNC_ENTER_NOINIT(H5P_create);
@@ -1308,8 +1489,8 @@ static H5P_genplist_t *H5P_create(H5P_genclass_t *pclass)
* Create new property list object
*/
- /* Allocate room for the property list & it's hash table of properties */
- if (NULL==(plist = H5MM_calloc (sizeof(H5P_genplist_t)+((pclass->hashsize-1)*sizeof(H5P_genprop_t *)))))
+ /* Allocate room for the property list */
+ if (NULL==(plist = H5FL_CALLOC(H5P_genplist_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed");
/* Set class state */
@@ -1317,57 +1498,57 @@ static H5P_genplist_t *H5P_create(H5P_genclass_t *pclass)
plist->nprops = 0; /* Initially the plist has the same number of properties as the class */
plist->class_init = 0; /* Initially, wait until the class callback finishes to set */
+ /* Create the TBBT for changed properties */
+ if((plist->props=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for changed properties");
+
+ /* Create the TBBT for deleted properties */
+ if((plist->del=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for deleted properties");
+
+ /* Create the TBBT to hold names of properties already seen
+ * (This prevents a property in the class hierarchy from having it's
+ * 'create' callback called, if a property in the class hierarchy has
+ * already been seen)
+ */
+ if((seen=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for seen properties");
+
/*
- * Copy class properties (up through list of parent classes also),
+ * Check if we should copy class properties (up through list of parent classes also),
* initialize each with default value & make property 'create' callback.
*/
tclass=pclass;
while(tclass!=NULL) {
if(tclass->nprops>0) {
- /* Walk through the hash table */
- for(u=0; u<tclass->hashsize; u++) {
- tmp=tclass->props[u];
- /* Walk through the list of properties at each hash location */
- while(tmp!=NULL) {
- /* Check for property already existing in list */
- if(H5P_find_prop(plist->props,pclass->hashsize,tmp->name)==NULL) {
- /* Make a copy of the class's property */
- if((pcopy=H5P_dup_prop(tmp))==NULL)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
-
- /* Create initial value from default value for non-zero sized properties */
- if(pcopy->size>0) {
- /* Properties from the class should have any values yet, but should have a default */
- assert(pcopy->value==NULL);
- assert(pcopy->def_value);
-
- /* Allocate space for the property value & copy default value */
- if (NULL==(pcopy->value = H5MM_malloc (pcopy->size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- HDmemcpy(pcopy->value,pcopy->def_value,pcopy->size);
- } /* end if */
-
- /* Call property creation callback, if it exists */
- if(pcopy->create) {
- if((pcopy->create)(pcopy->name,pcopy->size,pcopy->value)<0) {
- H5P_free_prop(pcopy);
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't initialize property");
- } /* end if */
- } /* end if */
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(tclass->props->root);
+ while(curr_node!=NULL) {
+ /* Get pointer to property from node */
+ tmp=curr_node->data;
+
+ /* Only "create" properties we haven't seen before */
+ if(H5TB_dfind(seen,tmp->name,NULL)==NULL) {
+ /* Call property creation callback, if it exists */
+ if(tmp->create) {
+ /* Call the callback & insert changed value into tree (if necessary) */
+ if(H5P_do_prop_cb1(plist->props,tmp,tmp->create)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property");
+ } /* end if */
- /* Insert the initialized property into the property list */
- if(H5P_add_prop(plist->props,pclass->hashsize,pcopy)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class");
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,tmp->name,tmp->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
- /* Increment the number of properties in list */
- plist->nprops++;
- } /* end if */
+ /* Increment the number of properties in list */
+ plist->nprops++;
+ } /* end if */
- /* Go to next registered property in class */
- tmp=tmp->next;
- } /* end while */
- } /* end for */
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
} /* end if */
/* Go up to parent class */
@@ -1382,14 +1563,25 @@ static H5P_genplist_t *H5P_create(H5P_genclass_t *pclass)
ret_value=plist;
done:
+ /* Release the tree of 'seen' properties */
+ if(seen!=NULL)
+ H5TB_dfree(seen,NULL,NULL);
+
/* Release resources allocated on failure */
if(ret_value==NULL) {
if(plist!=NULL) {
- /* Close & free all the properties */
- H5P_free_all_prop(plist->props,pclass->hashsize,1);
+ /* Close & free any changed properties */
+ if(plist->props) {
+ H5P_free_all_prop(plist->props,1);
+ H5TB_dfree(plist->props,NULL,NULL);
+ } /* end if */
- /* Decrement the number of property lists derived from the class */
- pclass->plists--;
+ /* Release the deleted property TBBT */
+ if(plist->del)
+ H5TB_dfree(plist->del,NULL,NULL);
+
+ /* Release the property list itself */
+ H5FL_FREE(H5P_genplist_t,plist);
} /* end if */
} /* end if */
@@ -1419,7 +1611,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5P_create_id(H5P_genclass_t *pclass)
+hid_t
+H5P_create_id(H5P_genclass_t *pclass)
{
H5P_genplist_t *plist=NULL; /* Property list created */
hid_t plist_id=FAIL; /* Property list ID */
@@ -1485,7 +1678,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5Pcreate(hid_t cls_id)
+hid_t
+H5Pcreate(hid_t cls_id)
{
H5P_genclass_t *pclass; /* Property list class to modify */
hid_t ret_value; /* return value */
@@ -1636,16 +1830,15 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5P_register(H5P_genclass_t *pclass, const char *name, size_t size,
+herr_t
+H5P_register(H5P_genclass_t *pclass, const char *name, size_t size,
void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close)
{
H5P_genclass_t *new_class; /* New class pointer */
- H5P_genprop_t *tmp_prop; /* Temporary property pointer */
H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */
H5P_genprop_t *pcopy; /* Property copy */
- unsigned u; /* Local index variable */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5P_register, FAIL);
@@ -1655,51 +1848,60 @@ herr_t H5P_register(H5P_genclass_t *pclass, const char *name, size_t size,
assert((size>0 && def_value!=NULL) || (size==0));
/* Check for duplicate named properties */
- if((tmp_prop=H5P_find_prop(pclass->props,pclass->hashsize,name))!=NULL)
+ if(H5TB_dfind(pclass->props,name,NULL)!=NULL)
HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists");
/* Check if class needs to be split because property lists or classes have
* been created since the last modification was made to the class.
*/
if(pclass->plists>0 || pclass->classes>0) {
- if((new_class=H5P_create_class(pclass->parent,pclass->name,pclass->hashsize,
+ if((new_class=H5P_create_class(pclass->parent,pclass->name,
pclass->internal,pclass->create_func,pclass->create_data,
pclass->copy_func,pclass->copy_data,
pclass->close_func,pclass->close_data))==NULL)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class");
- /* Walk through the hash table of the old class and copy properties */
- for(u=0; u<pclass->hashsize; u++) {
- tmp_prop=pclass->props[u];
- while(tmp_prop!=NULL) {
+ /* Walk through the TBBT of the old class and copy properties */
+ if(pclass->nprops>0) {
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+
+ /* Walk through the properties in the old class */
+ curr_node=H5TB_first(pclass->props->root);
+ while(curr_node!=NULL) {
/* Make a copy of the class's property */
- if((pcopy=H5P_dup_prop(tmp_prop))==NULL)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
+ if((pcopy=H5P_dup_prop(curr_node->data,H5P_PROP_WITHIN_CLASS))==NULL)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
+
+ /* Insert the initialized property into the property list */
+ if(H5P_add_prop(new_class->props,pcopy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class");
- /* Insert the property into the new property class */
- if(H5P_add_prop(new_class->props,pclass->hashsize,pcopy)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
+ /* Increment property count for class */
+ new_class->nprops++;
- /* Go to next registered property in class */
- tmp_prop=tmp_prop->next;
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
} /* end while */
- } /* end for */
+ } /* end if */
/* Use the new class instead of the old one */
pclass=new_class;
} /* end if */
/* Create property object from parameters */
- if((new_prop=H5P_create_prop(name,size,def_value,NULL,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_close))==NULL)
+ if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_CLASS,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_close))==NULL)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property");
/* Insert property into property list class */
- if(H5P_add_prop(pclass->props,pclass->hashsize,new_prop)<0)
+ if(H5P_add_prop(pclass->props,new_prop)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
/* Increment property count for class */
pclass->nprops++;
+ /* Update the revision for the class */
+ pclass->revision = H5P_GET_NEXT_REV;
+
done:
if(ret_value==FAIL) {
if(new_prop!=NULL) {
@@ -1707,9 +1909,7 @@ done:
H5MM_xfree(new_prop->name);
if(new_prop->value!=NULL)
H5MM_xfree(new_prop->value);
- if(new_prop->def_value!=NULL)
- H5MM_xfree(new_prop->def_value);
- H5MM_xfree(new_prop);
+ H5FL_FREE(H5P_genprop_t,new_prop);
} /* end if */
} /* end if */
FUNC_LEAVE (ret_value);
@@ -1847,7 +2047,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pregister(hid_t cls_id, const char *name, size_t size, void *def_value,
+herr_t
+H5Pregister(hid_t cls_id, const char *name, size_t size, void *def_value,
H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close)
@@ -1986,8 +2187,9 @@ H5P_insert(H5P_genplist_t *plist, const char *name, size_t size,
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
H5P_prp_close_func_t prp_close)
{
- H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */
+ H5TB_NODE *prop_node; /* TBBT node holding property */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5P_insert);
@@ -1996,15 +2198,44 @@ H5P_insert(H5P_genplist_t *plist, const char *name, size_t size,
assert((size>0 && value!=NULL) || (size==0));
/* Check for duplicate named properties */
- if(H5P_find_prop(plist->props,plist->pclass->hashsize,name)!=NULL)
+ if(H5TB_dfind(plist->props,name,NULL)!=NULL)
HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists");
+ /* Check if the property has been deleted */
+ if((prop_node=H5TB_dfind(plist->del,name,NULL))!=NULL) {
+ /* Remove the property name from the deleted property TBBT */
+ if(H5TB_rem(&plist->del->root,prop_node,NULL)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted TBBT");
+
+ /* Fall through to add property to list */
+ } /* end if */
+ else {
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+
+ /* Check if the property is already in the class hierarchy */
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Find the property in the class */
+ if(H5TB_dfind(tclass->props,name,NULL)!=NULL)
+ HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists");
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
+
+ /* Fall through to add property to list */
+ } /* end else */
+
+ /* Ok to add to property list */
+
/* Create property object from parameters */
- if((new_prop=H5P_create_prop(name,size,NULL,value,NULL,prp_set,prp_get,prp_delete,prp_copy,prp_close))==NULL)
+ if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_LIST,value,NULL,prp_set,prp_get,prp_delete,prp_copy,prp_close))==NULL)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property");
/* Insert property into property list class */
- if(H5P_add_prop(plist->props,plist->pclass->hashsize,new_prop)<0)
+ if(H5P_add_prop(plist->props,new_prop)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
/* Increment property count for class */
@@ -2017,9 +2248,7 @@ done:
H5MM_xfree(new_prop->name);
if(new_prop->value!=NULL)
H5MM_xfree(new_prop->value);
- if(new_prop->def_value!=NULL)
- H5MM_xfree(new_prop->def_value);
- H5MM_xfree(new_prop);
+ H5FL_FREE(H5P_genprop_t,new_prop);
} /* end if */
} /* end if */
@@ -2132,7 +2361,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pinsert(hid_t plist_id, const char *name, size_t size, void *value,
+herr_t
+H5Pinsert(hid_t plist_id, const char *name, size_t size, void *value,
H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
H5P_prp_close_func_t prp_close)
@@ -2190,9 +2420,12 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
+herr_t
+H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
{
+ H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genprop_t *prop; /* Temporary property pointer */
+ H5TB_NODE *prop_node; /* TBBT node holding property */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5P_set, FAIL);
@@ -2201,36 +2434,123 @@ herr_t H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
assert(name);
assert(value);
- /* Find property */
- if((prop=H5P_find_prop(plist->props,plist->pclass->hashsize,name))==NULL)
+ /* Check if the property has been deleted */
+ if(H5TB_dfind(plist->del,name,NULL)!=NULL)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
- /* Check for property size >0 */
- if(prop->size==0)
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
+ /* Find property in changed list */
+ if((prop_node=H5TB_dfind(plist->props,name,NULL))!=NULL) {
+ /* Get pointer to actual property */
+ prop=prop_node->data;
+
+ /* Check for property size >0 */
+ if(prop->size==0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
- /* Make a copy of the value and pass to 'set' callback */
- if(prop->set!=NULL) {
- void *tmp_value; /* Temporary value for property */
+ /* Make a copy of the value and pass to 'set' callback */
+ if(prop->set!=NULL) {
+ void *tmp_value; /* Temporary value for property */
- /* Make a copy of the current value, in case the callback fails */
- if (NULL==(tmp_value=H5MM_malloc(prop->size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
- HDmemcpy(tmp_value,value,prop->size);
+ /* Make a copy of the current value, in case the callback fails */
+ if (NULL==(tmp_value=H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
+ HDmemcpy(tmp_value,value,prop->size);
- /* Call user's callback */
- if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
+ /* Call user's callback */
+ if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0) {
+ H5MM_xfree(tmp_value);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
+ } /* end if */
- /* Copy new [possibly unchanged] value into property value */
- HDmemcpy(prop->value,tmp_value,prop->size);
+ /* Copy new [possibly unchanged] value into property value */
+ HDmemcpy(prop->value,tmp_value,prop->size);
- /* Free the temporary value buffer */
- H5MM_xfree(tmp_value);
+ /* Free the temporary value buffer */
+ H5MM_xfree(tmp_value);
+ } /* end if */
+ /* No 'set' callback, just copy value */
+ else
+ HDmemcpy(prop->value,value,prop->size);
} /* end if */
- /* No 'set' callback, just copy value */
- else
- HDmemcpy(prop->value,value,prop->size);
+ else {
+ /*
+ * Check if we should set class properties (up through list of parent classes also),
+ * & make property 'set' callback.
+ */
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Find the property in the class */
+ if((prop_node=H5TB_dfind(tclass->props,name,NULL))!=NULL) {
+ H5P_genprop_t *pcopy; /* Copy of property to insert into TBBT */
+
+ /* Get pointer to actual property */
+ prop=prop_node->data;
+
+ /* Check for property size >0 */
+ if(prop->size==0)
+ HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
+
+ /* Make a copy of the value and pass to 'set' callback */
+ if(prop->set!=NULL) {
+ void *tmp_value; /* Temporary value for property */
+
+ /* Make a copy of the current value, in case the callback fails */
+ if (NULL==(tmp_value=H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
+ HDmemcpy(tmp_value,value,prop->size);
+
+ /* Call user's callback */
+ if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0) {
+ H5MM_xfree(tmp_value);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
+ } /* end if */
+
+ if(HDmemcmp(tmp_value,prop->value,prop->size)) {
+ /* Make a copy of the class's property */
+ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
+
+ /* Copy new value into property value */
+ HDmemcpy(pcopy->value,tmp_value,pcopy->size);
+
+ /* Insert the changed property into the property list */
+ if(H5P_add_prop(plist->props,pcopy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into TBBT");
+ } /* end if */
+
+ /* Free the temporary value buffer */
+ H5MM_xfree(tmp_value);
+ } /* end if */
+ /* No 'set' callback, just copy value */
+ else {
+ if(HDmemcmp(value,prop->value,prop->size)) {
+ /* Make a copy of the class's property */
+ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
+
+ HDmemcpy(pcopy->value,value,pcopy->size);
+
+ /* Insert the changed property into the property list */
+ if(H5P_add_prop(plist->props,pcopy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into TBBT");
+ } /* end if */
+ } /* end else */
+
+ /* Leave */
+ HGOTO_DONE(SUCCEED);
+ } /* end while */
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
+
+ /* If we get this far, then it wasn't in the list of changed properties,
+ * nor in the properties in the class hierarchy, indicate an error
+ */
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in TBBT");
+ } /* end else */
done:
FUNC_LEAVE (ret_value);
@@ -2268,7 +2588,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pset(hid_t plist_id, const char *name, void *value)
+herr_t
+H5Pset(hid_t plist_id, const char *name, void *value)
{
H5P_genplist_t *plist; /* Property list to modify */
herr_t ret_value=SUCCEED; /* return value */
@@ -2323,12 +2644,31 @@ H5P_exist_plist(H5P_genplist_t *plist, const char *name)
assert(plist);
assert(name);
- /* Check for property in property list */
- if(H5P_find_prop(plist->props,plist->pclass->hashsize,name)==NULL)
+ /* Check for property in deleted property list */
+ if(H5TB_dfind(plist->del,name,NULL)!=NULL)
ret_value=0;
- else
- ret_value=1;
+ else {
+ /* Check for property in changed property list */
+ if(H5TB_dfind(plist->props,name,NULL)!=NULL)
+ ret_value=1;
+ else {
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(H5TB_dfind(tclass->props,name,NULL)!=NULL)
+ HGOTO_DONE(1);
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
+
+ /* If we've reached here, we couldn't find the property */
+ ret_value=0;
+ } /* end else */
+ } /* end else */
+done:
FUNC_LEAVE (ret_value);
} /* H5P_exist_plist() */
@@ -2365,7 +2705,7 @@ H5P_exist_pclass(H5P_genclass_t *pclass, const char *name)
assert(name);
/* Check for property in property list */
- if(H5P_find_prop(pclass->props,pclass->hashsize,name)==NULL)
+ if(H5TB_dfind(pclass->props,name,NULL)==NULL)
ret_value=0;
else
ret_value=1;
@@ -2396,7 +2736,8 @@ H5P_exist_pclass(H5P_genclass_t *pclass, const char *name)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-htri_t H5Pexist(hid_t id, const char *name)
+htri_t
+H5Pexist(hid_t id, const char *name)
{
H5P_genplist_t *plist; /* Property list to query */
H5P_genclass_t *pclass; /* Property class to query */
@@ -2467,7 +2808,7 @@ H5P_get_size_plist(H5P_genplist_t *plist, const char *name, size_t *size)
assert(size);
/* Find property */
- if((prop=H5P_find_prop(plist->props,plist->pclass->hashsize,name))==NULL)
+ if((prop=H5P_find_prop_plist(plist,name))==NULL)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
/* Get property size */
@@ -2513,7 +2854,7 @@ H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size)
assert(size);
/* Find property */
- if((prop=H5P_find_prop(pclass->props,pclass->hashsize,name))==NULL)
+ if((prop=H5P_find_prop_pclass(pclass,name))==NULL)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
/* Get property size */
@@ -2547,7 +2888,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pget_size(hid_t id, const char *name, size_t *size)
+herr_t
+H5Pget_size(hid_t id, const char *name, size_t *size)
{
H5P_genclass_t *pclass; /* Property class to query */
H5P_genplist_t *plist; /* Property list to query */
@@ -2643,7 +2985,8 @@ H5P_get_class(H5P_genplist_t *plist)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5Pget_class(hid_t plist_id)
+hid_t
+H5Pget_class(hid_t plist_id)
{
H5P_genplist_t *plist; /* Property list to query */
H5P_genclass_t *pclass=NULL; /* Property list class */
@@ -2730,7 +3073,8 @@ H5P_get_nprops_plist(H5P_genplist_t *plist, size_t *nprops)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops)
+herr_t
+H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -2770,7 +3114,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pget_nprops(hid_t id, size_t *nprops)
+herr_t
+H5Pget_nprops(hid_t id, size_t *nprops)
{
H5P_genplist_t *plist; /* Property list to query */
H5P_genclass_t *pclass; /* Property class to query */
@@ -2853,13 +3198,6 @@ H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2)
if((cmp_value=HDmemcmp(prop1->value,prop2->value,prop1->size))!=0)
HGOTO_DONE(cmp_value);
- /* Check if they both have default values allocated (or not allocated) */
- if(prop1->def_value==NULL && prop2->def_value!=NULL) HGOTO_DONE(-1);
- if(prop1->def_value!=NULL && prop2->def_value==NULL) HGOTO_DONE(1);
- if(prop1->def_value!=NULL)
- if((cmp_value=HDmemcmp(prop1->def_value,prop2->def_value,prop1->size))!=0)
- HGOTO_DONE(cmp_value);
-
/* Check if they both have the same 'create' callback */
if(prop1->create==NULL && prop2->create!=NULL) HGOTO_DONE(-1);
if(prop1->create!=NULL && prop2->create==NULL) HGOTO_DONE(1);
@@ -2890,8 +3228,6 @@ H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2)
if(prop1->close!=NULL && prop2->close==NULL) HGOTO_DONE(1);
if(prop1->close!=prop2->close) HGOTO_DONE(-1);
- /* Don't check the 'next' field, they must be equal by now */
-
done:
FUNC_LEAVE (ret_value);
} /* H5P_cmp_prop() */
@@ -2922,16 +3258,19 @@ done:
static int
H5P_cmp_class(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
{
- H5P_genprop_t *tprop1, *tprop2;/* Temporary pointer to properties */
- unsigned u; /* Local index variable */
- int cmp_value; /* Value from comparison */
- int ret_value=0; /* return value */
+ H5TB_NODE *tnode1,*tnode2; /* Temporary pointer to propery nodes */
+ int cmp_value; /* Value from comparison */
+ int ret_value=0; /* Return value */
FUNC_ENTER_NOINIT(H5P_cmp_class);
assert(pclass1);
assert(pclass2);
+ /* Use the revision number to quickly check for identical classes */
+ if(pclass1->revision==pclass2->revision)
+ HGOTO_DONE(0);
+
/* Check the name */
if((cmp_value=HDstrcmp(pclass1->name,pclass2->name))!=0)
HGOTO_DONE(cmp_value);
@@ -2940,10 +3279,6 @@ H5P_cmp_class(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
if(pclass1->nprops < pclass2->nprops) HGOTO_DONE(-1);
if(pclass1->nprops > pclass2->nprops) HGOTO_DONE(1);
- /* Check the hashsize */
- if(pclass1->hashsize < pclass2->hashsize) HGOTO_DONE(-1);
- if(pclass1->hashsize > pclass2->hashsize) HGOTO_DONE(1);
-
/* Check the number of property lists created from the class */
if(pclass1->plists < pclass2->plists) HGOTO_DONE(-1);
if(pclass1->plists > pclass2->plists) HGOTO_DONE(1);
@@ -2979,29 +3314,21 @@ H5P_cmp_class(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2)
if(pclass1->close_data > pclass2->close_data) HGOTO_DONE(1);
/* Cycle through the properties and compare them also */
- for(u=0; u<pclass1->hashsize; u++) {
- tprop1=pclass1->props[u];
- tprop2=pclass2->props[u];
-
- /* Check if they both have properties in this hash location */
- if(tprop1==NULL && tprop2!=NULL) HGOTO_DONE(-1);
- if(tprop1!=NULL && tprop2==NULL) HGOTO_DONE(1);
-
- /* Check the actual properties */
- while(tprop1!=NULL && tprop2!=NULL) {
- /* Compare the two properties */
- if((cmp_value=H5P_cmp_prop(tprop1,tprop2))!=0)
- HGOTO_DONE(cmp_value);
-
- /* Advance the pointers */
- tprop1=tprop1->next;
- tprop2=tprop2->next;
+ tnode1=H5TB_first(pclass1->props->root);
+ tnode2=H5TB_first(pclass2->props->root);
+ while(tnode1 || tnode2) {
+ /* Check if they both have properties in this TBBT node */
+ if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1);
+ if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1);
+
+ /* Compare the two properties */
+ if((cmp_value=H5P_cmp_prop(tnode1->data,tnode2->data))!=0)
+ HGOTO_DONE(cmp_value);
- /* Check if they both have properties in this location */
- if(tprop1==NULL && tprop2!=NULL) HGOTO_DONE(-1);
- if(tprop1!=NULL && tprop2==NULL) HGOTO_DONE(1);
- } /* end while */
- } /* end for */
+ /* Advance the pointers */
+ tnode1=H5TB_next(tnode1);
+ tnode2=H5TB_next(tnode2);
+ } /* end while */
done:
FUNC_LEAVE (ret_value);
@@ -3033,8 +3360,7 @@ done:
static int
H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2)
{
- H5P_genprop_t *tprop1, *tprop2;/* Temporary pointer to properties */
- unsigned u; /* Local index variable */
+ H5TB_NODE *tnode1,*tnode2; /* Temporary pointer to propery nodes */
int cmp_value; /* Value from comparison */
int ret_value=0; /* return value */
@@ -3043,10 +3369,6 @@ H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2)
assert(plist1);
assert(plist2);
- /* Check the parent class */
- if(plist1->pclass < plist2->pclass) HGOTO_DONE(-1);
- if(plist1->pclass > plist2->pclass) HGOTO_DONE(1);
-
/* Check the number of properties */
if(plist1->nprops < plist2->nprops) HGOTO_DONE(-1);
if(plist1->nprops > plist2->nprops) HGOTO_DONE(1);
@@ -3055,24 +3377,57 @@ H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2)
if(plist1->class_init < plist2->class_init) HGOTO_DONE(-1);
if(plist1->class_init > plist2->class_init) HGOTO_DONE(1);
- /* Cycle through the properties and compare them also */
- for(u=0; u<plist1->pclass->hashsize; u++) {
- tprop1=plist1->props[u];
+ /* Check for identical deleted properties */
+ if(plist1->del->root) {
+ /* Check for no deleted properties in plist2 */
+ if(plist2->del->root==NULL) HGOTO_DONE(1);
+
+ tnode1=H5TB_first(plist1->del->root);
+ tnode2=H5TB_first(plist2->del->root);
+ while(tnode1 || tnode2) {
+ /* Check if they both have properties in this TBBT node */
+ if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1);
+ if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1);
+
+ /* Compare the two deleted properties */
+ if((cmp_value=HDstrcmp(tnode1->data,tnode2->data))!=0)
+ HGOTO_DONE(cmp_value);
+
+ /* Advance the pointers */
+ tnode1=H5TB_next(tnode1);
+ tnode2=H5TB_next(tnode2);
+ } /* end while */
+ } /* end if */
+ else
+ if(plist2->del->root!=NULL) HGOTO_DONE (-1);
- /* Check the actual properties */
- while(tprop1!=NULL) {
- /* Find a property with the same name in the second property list */
- if((tprop2=H5P_find_prop(plist2->props,plist2->pclass->hashsize,tprop1->name))==NULL)
- HGOTO_DONE(1);
+ /* Cycle through the changed properties and compare them also */
+ if(plist1->props->root) {
+ /* Check for no changed properties in plist2 */
+ if(plist2->props->root==NULL) HGOTO_DONE(1);
+
+ tnode1=H5TB_first(plist1->props->root);
+ tnode2=H5TB_first(plist2->props->root);
+ while(tnode1 || tnode2) {
+ /* Check if they both have properties in this TBBT node */
+ if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1);
+ if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1);
/* Compare the two properties */
- if((cmp_value=H5P_cmp_prop(tprop1,tprop2))!=0)
+ if((cmp_value=H5P_cmp_prop(tnode1->data,tnode2->data))!=0)
HGOTO_DONE(cmp_value);
- /* Advance to next property */
- tprop1=tprop1->next;
+ /* Advance the pointers */
+ tnode1=H5TB_next(tnode1);
+ tnode2=H5TB_next(tnode2);
} /* end while */
- } /* end for */
+ } /* end if */
+ else
+ if(plist2->props->root!=NULL) HGOTO_DONE (-1);
+
+ /* Check the parent classes */
+ if((cmp_value=H5P_cmp_class(plist1->pclass,plist2->pclass))!=0)
+ HGOTO_DONE(cmp_value);
done:
FUNC_LEAVE (ret_value);
@@ -3099,7 +3454,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-htri_t H5Pequal(hid_t id1, hid_t id2)
+htri_t
+H5Pequal(hid_t id1, hid_t id2)
{
void *obj1, *obj2; /* Property objects to compare */
htri_t ret_value=FALSE; /* return value */
@@ -3205,7 +3561,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id)
+htri_t
+H5P_isa_class(hid_t plist_id, hid_t pclass_id)
{
H5P_genplist_t *plist; /* Property list to query */
H5P_genclass_t *pclass; /* Property list class */
@@ -3251,7 +3608,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-htri_t H5Pisa_class(hid_t plist_id, hid_t pclass_id)
+htri_t
+H5Pisa_class(hid_t plist_id, hid_t pclass_id)
{
htri_t ret_value; /* return value */
@@ -3300,7 +3658,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void *H5P_object_verify(hid_t plist_id, hid_t pclass_id)
+void *
+H5P_object_verify(hid_t plist_id, hid_t pclass_id)
{
void *ret_value; /* return value */
@@ -3321,100 +3680,6 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5P_iterate_props
- PURPOSE
- Internal routine to iterate over a hashtable of properties
- USAGE
- herr_t H5P_iterate_props(id, hash, hashsize, idx, iter_func, iter_data)
- hid_t id; IN: ID of property object iterating over
- H5P_gen_prop_t *hash[]; IN: Pointer to array of properties for hash table
- unsigned hashsize; IN: Size of hash table
- int *idx; IN/OUT: Index of the property to begin with
- H5P_iterate_t iter_func; IN: Function pointer to function to be
- called with each property iterated over.
- void *iter_data; IN/OUT: Pointer to iteration data from user
- RETURNS
- Success: Returns the return value of the last call to ITER_FUNC if it was
- non-zero, or zero if all properties have been processed.
- Failure: negative value
- DESCRIPTION
- This routine iterates over the properties in the property object specified
-with ID. For each property in the object, the ITER_DATA and some
-additional information, specified below, are passed to the ITER_FUNC function.
-The iteration begins with the IDX property in the object and the next element
-to be processed by the operator is returned in IDX. If IDX is NULL, then the
-iterator starts at the first property; since no stopping point is returned in
-this case, the iterator cannot be restarted if one of the calls to its operator
-returns non-zero.
-
-The prototype for H5P_iterate_t is:
- typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
-The operation receives the property list or class identifier for the object
-being iterated over, ID, the name of the current property within the object,
-NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
-
-The return values from an operator are:
- Zero causes the iterator to continue, returning zero when all properties
- have been processed.
- Positive causes the iterator to immediately return that positive value,
- indicating short-circuit success. The iterator can be restarted at the
- index of the next property.
- Negative causes the iterator to immediately return that value, indicating
- failure. The iterator can be restarted at the index of the next
- property.
-
-H5Piterate assumes that the properties in the object identified by ID remains
-unchanged through the iteration. If the membership changes during the
-iteration, the function's behavior is undefined.
-
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static int
-H5P_iterate_props(hid_t id, H5P_genprop_t *hash[], unsigned hashsize, int *idx, H5P_iterate_t iter_func, void *iter_data)
-{
- H5P_genprop_t *prop; /* Temporary property pointer */
- unsigned u; /* Local index variable */
- int curr_idx=0; /* Current iteration index */
- int ret_value=0; /* Return value */
-
- FUNC_ENTER_NOINIT(H5P_iterate_props);
-
- assert(hash);
- assert(hashsize>0);
- assert(idx);
- assert(iter_func);
-
- /* Cycle through the properties and compare them also */
- for(u=0; u<hashsize && ret_value==0; u++) {
- prop=hash[u];
-
- /* Check the actual properties */
- while(prop!=NULL && ret_value==0) {
- /* Check if we are at the object to start iterating over */
- if(curr_idx>=*idx)
- ret_value=(*iter_func)(id,prop->name,iter_data);
-
- /* Increment the iteration index if iteration function succeeded */
- if(ret_value==0)
- curr_idx++;
-
- /* Advance the pointer */
- prop=prop->next;
- } /* end while */
- } /* end for */
-
- /* Set the index we stopped at */
- *idx=curr_idx;
-
- FUNC_LEAVE (ret_value);
-} /* H5P_iterate_props() */
-
-
-/*--------------------------------------------------------------------------
- NAME
H5P_iterate_plist
PURPOSE
Internal routine to iterate over the properties in a property list
@@ -3467,8 +3732,13 @@ iteration, the function's behavior is undefined.
static int
H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_data)
{
+ H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genplist_t *plist; /* Property list pointer */
- int ret_value; /* Return value */
+ H5P_genprop_t *tmp; /* Temporary pointer to properties */
+ H5TB_TREE *seen=NULL; /* TBBT to hold names of properties already seen */
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ int curr_idx=0; /* Current iteration index */
+ int ret_value=FAIL; /* Return value */
FUNC_ENTER_NOINIT(H5P_iterate_plist);
@@ -3479,10 +3749,90 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_
if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
- /* Iterate through the properties in the property list */
- ret_value=H5P_iterate_props(plist_id, plist->props, plist->pclass->hashsize, idx, iter_func, iter_data);
+ /* Create the TBBT to hold names of properties already seen
+ */
+ if((seen=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for seen properties");
+
+ /* Walk through the changed properties in the list */
+ if(plist->props->root) {
+ curr_node=H5TB_first(plist->props->root);
+ while(curr_node!=NULL) {
+ /* Get pointer to property from node */
+ tmp=curr_node->data;
+
+ /* Check if we've found the correctly indexed property */
+ if(curr_idx>=*idx) {
+ /* Call the callback function */
+ ret_value=(*iter_func)(plist_id,tmp->name,iter_data);
+
+ if(ret_value!=0)
+ HGOTO_DONE(ret_value);
+ } /* end if */
+
+ /* Increment the current index */
+ curr_idx++;
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,tmp->name,tmp->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
+
+ /* Walk up the class hiearchy */
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Walk through the properties in the class */
+ curr_node=H5TB_first(tclass->props->root);
+ while(curr_node!=NULL) {
+ /* Get pointer to property from node */
+ tmp=curr_node->data;
+
+ /* Only call iterator callback for properties we haven't seen
+ * before and that haven't been deleted
+ */
+ if(H5TB_dfind(seen,tmp->name,NULL)==NULL &&
+ H5TB_dfind(plist->del,tmp->name,NULL)==NULL) {
+
+
+ /* Check if we've found the correctly indexed property */
+ if(curr_idx>=*idx) {
+ /* Call the callback function */
+ ret_value=(*iter_func)(plist_id,tmp->name,iter_data);
+
+ if(ret_value!=0)
+ HGOTO_DONE(ret_value);
+ } /* end if */
+
+ /* Increment the current index */
+ curr_idx++;
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,tmp->name,tmp->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
+ } /* end if */
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
done:
+ /* Set the index we stopped at */
+ *idx=curr_idx;
+
+ /* Release the tree of 'seen' properties */
+ if(seen!=NULL)
+ H5TB_dfree(seen,NULL,NULL);
+
FUNC_LEAVE (ret_value);
} /* H5P_iterate_plist() */
@@ -3542,7 +3892,10 @@ static int
H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *iter_data)
{
H5P_genclass_t *pclass; /* Property list pointer */
- int ret_value; /* Return value */
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ H5P_genprop_t *prop; /* Temporary property pointer */
+ int curr_idx=0; /* Current iteration index */
+ int ret_value=FAIL; /* Return value */
FUNC_ENTER_NOINIT(H5P_iterate_pclass);
@@ -3553,10 +3906,33 @@ H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *ite
if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
- /* Iterate through the properties in the property list */
- ret_value=H5P_iterate_props(pclass_id, pclass->props, pclass->hashsize, idx, iter_func, iter_data);
+ /* Set the current index */
+ curr_idx=*idx;
+
+ /* Cycle through the properties and call the callback */
+ curr_node=H5TB_index(pclass->props->root,(unsigned)*idx);
+ while(curr_node!=NULL) {
+ /* Get the property for the node */
+ prop=curr_node->data;
+
+ /* Call the callback function */
+ ret_value=(*iter_func)(pclass_id,prop->name,iter_data);
+
+ /* Check if iteration function succeeded */
+ if(ret_value!=0)
+ HGOTO_DONE(ret_value);
+
+ /* Increment the iteration index */
+ curr_idx++;
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
done:
+ /* Set the index we stopped at */
+ *idx=curr_idx;
+
FUNC_LEAVE (ret_value);
} /* H5P_iterate_pclass() */
@@ -3613,7 +3989,8 @@ iteration, the function's behavior is undefined.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-int H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data)
+int
+H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data)
{
int fake_idx=0; /* Index when user doesn't provide one */
int ret_value; /* return value */
@@ -3672,7 +4049,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-unsigned H5P_peek_unsigned(H5P_genplist_t *plist, const char *name)
+unsigned
+H5P_peek_unsigned(H5P_genplist_t *plist, const char *name)
{
unsigned ret_value; /* return value */
@@ -3716,7 +4094,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5P_peek_hid_t(H5P_genplist_t *plist, const char *name)
+hid_t
+H5P_peek_hid_t(H5P_genplist_t *plist, const char *name)
{
hid_t ret_value; /* return value */
@@ -3760,7 +4139,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void *H5P_peek_voidp(H5P_genplist_t *plist, const char *name)
+void *
+H5P_peek_voidp(H5P_genplist_t *plist, const char *name)
{
void * ret_value; /* return value */
@@ -3804,7 +4184,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hsize_t H5P_peek_hsize_t(H5P_genplist_t *plist, const char *name)
+hsize_t
+H5P_peek_hsize_t(H5P_genplist_t *plist, const char *name)
{
hsize_t ret_value; /* return value */
@@ -3848,7 +4229,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-size_t H5P_peek_size_t(H5P_genplist_t *plist, const char *name)
+size_t
+H5P_peek_size_t(H5P_genplist_t *plist, const char *name)
{
size_t ret_value; /* return value */
@@ -3893,9 +4275,12 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value)
+herr_t
+H5P_get(H5P_genplist_t *plist, const char *name, void *value)
{
+ H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genprop_t *prop; /* Temporary property pointer */
+ H5TB_NODE *prop_node; /* TBBT node holding property */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5P_get, FAIL);
@@ -3904,36 +4289,113 @@ herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value)
assert(name);
assert(value);
- /* Find property */
- if((prop=H5P_find_prop(plist->props,plist->pclass->hashsize,name))==NULL)
+ /* Check if the property has been deleted */
+ if(H5TB_dfind(plist->del,name,NULL)!=NULL)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
- /* Check for property size >0 */
- if(prop->size==0)
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
+ /* Find property */
+ if((prop_node=H5TB_dfind(plist->props,name,NULL))!=NULL) {
+ /* Get pointer to actual property */
+ prop=prop_node->data;
+
+ /* Check for property size >0 */
+ if(prop->size==0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
- /* Make a copy of the value and pass to 'get' callback */
- if(prop->get!=NULL) {
- void *tmp_value; /* Temporary value for property */
+ /* Make a copy of the value and pass to 'get' callback */
+ if(prop->get!=NULL) {
+ void *tmp_value; /* Temporary value for property */
- /* Make a copy of the current value, in case the callback fails */
- if (NULL==(tmp_value=H5MM_malloc(prop->size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
- HDmemcpy(tmp_value,prop->value,prop->size);
+ /* Make a copy of the current value, in case the callback fails */
+ if (NULL==(tmp_value=H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
+ HDmemcpy(tmp_value,prop->value,prop->size);
- /* Call user's callback */
- if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value");
+ /* Call user's callback */
+ if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value");
- /* Copy new [possibly unchanged] value into return value */
- HDmemcpy(value,tmp_value,prop->size);
+ /* Copy new [possibly unchanged] value into return value */
+ HDmemcpy(value,tmp_value,prop->size);
- /* Free the temporary value buffer */
- H5MM_xfree(tmp_value);
+ /* Free the temporary value buffer */
+ H5MM_xfree(tmp_value);
+ } /* end if */
+ /* No 'get' callback, just copy value */
+ else
+ HDmemcpy(value,prop->value,prop->size);
} /* end if */
- /* No 'get' callback, just copy value */
- else
- HDmemcpy(value,prop->value,prop->size);
+ else {
+ /*
+ * Check if we should get class properties (up through list of parent classes also),
+ * & make property 'get' callback.
+ */
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Find the property in the class */
+ if((prop_node=H5TB_dfind(tclass->props,name,NULL))!=NULL) {
+ /* Get pointer to actual property */
+ prop=prop_node->data;
+
+ /* Check for property size >0 */
+ if(prop->size==0)
+ HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
+
+ /* Call the 'get' callback, if there is one */
+ if(prop->get!=NULL) {
+ void *tmp_value; /* Temporary value for property */
+
+ /* Make a copy of the current value, in case the callback fails */
+ if (NULL==(tmp_value=H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value");
+ HDmemcpy(tmp_value,prop->value,prop->size);
+
+ /* Call user's callback */
+ if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0) {
+ H5MM_xfree(tmp_value);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
+ } /* end if */
+
+ if(HDmemcmp(tmp_value,prop->value,prop->size)) {
+ H5P_genprop_t *pcopy; /* Copy of property to insert into TBBT */
+
+ /* Make a copy of the class's property */
+ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
+
+ /* Copy new value into property value */
+ HDmemcpy(pcopy->value,tmp_value,prop->size);
+
+ /* Insert the changed property into the property list */
+ if(H5P_add_prop(plist->props,pcopy)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into TBBT");
+ } /* end if */
+
+ /* Copy new [possibly unchanged] value into return value */
+ HDmemcpy(value,tmp_value,prop->size);
+
+ /* Free the temporary value buffer */
+ H5MM_xfree(tmp_value);
+ } /* end if */
+ /* No 'get' callback, just copy value */
+ else
+ HDmemcpy(value,prop->value,prop->size);
+
+ /* Leave */
+ HGOTO_DONE(SUCCEED);
+ } /* end while */
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
+
+ /* If we get this far, then it wasn't in the list of changed properties,
+ * nor in the properties in the class hierarchy, indicate an error
+ */
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in TBBT");
+ } /* end else */
done:
FUNC_LEAVE (ret_value);
@@ -3968,7 +4430,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pget(hid_t plist_id, const char *name, void * value)
+herr_t
+H5Pget(hid_t plist_id, const char *name, void * value)
{
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value=SUCCEED; /* return value */
@@ -4021,63 +4484,106 @@ done:
herr_t
H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name)
{
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+ H5TB_NODE *curr_node; /* TBBT node holding property */
H5P_genprop_t *prop; /* Temporary property pointer */
- H5P_genprop_t *tprop, *prev;/* Temporary pointer to properties */
- unsigned loc; /* Hash table location */
- herr_t ret_value=SUCCEED; /* Return value */
+ char *del_name; /* Pointer to deleted name */
+ herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOINIT(H5P_remove);
+ FUNC_ENTER_NOAPI(H5P_remove,FAIL);
assert(plist);
assert(name);
- /* Find the property in the property list */
- if((prop=H5P_find_prop(plist->props,plist->pclass->hashsize,name))==NULL)
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
+ /* Indicate that the property isn't in the list if it has been deleted already */
+ if(H5TB_dfind(plist->del,name,NULL)!=NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in TBBT");
- /* Pass value to 'close' callback, if it exists */
- if(prop->del!=NULL) {
- /* Call user's callback */
- if((*(prop->del))(plist_id,name,prop->size,prop->value)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value");
- } /* end if */
+ /* Get the property node from the changed property TBBT */
+ if((curr_node=H5TB_dfind(plist->props,name,NULL))!=NULL) {
+ /* Get pointer to property for node */
+ prop=curr_node->data;
- /* Get correct hash table location */
- loc=H5P_hash_name(name,plist->pclass->hashsize);
-
- /* Remove property from property list */
- /* Check if the property being removed is at the head of the list for a hash location */
- if(prop==plist->props[loc]) {
- /* Jump over the property we are deleting */
- plist->props[loc]=prop->next;
+ /* Pass value to 'close' callback, if it exists */
+ if(prop->del!=NULL) {
+ /* Call user's callback */
+ if((*(prop->del))(plist_id,name,prop->size,prop->value)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value");
+ } /* end if */
+
+ /* Duplicate string for insertion into new deleted property TBBT */
+ if((del_name=H5MM_xstrdup(name))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
+
+ /* Insert property name into deleted list */
+ if(H5TB_dins(plist->del,del_name,del_name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted TBBT");
+
+ /* Remove the property from the TBBT */
+ if(H5TB_rem(&plist->props->root,curr_node,NULL)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from TBBT");
/* Free the property, ignoring return value, nothing we can do */
H5P_free_prop(prop);
+
+ /* Decrement the number of properties in list */
+ plist->nprops--;
} /* end if */
+ /* Walk through all the properties in the class hierarchy, looking for the property */
else {
- /* Set up initial pointers */
- prev=tprop=plist->props[loc];
- tprop=tprop->next;
- while(tprop!=NULL) {
- if(tprop==prop) {
- /* Jump over the property we are deleting */
- prev->next=prop->next;
-
- /* Free the property, ignoring return value, nothing we can do */
- H5P_free_prop(prop);
-
- /* Break out of while loop */
- break;
+ /*
+ * Check if we should delete class properties (up through list of parent classes also),
+ * & make property 'delete' callback.
+ */
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Find the property in the class */
+ if((prop=H5P_find_prop_pclass(tclass,name))!=NULL) {
+ /* Pass value to 'del' callback, if it exists */
+ if(prop->del!=NULL) {
+ void *tmp_value; /* Temporary value buffer */
+
+ /* Allocate space for a temporary copy of the property value */
+ if (NULL==(tmp_value=H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value");
+ HDmemcpy(tmp_value,prop->value,prop->size);
+
+ /* Call user's callback */
+ if((*(prop->del))(plist_id,name,prop->size,tmp_value)<0) {
+ H5MM_xfree(tmp_value);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value");
+ } /* end if */
+
+ /* Release the temporary value buffer */
+ H5MM_xfree(tmp_value);
+ } /* end if */
+
+ /* Duplicate string for insertion into new deleted property TBBT */
+ if((del_name=H5MM_xstrdup(name))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
+
+ /* Insert property name into deleted list */
+ if(H5TB_dins(plist->del,del_name,del_name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted TBBT");
+
+ /* Decrement the number of properties in list */
+ plist->nprops--;
+
+ /* Leave */
+ HGOTO_DONE(SUCCEED);
+ } /* end while */
} /* end if */
- /* Move to the next nodes */
- prev=tprop;
- tprop=tprop->next;
+ /* Go up to parent class */
+ tclass=tclass->parent;
} /* end while */
- } /* end else */
- /* Decrement the number of properties in list */
- plist->nprops--;
+ /* If we get this far, then it wasn't in the list of changed properties,
+ * nor in the properties in the class hierarchy, indicate an error
+ */
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in TBBT");
+ } /* end else */
done:
FUNC_LEAVE (ret_value);
@@ -4110,7 +4616,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Premove(hid_t plist_id, const char *name)
+herr_t
+H5Premove(hid_t plist_id, const char *name)
{
H5P_genplist_t *plist; /* Property list to modify */
herr_t ret_value; /* return value */
@@ -4180,20 +4687,17 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
if(NULL == (src_plist = H5I_object(src_id)) || NULL == (dst_plist = H5I_object(dst_id)))
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
- /* Check if the property exists in the destination */
- prop=H5P_find_prop(dst_plist->props,dst_plist->pclass->hashsize,name);
-
/* If the property exists in the destination alread */
- if(prop!=NULL) {
+ if(H5P_find_prop_plist(dst_plist,name)!=NULL) {
/* Delete the property from the destination list, calling the 'close' callback if necessary */
if(H5P_remove(dst_id,dst_plist,name)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
/* Get the pointer to the source property */
- prop=H5P_find_prop(src_plist->props,src_plist->pclass->hashsize,name);
+ prop=H5P_find_prop_plist(src_plist,name);
/* Make a copy of the source property */
- if((new_prop=H5P_dup_prop(prop))==NULL)
+ if((new_prop=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
/* Call property copy callback, if it exists */
@@ -4203,7 +4707,7 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
} /* end if */
/* Insert the initialized property into the property list */
- if(H5P_add_prop(dst_plist->props,dst_plist->pclass->hashsize,new_prop)<0)
+ if(H5P_add_prop(dst_plist->props,new_prop)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list");
/* Increment the number of properties in list */
@@ -4212,10 +4716,10 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
/* If not, get the information required to do an H5Pinsert with the property into the destination list */
else {
/* Get the pointer to the source property */
- prop=H5P_find_prop(src_plist->props,src_plist->pclass->hashsize,name);
+ prop=H5P_find_prop_plist(src_plist,name);
/* Create property object from parameters */
- if((new_prop=H5P_create_prop(prop->name,prop->size,prop->def_value,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->copy))==NULL)
+ if((new_prop=H5P_create_prop(prop->name,prop->size,H5P_PROP_WITHIN_LIST,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->copy))==NULL)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property");
/* Call property creation callback, if it exists */
@@ -4225,7 +4729,7 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
} /* end if */
/* Insert property into property list class */
- if(H5P_add_prop(dst_plist->props,dst_plist->pclass->hashsize,new_prop)<0)
+ if(H5P_add_prop(dst_plist->props,new_prop)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class");
/* Increment property count for class */
@@ -4274,7 +4778,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t UNUSED *src_pclass, const char *name)
+H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, const char *name)
{
H5P_genprop_t *prop; /* Temporary property pointer */
herr_t ret_value=SUCCEED; /* return value */
@@ -4285,18 +4789,19 @@ H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t UNUSED *src_pcla
assert(src_pclass);
assert(name);
- /* Check if the property exists in the destination */
- prop=H5P_find_prop(dst_pclass->props,dst_pclass->hashsize,name);
-
/* If the property exists in the destination already */
- if(prop!=NULL) {
+ if(H5P_exist_pclass(dst_pclass,name)) {
/* Delete the old property from the destination class */
if(H5P_unregister(dst_pclass,name)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
} /* end if */
+ /* Get the property from the source */
+ if((prop=H5P_find_prop_pclass(src_pclass,name))==NULL)
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property");
+
/* Register the property into the destination */
- if(H5P_register(dst_pclass,name,prop->size,prop->def_value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->close)<0)
+ if(H5P_register(dst_pclass,name,prop->size,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->close)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
done:
@@ -4404,9 +4909,8 @@ done:
static herr_t
H5P_unregister(H5P_genclass_t *pclass, const char *name)
{
+ H5TB_NODE *prop_node; /* TBBT node holding property */
H5P_genprop_t *prop; /* Temporary property pointer */
- H5P_genprop_t *tprop, *prev;/* Temporary pointer to properties */
- unsigned loc; /* Hash table location */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5P_unregister);
@@ -4414,46 +4918,26 @@ H5P_unregister(H5P_genclass_t *pclass, const char *name)
assert(pclass);
assert(name);
- /* Find the property in the property list */
- if((prop=H5P_find_prop(pclass->props,pclass->hashsize,name))==NULL)
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
+ /* Get the property node from the TBBT */
+ if((prop_node=H5TB_dfind(pclass->props,name,NULL))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in TBBT");
- /* Get correct hash table location */
- loc=H5P_hash_name(name,pclass->hashsize);
-
- /* Remove property from property list */
- /* Check if the property being removed is at the head of the list for a hash location */
- if(prop==pclass->props[loc]) {
- pclass->props[loc]=prop->next;
+ /* Get the pointer to the property */
+ prop=prop_node->data;
- /* Free the property, ignoring return value, nothing we can do */
- H5P_free_prop(prop);
- } /* end if */
- else {
- /* Set up initial pointers */
- prev=tprop=pclass->props[loc];
- tprop=tprop->next;
- while(tprop!=NULL) {
- if(tprop==prop) {
- /* Jump over the property we are deleting */
- prev->next=prop->next;
-
- /* Free the property, ignoring return value, nothing we can do */
- H5P_free_prop(prop);
-
- /* Break out of while loop */
- break;
- } /* end if */
+ /* Remove the property from the TBBT */
+ if(H5TB_rem(&pclass->props->root,prop_node,NULL)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from TBBT");
- /* Move to the next nodes */
- prev=tprop;
- tprop=tprop->next;
- } /* end while */
- } /* end else */
+ /* Free the property, ignoring return value, nothing we can do */
+ H5P_free_prop(prop);
/* Decrement the number of registered properties in class */
pclass->nprops--;
+ /* Update the revision for the class */
+ pclass->revision = H5P_GET_NEXT_REV;
+
done:
FUNC_LEAVE (ret_value);
} /* H5P_unregister() */
@@ -4480,7 +4964,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Punregister(hid_t pclass_id, const char *name)
+herr_t
+H5Punregister(hid_t pclass_id, const char *name)
{
H5P_genclass_t *pclass; /* Property list class to modify */
herr_t ret_value; /* return value */
@@ -4529,8 +5014,12 @@ done:
herr_t
H5P_close(void *_plist)
{
+ H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genplist_t *plist=(H5P_genplist_t *)_plist;
- herr_t ret_value=SUCCEED; /* return value */
+ H5TB_TREE *seen=NULL; /* TBBT to hold names of properties already seen */
+ H5TB_NODE *curr_node; /* Current node in TBBT */
+ H5P_genprop_t *tmp; /* Temporary pointer to properties */
+ herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER_NOINIT(H5P_close);
@@ -4542,17 +5031,106 @@ H5P_close(void *_plist)
(plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data);
} /* end if */
- /* Make calls to any property close callbacks which exist */
- H5P_free_all_prop(plist->props,plist->pclass->hashsize,1);
+ /* Create the TBBT to hold names of properties already seen
+ * (This prevents a property in the class hierarchy from having it's
+ * 'close' callback called, if a property in the class hierarchy has
+ * already been seen)
+ */
+ if((seen=H5TB_fast_dmake(H5TB_FAST_STR_COMPARE))==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTMAKETREE,NULL,"can't create TBBT for seen properties");
+
+ /* Walk through the changed properties in the list */
+ if(plist->props->root) {
+ curr_node=H5TB_first(plist->props->root);
+ while(curr_node!=NULL) {
+ /* Get pointer to property from node */
+ tmp=curr_node->data;
+
+ /* Call property close callback, if it exists */
+ if(tmp->close) {
+ /* Call the 'close' callback */
+ (tmp->close)(tmp->name,tmp->size,tmp->value);
+ } /* end if */
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,tmp->name,tmp->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
+
+ /*
+ * Check if we should remove class properties (up through list of parent classes also),
+ * initialize each with default value & make property 'remove' callback.
+ */
+ tclass=plist->pclass;
+ while(tclass!=NULL) {
+ if(tclass->nprops>0) {
+ /* Walk through the properties in the class */
+ curr_node=H5TB_first(tclass->props->root);
+ while(curr_node!=NULL) {
+ /* Get pointer to property from node */
+ tmp=curr_node->data;
+
+ /* Only "delete" properties we haven't seen before
+ * and that haven't already been deleted
+ */
+ if(H5TB_dfind(seen,tmp->name,NULL)==NULL &&
+ H5TB_dfind(plist->del,tmp->name,NULL)==NULL) {
+
+ /* Call property close callback, if it exists */
+ if(tmp->close) {
+ void *tmp_value; /* Temporary value buffer */
+
+ /* Allocate space for a temporary copy of the property value */
+ if (NULL==(tmp_value=H5MM_malloc(tmp->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for temporary property value");
+ HDmemcpy(tmp_value,tmp->value,tmp->size);
+
+ /* Call the 'close' callback */
+ (tmp->close)(tmp->name,tmp->size,tmp_value);
+
+ /* Release the temporary value buffer */
+ H5MM_xfree(tmp_value);
+ } /* end if */
+
+ /* Add property name to "seen" list */
+ if(H5TB_dins(seen,tmp->name,tmp->name)==NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen TBBT");
+ } /* end if */
+
+ /* Get the next property node in the TBBT */
+ curr_node=H5TB_next(curr_node);
+ } /* end while */
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass=tclass->parent;
+ } /* end while */
/* Decrement class's dependant property list value! */
if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count");
+ /* Free the list of 'seen' properties */
+ seen=H5TB_dfree(seen,NULL,NULL);
+
+ /* Free the list of deleted property names */
+ H5TB_dfree(plist->del,free,NULL);
+
+ /* Free the property tree itself */
+ H5TB_dfree(plist->props,H5P_free_prop,NULL);
+
/* Destroy property list object */
- H5MM_xfree(plist);
+ H5FL_FREE(H5P_genplist_t,plist);
done:
+ /* Release the tree of 'seen' properties */
+ if(seen!=NULL)
+ H5TB_dfree(seen,NULL,NULL);
+
FUNC_LEAVE (ret_value);
} /* H5P_close() */
@@ -4578,7 +5156,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5Pclose(hid_t plist_id)
+herr_t
+H5Pclose(hid_t plist_id)
{
H5P_genplist_t *plist; /* Property list created */
herr_t ret_value=SUCCEED; /* return value */
@@ -4625,7 +5204,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-char *H5P_get_class_name(H5P_genclass_t *pclass)
+char *
+H5P_get_class_name(H5P_genclass_t *pclass)
{
char *ret_value; /* return value */
@@ -4661,7 +5241,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-char *H5Pget_class_name(hid_t pclass_id)
+char *
+H5Pget_class_name(hid_t pclass_id)
{
H5P_genclass_t *pclass; /* Property class to query */
char *ret_value; /* return value */
@@ -4889,7 +5470,8 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5P_open_class_path_test(const char *path)
+hid_t
+H5P_open_class_path_test(const char *path)
{
H5P_genclass_t *pclass=NULL;/* Property class to query */
hid_t ret_value; /* Return value */
@@ -4970,7 +5552,8 @@ H5P_get_class_parent(H5P_genclass_t *pclass)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hid_t H5Pget_class_parent(hid_t pclass_id)
+hid_t
+H5Pget_class_parent(hid_t pclass_id)
{
H5P_genclass_t *pclass; /* Property class to query */
H5P_genclass_t *parent=NULL; /* Parent's property class */
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index c034156..92ebfc2 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -963,7 +963,7 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/)
HDmemcpy(buf, fill.buf, H5T_get_size(fill.type));
/* Do the conversion */
- if (H5T_convert(tpath, src_id, type_id, (hsize_t)1, 0, 0, buf, bkg, H5P_DEFAULT)<0)
+ if (H5T_convert(tpath, src_id, type_id, (hsize_t)1, 0, 0, buf, bkg, H5P_DATASET_XFER_DEFAULT)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
if (buf!=value)
HDmemcpy(value, buf, H5T_get_size(type));
@@ -980,7 +980,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5P_fill_value_defined
+ * Function: H5P_is_fill_value_defined
*
* Purpose: Check if fill value is defined. Internal version of function
*
@@ -990,35 +990,30 @@ done:
* Wednesday, January 16, 2002
*
* Modifications:
- *
+ * Extracted from H5P_fill_value_defined, QAK, Dec. 13, 2002
*
*-------------------------------------------------------------------------
*/
herr_t
-H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status)
+H5P_is_fill_value_defined(const struct H5O_fill_t *fill, H5D_fill_value_t *status)
{
herr_t ret_value = SUCCEED;
- H5O_fill_t fill;
- FUNC_ENTER_NOAPI(H5P_fill_value_defined, FAIL);
+ FUNC_ENTER_NOAPI(H5P_is_fill_value_defined, FAIL);
- assert(plist);
+ assert(fill);
assert(status);
- /* Get the fill value struct */
- if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
-
/* Check if the fill value was never set */
- if(fill.size == (size_t)-1 && !fill.buf) {
+ if(fill->size == (size_t)-1 && !fill->buf) {
*status = H5D_FILL_VALUE_UNDEFINED;
}
/* Check if the fill value was set to the default fill value by the library */
- else if(fill.size == 0 && !fill.buf) {
+ else if(fill->size == 0 && !fill->buf) {
*status = H5D_FILL_VALUE_DEFAULT;
}
/* Check if the fill value was set by the application */
- else if(fill.size > 0 && fill.buf) {
+ else if(fill->size > 0 && fill->buf) {
*status = H5D_FILL_VALUE_USER_DEFINED;
}
else {
@@ -1028,6 +1023,45 @@ H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status)
done:
FUNC_LEAVE(ret_value);
+} /* end H5P_is_fill_value_defined() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_fill_value_defined
+ *
+ * Purpose: Check if fill value is defined. Internal version of function
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, January 16, 2002
+ *
+ * Modifications:
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status)
+{
+ herr_t ret_value = SUCCEED;
+ H5O_fill_t fill;
+
+ FUNC_ENTER_NOAPI(H5P_fill_value_defined, FAIL);
+
+ assert(plist);
+ assert(status);
+
+ /* Get the fill value struct */
+ if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
+
+ /* Get the fill-value status */
+ if(H5P_is_fill_value_defined(&fill, status) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't check fill value status");
+
+done:
+ FUNC_LEAVE(ret_value);
} /* end H5P_fill_value_defined() */
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 2e32e0a..ba4be48 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -526,7 +526,7 @@ herr_t H5Pset_family_offset(hid_t fapl_id, hsize_t offset)
/* Get the plist structure */
if(H5P_DEFAULT == fapl_id)
- fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't modify default property list");
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Set values */
@@ -600,7 +600,7 @@ herr_t H5Pget_family_offset(hid_t fapl_id, hsize_t *offset)
/* Get the plist structure */
if(H5P_DEFAULT == fapl_id)
- fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't modify default property list");
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Set values */
@@ -674,7 +674,7 @@ herr_t H5Pset_multi_type(hid_t fapl_id, H5FD_mem_t type)
/* Get the plist structure */
if(H5P_DEFAULT == fapl_id)
- fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't modify default property list");
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Set values */
@@ -748,7 +748,7 @@ herr_t H5Pget_multi_type(hid_t fapl_id, H5FD_mem_t *type)
/* Get the plist structure */
if(H5P_DEFAULT == fapl_id)
- fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't modify default property list");
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Set values */
diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h
index b600769..65b76a0 100644
--- a/src/H5Ppkg.h
+++ b/src/H5Ppkg.h
@@ -24,6 +24,14 @@
#endif
#include "H5Pprivate.h"
+#include "H5TBprivate.h" /* TBBTs */
+
+/* Define enum for type of object that property is within */
+typedef enum {
+ H5P_PROP_WITHIN_UNKNOWN=0, /* Property container is unknown */
+ H5P_PROP_WITHIN_LIST, /* Property is within a list */
+ H5P_PROP_WITHIN_CLASS /* Property is within a class */
+} H5P_prop_within_t;
/* Define enum for modifications to class */
typedef enum {
@@ -40,21 +48,19 @@ typedef enum {
/* Define structure to hold property information */
typedef struct H5P_genprop_t {
/* Values for this property */
- unsigned xor_val; /* XOR'ed version of the name, for faster comparisons */
char *name; /* Name of property */
size_t size; /* Size of property value */
void *value; /* Pointer to property value */
+ H5P_prop_within_t type; /* Type of object the property is within */
+ unsigned shared_name; /* Boolean: whether the name is shared or not */
/* Callback function pointers & info */
H5P_prp_create_func_t create; /* Function to call when a property is created */
- void *def_value; /* Pointer to default value to pass along to create callback */
H5P_prp_set_func_t set; /* Function to call when a property value is set */
H5P_prp_get_func_t get; /* Function to call when a property value is retrieved */
H5P_prp_delete_func_t del; /* Function to call when a property is deleted */
H5P_prp_copy_func_t copy; /* Function to call when a property is copied */
H5P_prp_close_func_t close; /* Function to call when a property is closed */
-
- struct H5P_genprop_t *next; /* Pointer to the next property in this list */
} H5P_genprop_t;
/* Define structure to hold class information */
@@ -62,12 +68,13 @@ struct H5P_genclass_t {
struct H5P_genclass_t *parent; /* Pointer to parent class */
char *name; /* Name of property list class */
size_t nprops; /* Number of properties in class */
- unsigned hashsize; /* Hash table size */
unsigned plists; /* Number of property lists that have been created since the last modification to the class */
unsigned classes; /* Number of classes that have been derived since the last modification to the class */
unsigned ref_count; /* Number of oustanding ID's open on this class object */
unsigned internal; /* Whether this class is internal to the library or not */
unsigned deleted; /* Whether this class has been deleted and is waiting for dependent classes & proplists to close */
+ unsigned revision; /* Revision number of a particular class (global) */
+ H5TB_TREE *props; /* TBBT containing properties */
/* Callback function pointers & info */
H5P_cls_create_func_t create_func; /* Function to call when a property list is created */
@@ -76,8 +83,6 @@ struct H5P_genclass_t {
void *copy_data; /* Pointer to user data to pass along to copy callback */
H5P_cls_close_func_t close_func; /* Function to call when a property list is closed */
void *close_data; /* Pointer to user data to pass along to close callback */
-
- H5P_genprop_t *props[1]; /* Hash table of pointers to properties in the class */
};
/* Define structure to hold property list information */
@@ -86,14 +91,14 @@ struct H5P_genplist_t {
hid_t plist_id; /* Copy of the property list ID (for use in close callback) */
size_t nprops; /* Number of properties in class */
unsigned class_init:1; /* Whether the class initialization callback finished successfully */
-
- /* Hash size for a property list is same as class */
- H5P_genprop_t *props[1]; /* Hash table of pointers to properties in the list */
+ H5TB_TREE *del; /* TBBT containing names of deleted properties */
+ H5TB_TREE *props; /* TBBT containing properties */
};
/* Private functions, not part of the publicly documented API */
-H5_DLL herr_t H5P_add_prop(H5P_genprop_t *hash[], unsigned hashsize, H5P_genprop_t *prop);
+H5_DLL herr_t H5P_add_prop(H5TB_TREE *props, H5P_genprop_t *prop);
H5_DLL herr_t H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod);
+H5_DLL int H5P_tbbt_strcmp(const void *k1, const void *k2, int UNUSED cmparg);
#endif /* _H5Ppkg_H */
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index dca48be..d854936 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -25,6 +25,9 @@
typedef struct H5P_genplist_t H5P_genplist_t;
typedef struct H5P_genclass_t H5P_genclass_t;
+/* Forward declarations for prototypes arguments */
+struct H5O_fill_t;
+
/* Private functions, not part of the publicly documented API */
H5_DLL herr_t H5P_init(void);
@@ -60,6 +63,8 @@ H5_DLL herr_t H5P_get_multi_type(H5P_genplist_t *plist, H5FD_mem_t *type);
H5_DLL herr_t H5P_set_vlen_mem_manager(H5P_genplist_t *plist,
H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func,
void *free_info);
+H5_DLL herr_t H5P_is_fill_value_defined(const struct H5O_fill_t *fill,
+ H5D_fill_value_t *status);
H5_DLL herr_t H5P_fill_value_defined(H5P_genplist_t *plist,
H5D_fill_value_t *status);
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 615967c..3ac1029 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -57,12 +57,14 @@ typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id,
typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data);
/* Define property list callback function pointer types */
-typedef herr_t (*H5P_prp_create_func_t)(const char *name, size_t size, void *def_value);
-typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, size_t size, void *value);
-typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, size_t size, void *value);
-typedef herr_t (*H5P_prp_delete_func_t)(hid_t prop_id, const char *name, size_t size, void *value);
-typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, void *value);
-typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, void *value);
+typedef herr_t (*H5P_prp_cb1_t)(const char *name, size_t size, void *value);
+typedef herr_t (*H5P_prp_cb2_t)(hid_t prop_id, const char *name, size_t size, void *value);
+typedef H5P_prp_cb1_t H5P_prp_create_func_t;
+typedef H5P_prp_cb2_t H5P_prp_set_func_t;
+typedef H5P_prp_cb2_t H5P_prp_get_func_t;
+typedef H5P_prp_cb2_t H5P_prp_delete_func_t;
+typedef H5P_prp_cb1_t H5P_prp_copy_func_t;
+typedef H5P_prp_cb1_t H5P_prp_close_func_t;
/* Define property list iteration function type */
typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
@@ -73,19 +75,25 @@ extern "C" {
/*
* The library created property list classes
+ *
+ * NOTE: When adding H5P_* macros, remember to redefine them in H5Pprivate.h
+ *
*/
-#define H5P_NO_CLASS (H5open(), H5P_CLS_NO_CLASS_g)
-#define H5P_NO_CLASS_HASH_SIZE 1 /* 1, not 0, otherwise allocations get weird */
-#define H5P_FILE_CREATE (H5open(), H5P_CLS_FILE_CREATE_g)
-#define H5P_FILE_CREATE_HASH_SIZE 17
-#define H5P_FILE_ACCESS (H5open(), H5P_CLS_FILE_ACCESS_g)
-#define H5P_FILE_ACCESS_HASH_SIZE 17
-#define H5P_DATASET_CREATE (H5open(), H5P_CLS_DATASET_CREATE_g)
-#define H5P_DATASET_CREATE_HASH_SIZE 17
-#define H5P_DATASET_XFER (H5open(), H5P_CLS_DATASET_XFER_g)
-#define H5P_DATASET_XFER_HASH_SIZE 17
-#define H5P_MOUNT (H5open(), H5P_CLS_MOUNT_g)
-#define H5P_MOUNT_HASH_SIZE 17
+
+/* When this header is included from H5Pprivate.h, don't make calls to H5open() */
+#undef H5OPEN
+#ifndef _H5Pprivate_H
+#define H5OPEN H5open(),
+#else /* _H5Pprivate_H */
+#define H5OPEN
+#endif /* _H5Pprivate_H */
+
+#define H5P_NO_CLASS (H5OPEN H5P_CLS_NO_CLASS_g)
+#define H5P_FILE_CREATE (H5OPEN H5P_CLS_FILE_CREATE_g)
+#define H5P_FILE_ACCESS (H5OPEN H5P_CLS_FILE_ACCESS_g)
+#define H5P_DATASET_CREATE (H5OPEN H5P_CLS_DATASET_CREATE_g)
+#define H5P_DATASET_XFER (H5OPEN H5P_CLS_DATASET_XFER_g)
+#define H5P_MOUNT (H5OPEN H5P_CLS_MOUNT_g)
H5_DLLVAR hid_t H5P_CLS_NO_CLASS_g;
H5_DLLVAR hid_t H5P_CLS_FILE_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_FILE_ACCESS_g;
@@ -95,13 +103,16 @@ H5_DLLVAR hid_t H5P_CLS_MOUNT_g;
/*
* The library created default property lists
+ *
+ * NOTE: When adding H5P_* macros, remember to redefine them in H5Pprivate.h
+ *
*/
-#define H5P_NO_CLASS_DEFAULT (H5open(), H5P_LST_NO_CLASS_g)
-#define H5P_FILE_CREATE_DEFAULT (H5open(), H5P_LST_FILE_CREATE_g)
-#define H5P_FILE_ACCESS_DEFAULT (H5open(), H5P_LST_FILE_ACCESS_g)
-#define H5P_DATASET_CREATE_DEFAULT (H5open(), H5P_LST_DATASET_CREATE_g)
-#define H5P_DATASET_XFER_DEFAULT (H5open(), H5P_LST_DATASET_XFER_g)
-#define H5P_MOUNT_DEFAULT (H5open(), H5P_LST_MOUNT_g)
+#define H5P_NO_CLASS_DEFAULT (H5OPEN H5P_LST_NO_CLASS_g)
+#define H5P_FILE_CREATE_DEFAULT (H5OPEN H5P_LST_FILE_CREATE_g)
+#define H5P_FILE_ACCESS_DEFAULT (H5OPEN H5P_LST_FILE_ACCESS_g)
+#define H5P_DATASET_CREATE_DEFAULT (H5OPEN H5P_LST_DATASET_CREATE_g)
+#define H5P_DATASET_XFER_DEFAULT (H5OPEN H5P_LST_DATASET_XFER_g)
+#define H5P_MOUNT_DEFAULT (H5OPEN H5P_LST_MOUNT_g)
H5_DLLVAR hid_t H5P_LST_NO_CLASS_g;
H5_DLLVAR hid_t H5P_LST_FILE_CREATE_g;
H5_DLLVAR hid_t H5P_LST_FILE_ACCESS_g;
@@ -109,11 +120,8 @@ H5_DLLVAR hid_t H5P_LST_DATASET_CREATE_g;
H5_DLLVAR hid_t H5P_LST_DATASET_XFER_g;
H5_DLLVAR hid_t H5P_LST_MOUNT_g;
-/* Default hash table size */
-#define H5P_DEFAULT_HASH_SIZE 17
-
/* Public functions */
-H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize,
+H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name,
H5P_cls_create_func_t cls_create, void *create_data,
H5P_cls_copy_func_t cls_copy, void *copy_data,
H5P_cls_close_func_t cls_close, void *close_data);
diff --git a/src/H5R.c b/src/H5R.c
index 795bc56..1ffa827 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -331,7 +331,6 @@ done:
static hid_t
H5R_dereference(H5F_t *file, H5R_type_t ref_type, void *_ref)
{
- H5D_t *dataset; /* Pointer to dataset to open */
H5G_t *group; /* Pointer to group to open */
H5T_t *datatype; /* Pointer to datatype to open */
H5G_entry_t ent; /* Symbol table entry */
@@ -428,14 +427,9 @@ H5R_dereference(H5F_t *file, H5R_type_t ref_type, void *_ref)
break;
case H5G_DATASET:
- if ((dataset=H5D_open_oid(&ent)) == NULL)
+ /* Open the dataset */
+ if ((ret_value=H5D_open(&ent)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
-
- /* Create an atom for the dataset */
- if ((ret_value = H5I_register(H5I_DATASET, dataset)) < 0) {
- H5D_close(dataset);
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset");
- }
break;
default:
@@ -524,7 +518,6 @@ done:
static H5S_t *
H5R_get_region(H5F_t *file, H5R_type_t UNUSED ref_type, void *_ref)
{
- H5D_t *dataset; /* Pointer to dataset to open */
H5G_entry_t ent; /* Symbol table entry */
uint8_t *p; /* Pointer to OID to store */
hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
@@ -556,12 +549,8 @@ H5R_get_region(H5F_t *file, H5R_type_t UNUSED ref_type, void *_ref)
p=(uint8_t *)buf;
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
- /* Open the dataset object */
- if ((dataset=H5D_open_oid(&ent)) == NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found");
-
- /* Copy the dataspace object */
- if ((ret_value=H5D_get_space(dataset)) == NULL)
+ /* Open and copy the dataset's dataspace */
+ if ((ret_value=H5S_read(&ent)) == NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found");
/* Unserialize the selection */
@@ -571,10 +560,6 @@ H5R_get_region(H5F_t *file, H5R_type_t UNUSED ref_type, void *_ref)
/* Free the buffer allocated in H5HG_read() */
H5MM_xfree(buf);
- /* Close the dataset we opened */
- if (H5D_close(dataset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "not found");
-
done:
FUNC_LEAVE(ret_value);
} /* end H5R_get_region() */
diff --git a/src/H5RS.c b/src/H5RS.c
new file mode 100644
index 0000000..f6f18ac
--- /dev/null
+++ b/src/H5RS.c
@@ -0,0 +1,390 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ * Reference counted string algorithms.
+ *
+ * These are used for various internal strings which get copied multiple times.
+ *
+ */
+
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5RSprivate.h" /* Reference-counted strings */
+
+#define PABLO_MASK H5RS_mask
+
+/* Interface initialization */
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/* Declare a free list to manage the H5RS_str_t struct */
+H5FL_DEFINE_STATIC(H5RS_str_t);
+
+/* Declare the PQ free list for the wrapped strings */
+H5FL_BLK_DEFINE(str_buf);
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_xstrdup
+ PURPOSE
+ Duplicate the string being reference counted
+ USAGE
+ char *H5RS_xstrdup(s)
+ const char *s; IN: String to duplicate
+
+ RETURNS
+ Returns a pointer to a new string on success, NULL on failure.
+ DESCRIPTION
+ Duplicate a string buffer being reference counted. Use this instead of
+ [H5MM_][x]strdup, in order to use the free-list memory routines.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static char *
+H5RS_xstrdup(const char *s)
+{
+ char *ret_value; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5RS_xstrdup);
+
+ if (s) {
+ ret_value = H5FL_BLK_MALLOC(str_buf,HDstrlen(s) + 1);
+ assert (ret_value);
+ HDstrcpy(ret_value, s);
+ } /* end if */
+ else
+ ret_value=NULL;
+
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_xstrdup() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_create
+ PURPOSE
+ Create a reference counted string
+ USAGE
+ H5RS_str_t *H5RS_create(s)
+ const char *s; IN: String to initialize ref-counted string with
+
+ RETURNS
+ Returns a pointer to a new ref-counted string on success, NULL on failure.
+ DESCRIPTION
+ Create a reference counted string. The string passed in is copied into an
+ internal buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5RS_str_t *
+H5RS_create(const char *s)
+{
+ H5RS_str_t *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5RS_create,NULL);
+
+ /* Allocate ref-counted string structure */
+ if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
+ HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+
+ /* Set the internal fields */
+ ret_value->s=H5RS_xstrdup(s);
+ ret_value->wrapped=0;
+ ret_value->n=1;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_create() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_wrap
+ PURPOSE
+ "Wrap" a reference counted string around an existing string
+ USAGE
+ H5RS_str_t *H5RS_wrap(s)
+ const char *s; IN: String to wrap ref-counted string around
+
+ RETURNS
+ Returns a pointer to a new ref-counted string on success, NULL on failure.
+ DESCRIPTION
+ Wrap a reference counted string around an existing string, which is not
+ duplicated, unless its reference count gets incremented.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5RS_str_t *
+H5RS_wrap(char *s)
+{
+ H5RS_str_t *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5RS_wrap,NULL);
+
+ /* Allocate ref-counted string structure */
+ if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
+ HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+
+ /* Set the internal fields */
+ ret_value->s=s;
+ ret_value->wrapped=1;
+ ret_value->n=1;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_wrap() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_own
+ PURPOSE
+ Transfer ownership of a regular string to a reference counted string
+ USAGE
+ H5RS_str_t *H5RS_own(s)
+ const char *s; IN: String to transfer ownership of
+
+ RETURNS
+ Returns a pointer to a new ref-counted string on success, NULL on failure.
+ DESCRIPTION
+ Transfer ownership of a dynamically allocated string to a reference counted
+ string. The routine which passed in the string should not attempt to free
+ it, the reference counting string routines will do that when the reference
+ count drops to zero.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5RS_str_t *
+H5RS_own(char *s)
+{
+ H5RS_str_t *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5RS_own,NULL);
+
+ /* Allocate ref-counted string structure */
+ if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
+ HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+
+ /* Set the internal fields */
+ ret_value->s=s;
+ ret_value->wrapped=0;
+ ret_value->n=1;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_own() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_decr
+ PURPOSE
+ Decrement the reference count for a ref-counted string
+ USAGE
+ herr_t H5RS_decr(rs)
+ H5RS_str_t *rs; IN/OUT: Ref-counted string to decrement count of
+
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Decrement the reference count for a reference counted string. If the
+ reference count drops to zero, the reference counted string is deleted.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5RS_decr(H5RS_str_t *rs)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5RS_decr,FAIL);
+
+ /* Sanity check */
+ assert(rs);
+ assert(rs->n > 0);
+
+ /* Decrement reference count for string */
+ if((--rs->n)==0) {
+ if(!rs->wrapped)
+ H5FL_BLK_FREE(str_buf,rs->s);
+ H5FL_FREE(H5RS_str_t,rs);
+ } /* end if */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_decr() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_incr
+ PURPOSE
+ Increment the reference count for a ref-counted string
+ USAGE
+ herr_t H5RS_incr(rs)
+ H5RS_str_t *rs; IN/OUT: Ref-counted string to increment count of
+
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Increment the reference count for a reference counted string.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5RS_incr(H5RS_str_t *rs)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5RS_incr,FAIL);
+
+ /* Sanity check */
+ assert(rs);
+ assert(rs->n > 0);
+
+ /* If the ref-counted string started life as a wrapper around an existing
+ * string, duplicate the string now, so that the wrapped string can go out
+ * scope appropriately.
+ */
+ if(rs->wrapped) {
+ rs->s=H5RS_xstrdup(rs->s);
+ rs->wrapped=0;
+ } /* end if */
+
+ /* Increment reference count for string */
+ rs->n++;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_incr() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_dup
+ PURPOSE
+ "Duplicate" a ref-counted string
+ USAGE
+ H5RS_str_t H5RS_incr(rs)
+ H5RS_str_t *rs; IN/OUT: Ref-counted string to "duplicate"
+
+ RETURNS
+ Returns a pointer to ref-counted string on success, NULL on failure.
+ DESCRIPTION
+ Increment the reference count for the reference counted string and return
+ a pointer to it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5RS_str_t *
+H5RS_dup(H5RS_str_t *ret_value)
+{
+ FUNC_ENTER_NOAPI(H5RS_dup,NULL);
+
+ /* Check for valid reference counted string */
+ if(ret_value!=NULL)
+ /* Increment reference count for string */
+ ret_value->n++;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_dup() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_cmp
+ PURPOSE
+ Compare two ref-counted strings
+ USAGE
+ int H5RS_cmp(rs1,rs2)
+ const H5RS_str_t *rs1; IN: First Ref-counted string to compare
+ const H5RS_str_t *rs2; IN: Second Ref-counted string to compare
+
+ RETURNS
+ Returns positive, negative or 0 for comparison of two r-strings [same as
+ strcmp()]
+ DESCRIPTION
+ Compare two ref-counted strings and return a value indicating their sort
+ order [same as strcmp()]
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2)
+{
+ /* Can't return invalid value from this function */
+ FUNC_ENTER_NOINIT(H5RS_cmp);
+
+ /* Sanity check */
+ assert(rs1);
+ assert(rs1->s);
+ assert(rs2);
+ assert(rs2->s);
+
+ FUNC_LEAVE(HDstrcmp(rs1->s,rs2->s));
+} /* end H5RS_cmp() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS_len
+ PURPOSE
+ Compute the length of a ref-counted string
+ USAGE
+ ssize_t H5RS_cmp(rs)
+ const H5RS_str_t *rs; IN: Ref-counted string to compute length of
+
+ RETURNS
+ Returns non-negative value on success, negative value on failure
+ DESCRIPTION
+ Compute the length of a ref-counted string. [same as strlen()]
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+ssize_t
+H5RS_len(const H5RS_str_t *rs)
+{
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5RS_len,FAIL);
+
+ /* Sanity check */
+ assert(rs);
+ assert(rs->s);
+
+ ret_value=HDstrlen(rs->s);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5RS_len() */
+
diff --git a/src/H5RSprivate.h b/src/H5RSprivate.h
new file mode 100644
index 0000000..086396f
--- /dev/null
+++ b/src/H5RSprivate.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ * This file contains private information about the H5RS module
+ */
+#ifndef _H5RSprivate_H
+#define _H5RSprivate_H
+
+#ifdef LATER
+#include "H5RSpublic.h"
+#endif /* LATER */
+
+/* Private headers needed by this file */
+#include "H5private.h"
+
+/* Typedefs */
+
+/* Typedef for reference counted string */
+typedef struct {
+ char *s; /* String to be reference counted */
+ unsigned wrapped; /* Indicates that the string to be ref-counted is not copied */
+ unsigned n; /* Reference count of number of pointers sharing string */
+} H5RS_str_t;
+
+/* Macros */
+
+/* Get the pointer to the actual string */
+#define H5RS_GET_STR(rs) ((rs)->s)
+#define H5RS_GET_COUNT(rs) ((rs)->n)
+
+/* Private routines */
+H5_DLL H5RS_str_t *H5RS_create(const char *s);
+H5_DLL H5RS_str_t *H5RS_wrap(char *s);
+H5_DLL H5RS_str_t *H5RS_own(char *s);
+H5_DLL herr_t H5RS_decr(H5RS_str_t *rs);
+H5_DLL herr_t H5RS_incr(H5RS_str_t *rs);
+H5_DLL H5RS_str_t *H5RS_dup(H5RS_str_t *s);
+H5_DLL int H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2);
+H5_DLL ssize_t H5RS_len(const H5RS_str_t *rs);
+
+#endif /* _H5STprivate_H */
+
diff --git a/src/H5S.c b/src/H5S.c
index 6424ada..0127056 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -303,8 +303,21 @@ H5S_create(H5S_class_t type)
FUNC_ENTER_NOAPI(H5S_create, NULL);
/* Create a new data space */
- if((ret_value = H5FL_ALLOC(H5S_t,1))!=NULL) {
+ if((ret_value = H5FL_CALLOC(H5S_t))!=NULL) {
ret_value->extent.type = type;
+
+ switch(type) {
+ case H5S_SCALAR:
+ ret_value->extent.nelem = 1;
+ break;
+ case H5S_SIMPLE:
+ ret_value->extent.nelem = 0;
+ break;
+ default:
+ assert("unknown dataspace (extent) type" && 0);
+ break;
+ } /* end switch */
+
if(H5S_select_all(ret_value,0)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection");
} /* end if */
@@ -647,12 +660,12 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src)
case H5S_SIMPLE:
if (src->u.simple.size) {
- dst->u.simple.size = H5FL_ARR_ALLOC(hsize_t,src->u.simple.rank,0);
+ dst->u.simple.size = H5FL_ARR_MALLOC(hsize_t,src->u.simple.rank);
for (u = 0; u < src->u.simple.rank; u++)
dst->u.simple.size[u] = src->u.simple.size[u];
}
if (src->u.simple.max) {
- dst->u.simple.max = H5FL_ARR_ALLOC(hsize_t,src->u.simple.rank,0);
+ dst->u.simple.max = H5FL_ARR_MALLOC(hsize_t,src->u.simple.rank);
for (u = 0; u < src->u.simple.rank; u++)
dst->u.simple.max[u] = src->u.simple.max[u];
}
@@ -697,7 +710,7 @@ H5S_copy(const H5S_t *src)
FUNC_ENTER_NOAPI(H5S_copy, NULL);
- if (NULL==(dst = H5FL_ALLOC(H5S_t,0)))
+ if (NULL==(dst = H5FL_MALLOC(H5S_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Copy the field in the struct */
@@ -740,30 +753,14 @@ hssize_t
H5S_get_simple_extent_npoints(const H5S_t *ds)
{
hssize_t ret_value;
- unsigned u;
FUNC_ENTER_NOAPI(H5S_get_simple_extent_npoints, -1);
/* check args */
assert(ds);
- switch (ds->extent.type) {
- case H5S_SCALAR:
- ret_value = 1;
- break;
-
- case H5S_SIMPLE:
- for (ret_value=1, u=0; u<ds->extent.u.simple.rank; u++)
- ret_value *= ds->extent.u.simple.size[u];
- break;
-
- case H5S_COMPLEX:
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "complex data spaces are not supported yet");
-
- default:
- assert("unknown data space class" && 0);
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown data space class)");
- }
+ /* Get the number of elements in extent */
+ ret_value = ds->extent.nelem;
done:
FUNC_LEAVE(ret_value);
@@ -1078,7 +1075,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5S_modify(H5G_entry_t *ent, const H5S_t *ds)
+H5S_modify(H5G_entry_t *ent, const H5S_t *ds, hbool_t update_time)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -1090,7 +1087,7 @@ H5S_modify(H5G_entry_t *ent, const H5S_t *ds)
switch (ds->extent.type) {
case H5S_SCALAR:
case H5S_SIMPLE:
- if (H5O_modify(ent, H5O_SDSPACE, 0, 0, &(ds->extent.u.simple))<0)
+ if (H5O_modify(ent, H5O_SDSPACE, 0, 0, update_time, &(ds->extent.u.simple))<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message");
break;
@@ -1108,6 +1105,52 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5S_append
+ *
+ * Purpose: Updates a data space by adding a message to an object
+ * header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 31, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_append(H5F_t *f, H5O_t *oh, const H5S_t *ds)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_append, FAIL);
+
+ assert(f);
+ assert(oh);
+ assert(ds);
+
+ switch (ds->extent.type) {
+ case H5S_SCALAR:
+ case H5S_SIMPLE:
+ if (H5O_append(f, oh, H5O_SDSPACE, 0, &(ds->extent.u.simple))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message");
+ break;
+
+ case H5S_COMPLEX:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "complex data spaces are not implemented yet");
+
+ default:
+ assert("unknown data space class" && 0);
+ break;
+ }
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5S_append() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_read
*
* Purpose: Reads the data space from an object header.
@@ -1136,23 +1179,34 @@ H5S_read(H5G_entry_t *ent)
/* check args */
assert(ent);
- if (NULL==(ds = H5FL_ALLOC(H5S_t,1)))
+ if (NULL==(ds = H5FL_CALLOC(H5S_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
if (H5O_read(ent, H5O_SDSPACE, 0, &(ds->extent.u.simple)) == NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to load dataspace info from dataset header");
- if(ds->extent.u.simple.rank != 0)
- ds->extent.type = H5S_SIMPLE;
- else
- ds->extent.type = H5S_SCALAR;
+ if(ds->extent.u.simple.rank != 0) {
+ hsize_t nelem; /* Number of elements in extent */
+ unsigned u; /* Local index variable */
+
+ ds->extent.type = H5S_SIMPLE;
+
+ /* Compute the number of elements in the extent */
+ for(u=0, nelem=1; u<ds->extent.u.simple.rank; u++)
+ nelem*=ds->extent.u.simple.size[u];
+ ds->extent.nelem = nelem;
+ } /* end if */
+ else {
+ ds->extent.type = H5S_SCALAR;
+ ds->extent.nelem = 1;
+ } /* end else */
/* Default to entire dataspace being selected */
if(H5S_select_all(ds,0)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection");
/* Allocate space for the offset and set it to zeros */
- if (NULL==(ds->select.offset = H5FL_ARR_ALLOC(hssize_t,ds->extent.u.simple.rank,1)))
+ if (NULL==(ds->select.offset = H5FL_ARR_CALLOC(hssize_t,ds->extent.u.simple.rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Set the value for successful return */
@@ -1407,7 +1461,7 @@ H5S_set_extent_simple (H5S_t *space, unsigned rank, const hsize_t *dims,
space->select.offset=H5FL_ARR_FREE(hssize_t,space->select.offset);
/* Allocate space for the offset and set it to zeros */
- if (NULL==(space->select.offset = H5FL_ARR_ALLOC(hssize_t,rank,1)))
+ if (NULL==(space->select.offset = H5FL_ARR_CALLOC(hssize_t,rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* shift out of the previous state to a "simple" dataspace */
@@ -1433,18 +1487,27 @@ H5S_set_extent_simple (H5S_t *space, unsigned rank, const hsize_t *dims,
if (rank == 0) { /* scalar variable */
space->extent.type = H5S_SCALAR;
+ space->extent.nelem = 1;
space->extent.u.simple.rank = 0; /* set to scalar rank */
} else {
+ hsize_t nelem; /* Number of elements in extent */
+ unsigned u; /* Local index variable */
+
space->extent.type = H5S_SIMPLE;
/* Set the rank and copy the dims */
space->extent.u.simple.rank = rank;
- space->extent.u.simple.size = H5FL_ARR_ALLOC(hsize_t,rank,0);
+ space->extent.u.simple.size = H5FL_ARR_MALLOC(hsize_t,rank);
HDmemcpy(space->extent.u.simple.size, dims, sizeof(hsize_t) * rank);
+ /* Compute the number of elements in the extent */
+ for(u=0, nelem=1; u<space->extent.u.simple.rank; u++)
+ nelem*=space->extent.u.simple.size[u];
+ space->extent.nelem = nelem;
+
/* Copy the maximum dimensions if specified */
if(max!=NULL) {
- space->extent.u.simple.max = H5FL_ARR_ALLOC(hsize_t,rank,0);
+ space->extent.u.simple.max = H5FL_ARR_MALLOC(hsize_t,rank);
HDmemcpy(space->extent.u.simple.max, max, sizeof(hsize_t) * rank);
} /* end if */
}
@@ -1629,6 +1692,7 @@ H5S_extend (H5S_t *space, const hsize_t *size)
assert (space && H5S_SIMPLE==space->extent.type);
assert (size);
+ /* Check through all the dimensions to see if modifying the dataspace is allowed */
for (u=0; u<space->extent.u.simple.rank; u++) {
if (space->extent.u.simple.size[u]<size[u]) {
if (space->extent.u.simple.max &&
@@ -1641,10 +1705,16 @@ H5S_extend (H5S_t *space, const hsize_t *size)
/* Update */
if (ret_value) {
- for (u=0; u<space->extent.u.simple.rank; u++) {
+ hsize_t nelem; /* Number of elements in extent */
+
+ /* Change the dataspace size & re-compute the number of elements in the extent */
+ for (u=0, nelem=1; u<space->extent.u.simple.rank; u++) {
if (space->extent.u.simple.size[u]<size[u])
space->extent.u.simple.size[u] = size[u];
+
+ nelem*=space->extent.u.simple.size[u];
}
+ space->extent.nelem = nelem;
}
done:
@@ -1872,7 +1942,7 @@ H5Soffset_simple(hid_t space_id, const hssize_t *offset)
/* Allocate space for new offset */
if(space->select.offset==NULL) {
- if (NULL==(space->select.offset = H5FL_ARR_ALLOC(hssize_t,space->extent.u.simple.rank,0)))
+ if (NULL==(space->select.offset = H5FL_ARR_MALLOC(hssize_t,space->extent.u.simple.rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
}
@@ -1922,9 +1992,14 @@ H5S_set_extent( H5S_t *space, const hsize_t *size )
/* Update */
if (ret_value) {
- /* Update dimensions with new values */
- for ( u = 0; u < space->extent.u.simple.rank; u++ )
+ hsize_t nelem; /* Number of elements in extent */
+
+ /* Change the dataspace size & re-compute the number of elements in the extent */
+ for (u=0, nelem=1; u < space->extent.u.simple.rank; u++ ) {
space->extent.u.simple.size[u] = size[u];
+ nelem*=space->extent.u.simple.size[u];
+ } /* end for */
+ space->extent.nelem = nelem;
} /* end if */
done:
diff --git a/src/H5ST.c b/src/H5ST.c
new file mode 100644
index 0000000..35b6ab8
--- /dev/null
+++ b/src/H5ST.c
@@ -0,0 +1,795 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/* TERNARY SEARCH TREE ALGS
+ This code is described in "Ternary Search Trees" by Jon
+Bentley and Robert Sedgewick in the April, 1998, Dr. Dobb's Journal.
+*/
+
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5STprivate.h" /* Ternary search trees */
+
+#define PABLO_MASK H5ST_mask
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/* Declare a free list to manage the H5ST_node_t struct */
+H5FL_DEFINE_STATIC(H5ST_node_t);
+
+/* Declare a free list to manage the H5ST_tree_t struct */
+H5FL_DEFINE_STATIC(H5ST_tree_t);
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_create
+ PURPOSE
+ Create a TST
+ USAGE
+ H5ST_ptr_t H5ST_create()
+
+ RETURNS
+ Returns a pointer to the new TST tree on success, NULL on failure.
+ DESCRIPTION
+ Create a TST.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5ST_tree_t *
+H5ST_create(void)
+{
+ H5ST_tree_t *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_create,NULL);
+
+ /* Allocate wrapper for TST */
+ if((ret_value=H5FL_MALLOC(H5ST_tree_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed");
+
+ /* Set the internal fields */
+ ret_value->root=NULL;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_create() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_close_internal
+ PURPOSE
+ Close a TST, deallocating it.
+ USAGE
+ herr_t H5ST_close(p)
+ H5ST_ptr_t p; IN/OUT: Root of TST to free
+
+ RETURNS
+ Returns non-negative on success, negative on failure.
+ DESCRIPTION
+ Close a TST, freeing all nodes.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5ST_close_internal(H5ST_ptr_t p)
+{
+ FUNC_ENTER_NOINIT(H5ST_close_internal);
+
+ /* Recursively free TST */
+ if(p) {
+ H5ST_close_internal(p->lokid);
+ if (p->splitchar)
+ H5ST_close_internal(p->eqkid);
+ H5ST_close_internal(p->hikid);
+ H5FL_FREE(H5ST_node_t,p);
+ } /* end if */
+
+ FUNC_LEAVE(SUCCEED);
+} /* end H5ST_close_internal() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_close
+ PURPOSE
+ Close a TST, deallocating it.
+ USAGE
+ herr_t H5ST_close(tree)
+ H5ST_tree_t *tree; IN/OUT: TST tree to free
+
+ RETURNS
+ Returns non-negative on success, negative on failure.
+ DESCRIPTION
+ Close a TST, freeing all nodes.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5ST_close(H5ST_tree_t *tree)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_close,FAIL);
+
+ /* Check arguments */
+ if(tree==NULL)
+ HGOTO_ERROR(H5E_ARGS,H5E_BADVALUE,FAIL,"invalid TST");
+
+ /* Free the TST itself */
+ if(H5ST_close_internal(tree->root)<0)
+ HGOTO_ERROR(H5E_TST,H5E_CANTFREE,FAIL,"can't free TST");
+
+ /* Free root node itself */
+ H5FL_FREE(H5ST_tree_t,tree);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_close() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_insert
+ PURPOSE
+ Insert a string/object pair into a TST
+ USAGE
+ herr_t H5ST_insert(tree,s,obj)
+ H5ST_tree_t *tree; IN/OUT: TST to insert string into
+ const char *s; IN: String to use as key for object
+ void *obj; IN: Pointer to object to insert
+
+ RETURNS
+ Returns non-negative on success, negative on failure.
+ DESCRIPTION
+ Insert a key (string)/object pair into a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
+{
+ int d; /* Comparison value */
+ H5ST_ptr_t pp, *p; /* Pointer to current node and pointer to that */
+ H5ST_ptr_t parent=NULL; /* Pointer to parent node */
+ H5ST_ptr_t up=NULL; /* Pointer to up node */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_insert,FAIL);
+
+ /* Find the correct location to insert object */
+ p = &tree->root;
+ while((pp = *p)) {
+ /* If this node matches the character in the key, then drop down to the lower tree */
+ if ((d = *s - pp->splitchar) == 0) {
+ if (*s++ == 0)
+ HGOTO_ERROR(H5E_TST,H5E_EXISTS,FAIL,"key already in tree");
+ up=pp;
+ p = &(pp->eqkid);
+ } /* end if */
+ else {
+ /* Walk through the current tree, searching for the matching character */
+ parent=pp;
+ if (d < 0)
+ p = &(pp->lokid);
+ else
+ p = &(pp->hikid);
+ } /* end else */
+ } /* end while */
+
+ /* Finish walking through the key string, adding nodes until the end */
+ for (;;) {
+ if((*p = H5FL_MALLOC(H5ST_node_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
+ pp = *p;
+ pp->splitchar = *s;
+ pp->up = up;
+ pp->parent = parent;
+ pp->lokid = pp->eqkid = pp->hikid = NULL;
+
+ /* If this is the end of the key string, break out */
+ if (*s++ == 0) {
+ pp->eqkid = (H5ST_ptr_t) obj;
+ break;
+ } /* end if */
+
+ /* Continue to next character */
+ parent=NULL;
+ up=pp;
+ p = &(pp->eqkid);
+ } /* end for */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_insert() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_search
+ PURPOSE
+ Determine if a key is in the TST
+ USAGE
+ hbool_t H5ST_search(tree,s)
+ H5ST_tree_t *tree; IN: TST to find string in
+ const char *s; IN: String to use as key to locate
+
+ RETURNS
+ Success: TRUE if key string in TST, FALSE if not
+ Failure: negative
+ DESCRIPTION
+ Locate a key (string) in a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5ST_search(H5ST_tree_t *tree, const char *s)
+{
+ H5ST_ptr_t p; /* Temporary pointer to TST node */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_search,FAIL);
+
+ p = tree->root;
+ while (p) {
+ if (*s < p->splitchar)
+ p = p->lokid;
+ else if (*s == p->splitchar) {
+ if (*s++ == 0)
+ HGOTO_DONE(TRUE);
+ p = p->eqkid;
+ } else
+ p = p->hikid;
+ } /* end while */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_search() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_find_internal
+ PURPOSE
+ Find the node matching a particular key string
+ USAGE
+ H5ST_ptr_t H5ST_find(p,s)
+ H5ST_ptr_t p; IN: TST to find string in
+ const char *s; IN: String to use as key to locate
+
+ RETURNS
+ Success: Non-NULL
+ Failure: NULL
+ DESCRIPTION
+ Locate a key (string) in a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static H5ST_ptr_t
+H5ST_find_internal(H5ST_ptr_t p, const char *s)
+{
+ H5ST_ptr_t ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5ST_find_internal);
+
+ while (p) {
+ if (*s < p->splitchar)
+ p = p->lokid;
+ else if (*s == p->splitchar) {
+ if (*s++ == 0)
+ HGOTO_DONE(p);
+ p = p->eqkid;
+ } else
+ p = p->hikid;
+ } /* end while */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_find_internal() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_find
+ PURPOSE
+ Find the node matching a particular key string
+ USAGE
+ H5ST_ptr_t H5ST_find(tree,s)
+ H5ST_tree_t *tree; IN: TST to find string in
+ const char *s; IN: String to use as key to locate
+
+ RETURNS
+ Success: Non-NULL
+ Failure: NULL
+ DESCRIPTION
+ Locate a key (string) in a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5ST_ptr_t
+H5ST_find(H5ST_tree_t *tree, const char *s)
+{
+ H5ST_ptr_t ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_find,NULL);
+
+ if((ret_value=H5ST_find_internal(tree->root,s))==NULL)
+ HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_find() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_locate
+ PURPOSE
+ Find an object in a TST
+ USAGE
+ void *H5ST_locate(tree,s)
+ H5ST_tree_t *tree; IN: TST to locate object within
+ const char *s; IN: String of key for object to locate
+ RETURNS
+ Success: Non-NULL, pointer to object stored for key
+ Failure: Negative
+ DESCRIPTION
+ Locate a node in a TST, returning the object from the node.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+void *
+H5ST_locate(H5ST_tree_t *tree, const char *s)
+{
+ H5ST_ptr_t node; /* Pointer to node located */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_locate,NULL);
+
+ /* Locate the node to remove */
+ if((node=H5ST_find_internal(tree->root,s))==NULL)
+ HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+
+ /* Get the pointer to the object to return */
+ ret_value=node->eqkid;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* H5ST_locate() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_findfirst_internal
+ PURPOSE
+ Find the first node in a TST
+ USAGE
+ H5ST_ptr_t H5ST_findfirst_internal(p)
+ H5ST_ptr_t p; IN: TST to locate first node within
+ RETURNS
+ Success: Non-NULL
+ Failure: NULL
+ DESCRIPTION
+ Get the first (lexicographically) node in a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static H5ST_ptr_t
+H5ST_findfirst_internal(H5ST_ptr_t p)
+{
+ H5ST_ptr_t ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5ST_findfirst_internal);
+
+ while(p) {
+ /* Find least node in current tree */
+ while(p->lokid)
+ p=p->lokid;
+
+ /* Is least node '\0'? */
+ if(p->splitchar=='\0') {
+ /* Return it */
+ HGOTO_DONE(p);
+ } /* end if */
+ else {
+ /* Go down to next level of tree */
+ p=p->eqkid;
+ } /* end else */
+ } /* end while */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_findfirst_internal() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_findfirst
+ PURPOSE
+ Find the first node in a TST
+ USAGE
+ H5ST_ptr_t H5ST_findfirst(tree)
+ H5ST_tree_t *tree; IN: TST to locate first node within
+ RETURNS
+ Success: Non-NULL
+ Failure: NULL
+ DESCRIPTION
+ Get the first (lexicographically) node in a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5ST_ptr_t
+H5ST_findfirst(H5ST_tree_t *tree)
+{
+ H5ST_ptr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_findfirst,NULL);
+
+ if((ret_value=H5ST_findfirst_internal(tree->root))==NULL)
+ HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"no nodes in TST");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_findfirst() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_getnext
+ PURPOSE
+ Internal routine to find the next node in a given level of a TST
+ USAGE
+ H5ST_ptr_t H5ST_getnext(p)
+ H5ST_ptr_t *p; IN: Pointer to node to find next node from
+ RETURNS
+ Success: Non-NULL
+ Failure: NULL
+ DESCRIPTION
+ Get the next (lexicographically) node in the current level of a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static H5ST_ptr_t
+H5ST_getnext(H5ST_ptr_t p)
+{
+ H5ST_ptr_t ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5ST_getnext);
+
+ /* If the node to continue from has higher-valued nodes attached */
+ if(p->hikid) {
+ /* Go to first higher-valued node */
+ p=p->hikid;
+
+ /* Find least node from here */
+ while(p->lokid)
+ p=p->lokid;
+ HGOTO_DONE(p);
+ } /* end if */
+ else {
+ H5ST_ptr_t q; /* Temporary TST node pointer */
+
+ /* Go up one level in current tree */
+ q=p->parent;
+ if(q==NULL)
+ HGOTO_DONE(NULL);
+
+ /* While the previous node was the higher-valued node, keep backing up the tree */
+ while(q->hikid==p) {
+ p=q;
+ q=p->parent;
+ if(q==NULL)
+ HGOTO_DONE(NULL);
+ } /* end while */
+ HGOTO_DONE(q);
+ } /* end else */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_getnext() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_findnext
+ PURPOSE
+ Find the next node from a node in a TST
+ USAGE
+ H5ST_ptr_t H5ST_findnext(p)
+ H5ST_ptr_t p; IN: Current node to continue from
+ RETURNS
+ Success: Non-NULL
+ Failure: NULL
+ DESCRIPTION
+ Get the next (lexicographically) node in a TST
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5ST_ptr_t
+H5ST_findnext(H5ST_ptr_t p)
+{
+ H5ST_ptr_t q; /* Temporary pointer to TST node */
+ H5ST_ptr_t ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_findnext,NULL);
+
+ /* Find the next node at the current level, or go back up the tree */
+ do {
+ q=H5ST_getnext(p);
+ if(q) {
+ HGOTO_DONE(H5ST_findfirst_internal(q->eqkid));
+ } /* end if */
+ else
+ p=p->up;
+ } while(p);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_findnext() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_delete_internal
+ PURPOSE
+ Delete a node from a TST
+ USAGE
+ herr_t H5ST_delete_internal(root,p)
+ H5ST_ptr_t *root; IN/OUT: Root of TST to delete node from
+ H5ST_ptr_t p; IN: Node to delete
+ RETURNS
+ Success: Non-negative
+ Failure: Negative
+ DESCRIPTION
+ Delete a node from a TST.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ This should be the final node for a string.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5ST_delete_internal(H5ST_ptr_t *root, H5ST_ptr_t p)
+{
+ H5ST_ptr_t q, /* Temporary pointer to TST node */
+ newp; /* Pointer to node which will replace deleted node in tree */
+
+ FUNC_ENTER_NOINIT(H5ST_delete_internal);
+
+ /* Find node to replace one being deleted */
+ if(p->lokid) {
+ /* If the deleted node has lo & hi kids, attach them together */
+ if(p->hikid) {
+ q=p->lokid;
+ while(q->hikid)
+ q=q->hikid;
+ q->hikid=p->hikid;
+ p->hikid->parent=q;
+ } /* end if */
+ newp=p->lokid;
+ } /* end if */
+ else if(p->hikid) {
+ newp=p->hikid;
+ } /* end if */
+ else {
+ newp=NULL;
+ } /* end else */
+
+ /* Deleted node is in middle of tree */
+ if(p->parent) {
+ /* Attach new node to correct side of parent */
+ if(p==p->parent->lokid)
+ p->parent->lokid=newp;
+ else
+ p->parent->hikid=newp;
+ if(newp)
+ newp->parent=p->parent;
+ } /* end if */
+ else {
+ if(newp)
+ newp->parent=p->parent;
+ if(p->up) {
+ p->up->eqkid=newp;
+ /* If we deleted the last node in the TST, delete the upper node also */
+ if(newp==NULL)
+ H5ST_delete_internal(root,p->up);
+ } /* end if */
+ else /* Deleted last node at top level of tree */
+ *root=newp;
+ } /* end else */
+
+ H5FL_FREE(H5ST_node_t,p);
+
+ FUNC_LEAVE(SUCCEED);
+} /* end H5ST_delete_internal() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_delete
+ PURPOSE
+ Delete a node from a TST
+ USAGE
+ herr_t H5ST_delete(tree,p)
+ H5ST_tree_t *tree; IN/OUT: TST to delete node from
+ H5ST_ptr_t p; IN: Node to delete
+ RETURNS
+ Success: Non-negative
+ Failure: Negative
+ DESCRIPTION
+ Delete a node from a TST.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ This should be the final node for a string.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5ST_delete(H5ST_tree_t *tree, H5ST_ptr_t p)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_delete,FAIL);
+
+ if(H5ST_delete_internal(&tree->root,p)<0)
+ HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,FAIL,"can't delete node from TST");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_delete() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_remove
+ PURPOSE
+ Remove a node from a TST
+ USAGE
+ void *H5ST_remove(tree,s)
+ H5ST_tree_t *tree; IN/OUT: TST to remove node from
+ const char *s; IN: String of key for node to remove
+ RETURNS
+ Success: Non-NULL, pointer to object stored for key
+ Failure: Negative
+ DESCRIPTION
+ Remove a node from a TST, returning the object from the node.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+void *
+H5ST_remove(H5ST_tree_t *tree, const char *s)
+{
+ H5ST_ptr_t node; /* Pointer to node to remove */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_remove,NULL);
+
+ /* Locate the node to remove */
+ if((node=H5ST_find_internal(tree->root,s))==NULL)
+ HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+
+ /* Get the pointer to the object to return */
+ ret_value=node->eqkid;
+
+ /* Remove the node from the TST */
+ if(H5ST_delete_internal(&tree->root,node)<0)
+ HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,NULL,"can't delete node from TST");
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* H5ST_remove() */
+
+#ifdef H5ST_DEBUG
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_dump_internal
+ PURPOSE
+ Dump all the nodes of a TST
+ USAGE
+ herr_t H5ST_dump(p)
+ H5ST_ptr_t p; IN: Root of TST to dump
+ RETURNS
+ Success: Non-negative
+ Failure: Negative
+ DESCRIPTION
+ Dump information for a TST.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5ST_dump_internal(H5ST_ptr_t p)
+{
+ FUNC_ENTER_NOINIT(H5ST_dump_internal);
+
+ if (p) {
+ printf("p=%p\n",p);
+ printf("\tp->up=%p\n",p->up);
+ printf("\tp->parent=%p\n",p->parent);
+ printf("\tp->lokid=%p\n",p->lokid);
+ printf("\tp->hikid=%p\n",p->hikid);
+ printf("\tp->eqkid=%p\n",p->eqkid);
+ printf("\tp->splitchar=%c\n",p->splitchar);
+
+ H5ST_dump_internal(p->lokid);
+ if (p->splitchar)
+ H5ST_dump_internal(p->eqkid);
+ else
+ printf("%s\n", (char *) p->eqkid);
+ H5ST_dump_internal(p->hikid);
+ } /* end if */
+
+done:
+ FUNC_LEAVE(SUCCEED);
+} /* end H5ST_dump_internal() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ST_dump
+ PURPOSE
+ Dump all the nodes of a TST
+ USAGE
+ herr_t H5ST_dump(tree)
+ H5ST_tree_t *tree; IN: TST to dump
+ RETURNS
+ Success: Non-negative
+ Failure: Negative
+ DESCRIPTION
+ Dump information for a TST.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5ST_dump(H5ST_tree_t *tree)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5ST_dump,NULL);
+
+ /* Dump the tree */
+ H5ST_dump_internal(tree->root);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5ST_dump() */
+#endif /* H5ST_DEBUG */
diff --git a/src/H5STprivate.h b/src/H5STprivate.h
new file mode 100644
index 0000000..60452a6
--- /dev/null
+++ b/src/H5STprivate.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ * This file contains private information about the H5ST module
+ */
+#ifndef _H5STprivate_H
+#define _H5STprivate_H
+
+#ifdef LATER
+#include "H5STpublic.h"
+#endif /* LATER */
+
+/* Private headers needed by this file */
+#include "H5private.h"
+
+/* Typedefs */
+
+/* Internal nodes for TST */
+typedef struct H5ST_node *H5ST_ptr_t;
+typedef struct H5ST_node {
+ char splitchar; /* Character represented at node */
+ H5ST_ptr_t up; /* Pointer to the node in the tree above (before) this node */
+ H5ST_ptr_t parent; /* Pointer to the next higher tree node in this tree */
+ H5ST_ptr_t lokid; /* Pointer to the lower node from this one, in this tree */
+ H5ST_ptr_t eqkid; /* Pointer to the parent node in the next tree down (after) this node */
+ H5ST_ptr_t hikid; /* Pointer to the higher node from this one, in this tree */
+} H5ST_node_t;
+
+/* Wrapper about TST */
+typedef struct {
+ H5ST_ptr_t root; /* Pointer to actual TST */
+} H5ST_tree_t;
+
+/* Macro to access "data" pointer in H5ST_node_t's returned from functions */
+#define H5ST_NODE_DATA(p) ((void *)(p->eqkid))
+
+/* Private routines */
+H5_DLL H5ST_tree_t *H5ST_create(void);
+H5_DLL herr_t H5ST_close(H5ST_tree_t *p);
+H5_DLL herr_t H5ST_insert(H5ST_tree_t *root, const char *s, void *obj);
+H5_DLL htri_t H5ST_search(H5ST_tree_t *root, const char *s);
+H5_DLL H5ST_ptr_t H5ST_find(H5ST_tree_t *root, const char *s);
+H5_DLL void *H5ST_locate(H5ST_tree_t *root, const char *s);
+H5_DLL H5ST_ptr_t H5ST_findfirst(H5ST_tree_t *p);
+H5_DLL H5ST_ptr_t H5ST_findnext(H5ST_ptr_t p);
+H5_DLL void *H5ST_remove(H5ST_tree_t *root, const char *s);
+H5_DLL herr_t H5ST_delete(H5ST_tree_t *root, H5ST_ptr_t p);
+H5_DLL herr_t H5ST_dump(H5ST_ptr_t p);
+
+#endif /* _H5STprivate_H */
+
diff --git a/src/H5Sall.c b/src/H5Sall.c
index ab12d70..8bab11c 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -175,7 +175,6 @@ done:
hsize_t
H5S_all_npoints (const H5S_t *space)
{
- unsigned u; /* Counters */
hsize_t ret_value;
FUNC_ENTER_NOAPI(H5S_all_npoints, 0);
@@ -183,8 +182,7 @@ H5S_all_npoints (const H5S_t *space)
/* Check args */
assert (space);
- for(u=0, ret_value=1; u<space->extent.u.simple.rank; u++)
- ret_value*=space->extent.u.simple.size[u];
+ ret_value=(hsize_t)H5S_get_simple_extent_npoints(space);
done:
FUNC_LEAVE (ret_value);
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 3eec64e..994238f 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -156,10 +156,14 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
sel_iter->hyp.iter_rank=cont_dim;
/* Allocate the position & initialize to initial location */
- sel_iter->hyp.off = H5FL_ARR_ALLOC(hsize_t,cont_dim,0);
- sel_iter->hyp.diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,cont_dim,0);
- sel_iter->hyp.size = H5FL_ARR_ALLOC(hsize_t,cont_dim,0);
- sel_iter->hyp.sel_off = H5FL_ARR_ALLOC(hssize_t,cont_dim,0);
+ sel_iter->hyp.off = H5FL_ARR_MALLOC(hsize_t,cont_dim);
+ assert(sel_iter->hyp.off);
+ sel_iter->hyp.diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,cont_dim);
+ assert(sel_iter->hyp.diminfo);
+ sel_iter->hyp.size = H5FL_ARR_MALLOC(hsize_t,cont_dim);
+ assert(sel_iter->hyp.size);
+ sel_iter->hyp.sel_off = H5FL_ARR_MALLOC(hssize_t,cont_dim);
+ assert(sel_iter->hyp.sel_off);
/* "Flatten" dataspace extent and selection information */
for(i=space->extent.u.simple.rank-1, acc=1; i>=0; i--) {
@@ -197,10 +201,20 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
} /* end if */
else {
/* Allocate the position & initialize to initial location */
- sel_iter->hyp.off = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0);
+ sel_iter->hyp.off = H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank);
+ assert(sel_iter->hyp.off);
for(u=0; u<space->extent.u.simple.rank; u++)
sel_iter->hyp.off[u]=tdiminfo[u].start;
+
+ /* Initialize other regular region information also (for release) */
+ sel_iter->hyp.diminfo = NULL;
+ sel_iter->hyp.size = NULL;
+ sel_iter->hyp.sel_off = NULL;
} /* end else */
+
+ /* Initialize irregular region information also (for release) */
+ sel_iter->hyp.spans=NULL;
+ sel_iter->hyp.span=NULL;
} /* end if */
else {
/* Initialize the information needed for non-regular hyperslab I/O */
@@ -211,8 +225,10 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
H5S_hyper_span_precompute(sel_iter->hyp.spans,elmt_size);
/* Allocate the span tree pointers, span pointers and positions */
- sel_iter->hyp.span = H5FL_ARR_ALLOC(H5S_hyper_span_t,space->extent.u.simple.rank,0);
- sel_iter->hyp.off = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0);
+ sel_iter->hyp.span = H5FL_ARR_MALLOC(H5S_hyper_span_t,space->extent.u.simple.rank);
+ assert(sel_iter->hyp.span);
+ sel_iter->hyp.off = H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank);
+ assert(sel_iter->hyp.off);
/* Initialize the starting span_info's and spans */
spans=sel_iter->hyp.spans;
@@ -230,6 +246,11 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
/* Get the pointer to the next level down */
spans=spans->head->down;
} /* end for */
+
+ /* Initialize regular region information also (for release) */
+ sel_iter->hyp.diminfo = NULL;
+ sel_iter->hyp.size = NULL;
+ sel_iter->hyp.sel_off = NULL;
} /* end else */
done:
@@ -499,7 +520,7 @@ H5S_hyper_new_span (hssize_t low, hssize_t high, H5S_hyper_span_info_t *down, H5
FUNC_ENTER_NOINIT(H5S_hyper_new_span);
/* Allocate a new span node */
- if((ret_value = H5FL_ALLOC(H5S_hyper_span_t,0))==NULL)
+ if((ret_value = H5FL_MALLOC(H5S_hyper_span_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
/* Copy the span's basic information */
@@ -710,7 +731,7 @@ H5S_hyper_copy_span_helper (H5S_hyper_span_info_t *spans)
} /* end if */
else {
/* Allocate a new span_info node */
- if((ret_value = H5FL_ALLOC(H5S_hyper_span_info_t,0))==NULL)
+ if((ret_value = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
/* Copy the span_info information */
@@ -1033,7 +1054,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
/* Check if there is regular hyperslab information to copy */
if(src->select.sel_info.hslab.diminfo!=NULL) {
/* Create the per-dimension selection info */
- if((new_diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank,0))==NULL)
+ if((new_diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array");
/* Copy the per-dimension selection info */
@@ -1046,7 +1067,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
dst->select.sel_info.hslab.diminfo = new_diminfo;
/* Create the per-dimension selection info */
- if((new_diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank,0))==NULL)
+ if((new_diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array");
/* Copy the per-dimension selection info */
@@ -1676,13 +1697,13 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
UINT32DECODE(buf,num_elem); /* decode the number of points */
/* Allocate space for the coordinates */
- if((start = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
+ if((start = H5FL_ARR_MALLOC(hsize_t,rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
- if((end = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
+ if((end = H5FL_ARR_MALLOC(hsize_t,rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
- if((block = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
+ if((block = H5FL_ARR_MALLOC(hsize_t,rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
- if((count = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
+ if((count = H5FL_ARR_MALLOC(hsize_t,rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
/* Set the count for all blocks */
@@ -2603,7 +2624,7 @@ H5S_hyper_append_span (H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t ** sp
assert(*span_tree==NULL);
/* Allocate a new span_info node */
- if((*span_tree = H5FL_ALLOC(H5S_hyper_span_info_t,0))==NULL)
+ if((*span_tree = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
/* Set the span tree's basic information */
@@ -3631,7 +3652,7 @@ H5S_hyper_make_spans (unsigned rank, const hssize_t *start, const hsize_t *strid
/* Generate all the spans segments for this dimension */
for(u=0; u<count[i]; u++) {
/* Allocate a span node */
- if((span = H5FL_ALLOC(H5S_hyper_span_t,0))==NULL)
+ if((span = H5FL_MALLOC(H5S_hyper_span_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
/* Set the span's basic information */
@@ -3661,7 +3682,7 @@ H5S_hyper_make_spans (unsigned rank, const hssize_t *start, const hsize_t *strid
} /* end for */
/* Allocate a span info node */
- if((down = H5FL_ALLOC(H5S_hyper_span_info_t,0))==NULL)
+ if((down = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
/* Set the reference count */
@@ -3931,7 +3952,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
hssize_t fill=1;
/* Allocate temporary buffer */
- if ((_stride=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
+ if ((_stride=H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for stride buffer");
H5V_array_fill(_stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
stride = _stride;
@@ -3942,7 +3963,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
hssize_t fill=1;
/* Allocate temporary buffer */
- if ((_block=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
+ if ((_block=H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for stride buffer");
H5V_array_fill(_block,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
block = _block;
@@ -4046,7 +4067,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab");
/* Copy all the application per-dimension selection info into the space descriptor */
- if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL)
+ if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
for(u=0; u<space->extent.u.simple.rank; u++) {
diminfo[u].start = start[u];
@@ -4057,7 +4078,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
space->select.sel_info.hslab.app_diminfo = diminfo;
/* Allocate room for the optimized per-dimension selection info */
- if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL)
+ if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
/* Optimize the hyperslab selection to detect contiguously selected block/stride information */
@@ -4479,7 +4500,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
hssize_t fill=1;
/* Allocate temporary buffer */
- if ((_stride=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
+ if ((_stride=H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for stride buffer");
H5V_array_fill(_stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
stride = _stride;
@@ -4490,7 +4511,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
hssize_t fill=1;
/* Allocate temporary buffer */
- if ((_block=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
+ if ((_block=H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for stride buffer");
H5V_array_fill(_block,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
block = _block;
@@ -4595,7 +4616,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab");
/* Copy all the application per-dimension selection info into the space descriptor */
- if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL)
+ if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
for(u=0; u<space->extent.u.simple.rank; u++) {
diminfo[u].start = start[u];
@@ -4606,7 +4627,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
space->select.sel_info.hslab.app_diminfo = diminfo;
/* Allocate room for the optimized per-dimension selection info */
- if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL)
+ if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
/* Optimize the hyperslab selection to detect contiguously selected block/stride information */
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index 9b3f132..1fc2ea9 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -950,9 +950,9 @@ done:
*/
herr_t
H5S_mpio_spaces_read(H5F_t *f, const H5O_layout_t *layout,
- H5P_genplist_t UNUSED *dc_plist, size_t elmt_size,
- const H5S_t *file_space, const H5S_t *mem_space,
- hid_t dxpl_id, void *buf/*out*/)
+ H5P_genplist_t UNUSED *dc_plist, const H5O_efl_t UNUSED *efl, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id,
+ void *buf/*out*/)
{
herr_t ret_value;
@@ -989,9 +989,9 @@ done:
*/
herr_t
H5S_mpio_spaces_write(H5F_t *f, H5O_layout_t *layout,
- H5P_genplist_t UNUSED *dc_plist, size_t elmt_size,
- const H5S_t *file_space, const H5S_t *mem_space,
- hid_t dxpl_id, const void *buf)
+ H5P_genplist_t UNUSED *dc_plist, const H5O_efl_t UNUSED *efl, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id,
+ const void *buf)
{
herr_t ret_value;
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 97b5052..fc74733 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -33,7 +33,8 @@ typedef struct H5S_simple_t {
/* Extent container */
typedef struct {
- H5S_class_t type; /* Type of extent */
+ H5S_class_t type; /* Type of extent */
+ hsize_t nelem; /* Number of elements in extent */
union {
H5S_simple_t simple; /* Simple dimensionality information */
} u;
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 14d30d4..0072c15 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -167,7 +167,7 @@ H5S_point_add (H5S_t *space, H5S_seloper_t op, size_t num_elem, const hssize_t *
top=curr=NULL;
for(i=0; i<num_elem; i++) {
/* Allocate space for the new node */
- if((new_node = H5FL_ALLOC(H5S_pnt_node_t,0))==NULL)
+ if((new_node = H5FL_MALLOC(H5S_pnt_node_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node");
if((new_node->pnt = H5MM_malloc(space->extent.u.simple.rank*sizeof(hssize_t)))==NULL)
@@ -350,7 +350,7 @@ H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
/* Allocate space for the point selection information if necessary */
if(space->select.type!=H5S_SEL_POINTS || space->select.sel_info.pnt_lst==NULL) {
- if((space->select.sel_info.pnt_lst = H5FL_ALLOC(H5S_pnt_list_t,1))==NULL)
+ if((space->select.sel_info.pnt_lst = H5FL_CALLOC(H5S_pnt_list_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate element information");
} /* end if */
@@ -412,14 +412,14 @@ H5S_point_copy (H5S_t *dst, const H5S_t *src)
assert(dst);
/* Allocate room for the head of the point list */
- if((dst->select.sel_info.pnt_lst=H5FL_ALLOC(H5S_pnt_list_t,0))==NULL)
+ if((dst->select.sel_info.pnt_lst=H5FL_MALLOC(H5S_pnt_list_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node");
curr=src->select.sel_info.pnt_lst->head;
new_head=NULL;
while(curr!=NULL) {
/* Create each point */
- if((new_node=H5FL_ALLOC(H5S_pnt_node_t,0))==NULL)
+ if((new_node=H5FL_MALLOC(H5S_pnt_node_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node");
if((new_node->pnt = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information");
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 1daaf04..0c267ac 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -103,16 +103,16 @@ typedef struct H5S_conv_t {
/* Read from file to application w/o intermediate scratch buffer */
herr_t (*read)(H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size,
- const H5S_t *file_space, const H5S_t *mem_space,
- hid_t dxpl_id, void *buf/*out*/);
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space,
+ const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/);
/* Write directly from app buffer to file */
herr_t (*write)(H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size,
- const H5S_t *file_space, const H5S_t *mem_space,
- hid_t dxpl_id, const void *buf);
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space,
+ const H5S_t *mem_space, hid_t dxpl_id, const void *buf);
#ifdef H5S_DEBUG
struct {
@@ -150,7 +150,9 @@ H5_DLL int H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[]/*out*/,
hsize_t max_dims[]/*out*/);
H5_DLL herr_t H5S_set_extent_simple (H5S_t *space, unsigned rank, const hsize_t *dims,
const hsize_t *max);
-H5_DLL herr_t H5S_modify(struct H5G_entry_t *ent, const H5S_t *space);
+H5_DLL herr_t H5S_modify(struct H5G_entry_t *ent, const H5S_t *space,
+ hbool_t update_time);
+H5_DLL herr_t H5S_append(H5F_t *f, H5O_t *oh, const H5S_t *ds);
H5_DLL H5S_t *H5S_read(struct H5G_entry_t *ent);
H5_DLL int H5S_cmp(const H5S_t *ds1, const H5S_t *ds2);
H5_DLL htri_t H5S_is_simple(const H5S_t *sdim);
@@ -169,13 +171,13 @@ H5_DLL herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space,
H5_DLL herr_t H5S_select_fill(void *fill, size_t fill_size,
const H5S_t *space, void *buf);
H5_DLL herr_t H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id,
- const void *_buf);
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts,
+ hid_t dxpl_id, const void *_buf);
H5_DLL hsize_t H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id,
- void *buf);
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts,
+ hid_t dxpl_id, void *buf);
H5_DLL herr_t H5S_select_mscat (const void *_tscat_buf, size_t elmt_size,
const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
hid_t dxpl_id, void *_buf/*out*/);
@@ -183,11 +185,13 @@ H5_DLL hsize_t H5S_select_mgath (const void *_buf, size_t elmt_size,
const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
hid_t dxpl_id, void *_tgath_buf/*out*/);
H5_DLL herr_t H5S_select_read(H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size, const H5S_t *file_space,
- const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/);
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id,
+ void *buf/*out*/);
H5_DLL herr_t H5S_select_write(H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size, const H5S_t *file_space,
- const H5S_t *mem_space, hid_t dxpl_id, const void *buf/*out*/);
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id,
+ const void *buf/*out*/);
/* Needed for internal use of selections in H5Fistore code */
H5_DLL herr_t H5S_select_all(H5S_t *space, unsigned rel_prev);
@@ -200,6 +204,7 @@ H5_DLL herr_t H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hssize
H5_DLL herr_t H5S_mpio_spaces_read(H5F_t *f,
const struct H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
+ const H5O_efl_t *efl,
size_t elmt_size, const H5S_t *file_space,
const H5S_t *mem_space, hid_t dxpl_id,
void *buf/*out*/);
@@ -208,6 +213,7 @@ H5_DLL herr_t H5S_mpio_spaces_read(H5F_t *f,
H5_DLL herr_t H5S_mpio_spaces_write(H5F_t *f,
struct H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
+ const H5O_efl_t *efl,
size_t elmt_size, const H5S_t *file_space,
const H5S_t *mem_space, hid_t dxpl_id,
const void *buf);
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 0fb429e..edc8fa7 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -32,15 +32,56 @@ H5FL_ARR_DEFINE_STATIC(size_t,-1);
/* Declare a free list to manage arrays of hsize_t */
H5FL_ARR_DEFINE_STATIC(hsize_t,-1);
-/* Declare a free list to manage the H5S_sel_iter_t struct */
-H5FL_DEFINE_STATIC(H5S_sel_iter_t);
-
/* Declare a free list to manage blocks of single datatype element data */
H5FL_BLK_EXTERN(type_elem);
/*--------------------------------------------------------------------------
NAME
+ H5S_get_vector_size
+ PURPOSE
+ Gets the size of the I/O vector
+ USAGE
+ ssize_t H5S_get_vector_size(dxpl_id)
+ hid_t dxpl_id; IN: The dataset transfer property list to query
+ RETURNS
+ Non-negative number of entries in I/O vector on success, negative on failure
+ DESCRIPTION
+ Retrieves the number of I/O vector entries to use for a given dataset
+ transfer. If the default dataset property list is used, the default
+ number of I/O vectors is returned.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static ssize_t
+H5S_get_vector_size(hid_t dxpl_id)
+{
+ ssize_t ret_value; /* return value */
+
+ FUNC_ENTER_NOINIT(H5S_get_vector_size);
+
+ if(dxpl_id==H5P_DATASET_XFER_DEFAULT) {
+ ret_value=H5D_XFER_HYPER_VECTOR_SIZE_DEF;
+ } /* end if */
+ else {
+ H5P_genplist_t *dx_plist; /* Dataset transfer property list */
+
+ /* Get the hyperslab vector size */
+ if(NULL == (dx_plist = H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
+ if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&ret_value)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ } /* end else */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_get_vector_size() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_copy
PURPOSE
Copy a selection from one dataspace to another
@@ -75,7 +116,7 @@ H5S_select_copy (H5S_t *dst, const H5S_t *src)
/* Need to copy order information still */
/* Copy offset information */
- if (NULL==(dst->select.offset = H5FL_ARR_ALLOC(hssize_t,src->extent.u.simple.rank,1)))
+ if (NULL==(dst->select.offset = H5FL_ARR_CALLOC(hssize_t,src->extent.u.simple.rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
if(src->select.offset!=NULL)
HDmemcpy(dst->select.offset,src->select.offset,(src->extent.u.simple.rank*sizeof(hssize_t)));
@@ -342,8 +383,8 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
void *operator_data)
{
H5T_t *dt; /* Datatype structure */
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
- H5S_sel_iter_t *iter=NULL; /* Selection iteration info */
+ H5S_sel_iter_t iter; /* Selection iteration info */
+ hbool_t iter_init=0; /* Selection iteration info has been initialized */
uint8_t *loc; /* Current element location in buffer */
hssize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of element in dataspace */
hssize_t nelmts; /* Number of elements in selection */
@@ -353,7 +394,7 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
hsize_t tmp_off; /* Temporary offset within sequence */
size_t *len=NULL; /* Array to store sequence lengths */
size_t curr_len; /* Length of bytes left to process in sequence */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t nseq; /* Number of sequences generated */
size_t curr_seq; /* Current sequnce being worked on */
size_t nbytes; /* Number of bytes used in sequences */
@@ -374,15 +415,13 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
/* Get the hyperslab vector size */
/* (from the default data transfer property list, for now) */
- dx_plist = H5I_object(H5P_DATASET_XFER_DEFAULT);
- assert(dx_plist);
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ if((vector_size=H5S_get_vector_size(H5P_DATASET_XFER_DEFAULT))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
/* Get the datatype size */
@@ -391,13 +430,10 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
if((elmt_size=H5T_get_size(dt))==0)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid");
- /* Allocate iterator */
- if((iter = H5FL_ALLOC(H5S_sel_iter_t,1))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate selection iterator");
-
/* Initialize iterator */
- if ((*space->select.iter_init)(space, elmt_size, iter)<0)
+ if ((*space->select.iter_init)(space, elmt_size, &iter)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ iter_init=1; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
if((nelmts = (*space->select.get_npoints)(space))<0)
@@ -419,7 +455,7 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
/* Loop, while elements left in selection */
while(max_bytes>0 && user_ret==0) {
/* Get the sequences of bytes */
- if((*space->select.get_seq_list)(space,0,iter,elmt_size,vector_size,max_bytes,&nseq,&nbytes,off,len)<0)
+ if((*space->select.get_seq_list)(space,0,&iter,elmt_size,(size_t)vector_size,max_bytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Loop, while sequences left to process */
@@ -462,10 +498,9 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
done:
/* Release selection iterator */
- if(iter!=NULL) {
- if ((*space->select.iter_release)(iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- H5FL_FREE(H5S_sel_iter_t,iter);
+ if(iter_init) {
+ if ((*space->select.iter_release)(&iter)<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release length & offset vectors */
@@ -661,14 +696,14 @@ done:
herr_t
H5S_select_fill(void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
{
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
- H5S_sel_iter_t *iter=NULL; /* Selection iteration info */
+ H5S_sel_iter_t iter; /* Selection iteration info */
+ hbool_t iter_init=0; /* Selection iteration info has been initialized */
uint8_t *buf; /* Current location in buffer */
void *fill=_fill; /* Alias for fill-value buffer */
hssize_t nelmts; /* Number of elements in selection */
hsize_t *off=NULL; /* Array to store sequence offsets */
size_t *len=NULL; /* Array to store sequence lengths */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t nseq; /* Number of sequences generated */
size_t curr_seq; /* Current sequnce being worked on */
size_t nbytes; /* Number of bytes used in sequences */
@@ -684,30 +719,25 @@ H5S_select_fill(void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
/* Check if we need a temporary fill value buffer */
if(fill==NULL) {
- if (NULL==(fill = H5FL_BLK_ALLOC(type_elem,fill_size,1)))
+ if (NULL==(fill = H5FL_BLK_CALLOC(type_elem,fill_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "fill value buffer allocation failed");
} /* end if */
/* Get the hyperslab vector size */
/* (from the default data transfer property list, for now) */
- dx_plist = H5I_object(H5P_DATASET_XFER_DEFAULT);
- assert(dx_plist);
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ if((vector_size=H5S_get_vector_size(H5P_DATASET_XFER_DEFAULT))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- /* Allocate iterator */
- if((iter = H5FL_ALLOC(H5S_sel_iter_t,1))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate selection iterator");
-
/* Initialize iterator */
- if ((*space->select.iter_init)(space, fill_size, iter)<0)
+ if ((*space->select.iter_init)(space, fill_size, &iter)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ iter_init=1; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
if((nelmts = (*space->select.get_npoints)(space))<0)
@@ -720,7 +750,7 @@ H5S_select_fill(void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
/* Loop, while elements left in selection */
while(max_bytes>0) {
/* Get the sequences of bytes */
- if((*space->select.get_seq_list)(space,0,iter,fill_size,vector_size,max_bytes,&nseq,&nbytes,off,len)<0)
+ if((*space->select.get_seq_list)(space,0,&iter,fill_size,(size_t)vector_size,max_bytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Loop over sequences */
@@ -739,10 +769,9 @@ H5S_select_fill(void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
done:
/* Release selection iterator */
- if(iter!=NULL) {
- if ((*space->select.iter_release)(iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- H5FL_FREE(H5S_sel_iter_t,iter);
+ if(iter_init) {
+ if ((*space->select.iter_release)(&iter)<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release length & offset vectors */
@@ -779,18 +808,17 @@ done:
*/
herr_t
H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, size_t elmt_size,
- const H5S_t *space, H5S_sel_iter_t *iter,
- hsize_t nelmts, hid_t dxpl_id, const void *_buf)
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
+ hid_t dxpl_id, const void *_buf)
{
const uint8_t *buf=_buf; /* Alias for pointer arithmetic */
hsize_t *off=NULL; /* Array to store sequence offsets */
size_t *len=NULL; /* Array to store sequence lengths */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t maxbytes; /* Number of bytes in the buffer */
size_t nseq; /* Number of sequences generated */
size_t nbytes; /* Number of bytes used in sequences */
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_fscat, FAIL);
@@ -799,6 +827,7 @@ H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
assert (f);
assert (layout);
assert (elmt_size>0);
+ assert (efl);
assert (space);
assert (iter);
assert (nelmts>0);
@@ -806,15 +835,13 @@ H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
/* Get the hyperslab vector size */
- if(NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list");
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ if((vector_size=H5S_get_vector_size(dxpl_id))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
/* Compute the number of bytes available in buffer */
@@ -823,11 +850,11 @@ H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
/* Loop until all elements are written */
while(maxbytes>0) {
/* Get list of sequences for selection to write */
- if((*space->select.get_seq_list)(space,H5S_GET_SEQ_LIST_SORTED,iter,elmt_size,vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
+ if((*space->select.get_seq_list)(space,H5S_GET_SEQ_LIST_SORTED,iter,elmt_size,(size_t)vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Write sequence list out */
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, space, elmt_size, nseq, len, off, buf)<0)
+ if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, space, elmt_size, nseq, len, off, buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
/* Update buffer */
@@ -872,19 +899,17 @@ done:
*/
hsize_t
H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *space,
- H5S_sel_iter_t *iter, hsize_t nelmts, hid_t dxpl_id,
- void *_buf/*out*/)
+ H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
+ hid_t dxpl_id, void *_buf/*out*/)
{
uint8_t *buf=_buf; /* Alias for pointer arithmetic */
hsize_t *off=NULL; /* Array to store sequence offsets */
size_t *len=NULL; /* Array to store sequence lengths */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t maxbytes; /* Number of bytes in the buffer */
size_t nseq; /* Number of sequences generated */
size_t nbytes; /* Number of bytes used in sequences */
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
hsize_t ret_value=nelmts; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_fgath, 0);
@@ -893,21 +918,20 @@ H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
assert (f);
assert (layout);
assert (elmt_size>0);
+ assert (efl);
assert (space);
assert (iter);
assert (nelmts>0);
assert (_buf);
/* Get the hyperslab vector size */
- if(NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a file access property list");
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "unable to get value");
+ if((vector_size=H5S_get_vector_size(dxpl_id))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O length vector array");
- if((off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O offset vector array");
/* Compute the number of bytes available in buffer */
@@ -916,11 +940,11 @@ H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
/* Loop until all elements are written */
while(maxbytes>0) {
/* Get list of sequences for selection to write */
- if((*space->select.get_seq_list)(space,H5S_GET_SEQ_LIST_SORTED,iter,elmt_size,vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
+ if((*space->select.get_seq_list)(space,H5S_GET_SEQ_LIST_SORTED,iter,elmt_size,(size_t)vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed");
/* Read sequence list in */
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, space, elmt_size, nseq, len, off, buf)<0)
+ if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, space, elmt_size, nseq, len, off, buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error");
/* Update buffer */
@@ -961,11 +985,10 @@ herr_t
H5S_select_mscat (const void *_tscat_buf, size_t elmt_size, const H5S_t *space,
H5S_sel_iter_t *iter, hsize_t nelmts, hid_t dxpl_id, void *_buf/*out*/)
{
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
uint8_t *buf=(uint8_t *)_buf; /* Get local copies for address arithmetic */
const uint8_t *tscat_buf=(const uint8_t *)_tscat_buf;
hsize_t *off=NULL; /* Array to store sequence offsets */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t *len=NULL; /* Array to store sequence lengths */
size_t curr_len; /* Length of bytes left to process in sequence */
size_t maxbytes; /* Number of bytes in the buffer */
@@ -985,15 +1008,13 @@ H5S_select_mscat (const void *_tscat_buf, size_t elmt_size, const H5S_t *space,
assert (buf);
/* Get the hyperslab vector size */
- if(NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ if((vector_size=H5S_get_vector_size(dxpl_id))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
/* Compute the number of bytes available in buffer */
@@ -1002,7 +1023,7 @@ H5S_select_mscat (const void *_tscat_buf, size_t elmt_size, const H5S_t *space,
/* Loop until all elements are written */
while(maxbytes>0) {
/* Get list of sequences for selection to write */
- if((*space->select.get_seq_list)(space,0,iter,elmt_size,vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
+ if((*space->select.get_seq_list)(space,0,iter,elmt_size,(size_t)vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed");
/* Loop, while sequences left to process */
@@ -1053,11 +1074,10 @@ hsize_t
H5S_select_mgath (const void *_buf, size_t elmt_size, const H5S_t *space,
H5S_sel_iter_t *iter, hsize_t nelmts, hid_t dxpl_id, void *_tgath_buf/*out*/)
{
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
const uint8_t *buf=(const uint8_t *)_buf; /* Get local copies for address arithmetic */
uint8_t *tgath_buf=(uint8_t *)_tgath_buf;
hsize_t *off=NULL; /* Array to store sequence offsets */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t *len=NULL; /* Array to store sequence lengths */
size_t curr_len; /* Length of bytes left to process in sequence */
size_t maxbytes; /* Number of bytes in the buffer */
@@ -1077,15 +1097,13 @@ H5S_select_mgath (const void *_buf, size_t elmt_size, const H5S_t *space,
assert (tgath_buf);
/* Get the hyperslab vector size */
- if(NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataset transfer property list");
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "unable to get value");
+ if((vector_size=H5S_get_vector_size(dxpl_id))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O length vector array");
- if((off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O offset vector array");
/* Compute the number of bytes available in buffer */
@@ -1094,7 +1112,7 @@ H5S_select_mgath (const void *_buf, size_t elmt_size, const H5S_t *space,
/* Loop until all elements are written */
while(maxbytes>0) {
/* Get list of sequences for selection to write */
- if((*space->select.get_seq_list)(space,0,iter,elmt_size,vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
+ if((*space->select.get_seq_list)(space,0,iter,elmt_size,(size_t)vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed");
/* Loop, while sequences left to process */
@@ -1138,16 +1156,17 @@ done:
*/
herr_t
H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *file_space,
- const H5S_t *mem_space, hid_t dxpl_id, void *_buf/*out*/)
+ const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space,
+ const H5S_t *mem_space, hid_t dxpl_id, void *_buf/*out*/)
{
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
- H5S_sel_iter_t *mem_iter=NULL; /* Memory selection iteration info */
- H5S_sel_iter_t *file_iter=NULL; /* File selection iteration info */
+ H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
+ hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
+ H5S_sel_iter_t file_iter; /* File selection iteration info */
+ hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
uint8_t *buf=NULL; /* Local buffer pointer, for address arithmetic */
hsize_t *mem_off=NULL; /* Array to store sequence offsets in memory */
hsize_t *file_off=NULL; /* Array to store sequence offsets in the file */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t *mem_len=NULL; /* Array to store sequence lengths in memory */
size_t *file_len=NULL; /* Array to store sequence lengths in the file */
size_t maxbytes; /* Number of bytes in selection */
@@ -1168,40 +1187,33 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Check args */
assert(f);
+ assert(efl);
assert(_buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
/* Get the hyperslab vector size */
- if(NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ if((vector_size=H5S_get_vector_size(dxpl_id))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((mem_len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((mem_len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((mem_off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((mem_off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- if((file_len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((file_len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((file_off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((file_off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- /* Allocate file iterator */
- if((file_iter = H5FL_ALLOC(H5S_sel_iter_t,1))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate selection iterator");
-
/* Initialize file iterator */
- if ((*file_space->select.iter_init)(file_space, elmt_size, file_iter)<0)
+ if ((*file_space->select.iter_init)(file_space, elmt_size, &file_iter)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
-
- /* Allocate memory iterator */
- if((mem_iter = H5FL_ALLOC(H5S_sel_iter_t,1))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate selection iterator");
+ file_iter_init=1; /* File selection iteration info has been initialized */
/* Initialize memory iterator */
- if ((*mem_space->select.iter_init)(mem_space, elmt_size, mem_iter)<0)
+ if ((*mem_space->select.iter_init)(mem_space, elmt_size, &mem_iter)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ mem_iter_init=1; /* Memory selection iteration info has been initialized */
/* Get number of bytes in selection */
maxbytes=(*file_space->select.get_npoints)(file_space)*elmt_size;
@@ -1215,7 +1227,7 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Check if more file sequences are needed */
if(curr_file_seq>=file_nseq) {
/* Get sequences for file selection */
- if((*file_space->select.get_seq_list)(file_space,H5S_GET_SEQ_LIST_SORTED,file_iter,elmt_size,vector_size,maxbytes,&file_nseq,&file_nbytes,file_off,file_len)<0)
+ if((*file_space->select.get_seq_list)(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,elmt_size,(size_t)vector_size,maxbytes,&file_nseq,&file_nbytes,file_off,file_len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Start at the beginning of the sequences again */
@@ -1225,7 +1237,7 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Check if more memory sequences are needed */
if(curr_mem_seq>=mem_nseq) {
/* Get sequences for memory selection */
- if((*mem_space->select.get_seq_list)(mem_space,0,mem_iter,elmt_size,vector_size,maxbytes,&mem_nseq,&mem_nbytes,mem_off,mem_len)<0)
+ if((*mem_space->select.get_seq_list)(mem_space,0,&mem_iter,elmt_size,(size_t)vector_size,maxbytes,&mem_nseq,&mem_nbytes,mem_off,mem_len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Start at the beginning of the sequences again */
@@ -1271,7 +1283,7 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
partial_file=0;
/* Read file sequences into current memory sequence */
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, file_space, elmt_size, tot_file_seq, &file_len[orig_file_seq], &file_off[orig_file_seq], buf)<0)
+ if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tot_file_seq, &file_len[orig_file_seq], &file_off[orig_file_seq], buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
/* Update last file sequence, if it was partially accessed */
@@ -1308,7 +1320,7 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
tmp_file_len=mem_len[curr_mem_seq];
/* Read part of current file sequence into current memory sequence */
- if (H5F_seq_read(f, dxpl_id, layout, dc_plist, file_space, elmt_size, tmp_file_len, file_off[curr_file_seq], buf)<0)
+ if (H5F_seq_read(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tmp_file_len, file_off[curr_file_seq], buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
/* Update current file sequence information */
@@ -1331,17 +1343,15 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
done:
/* Release file selection iterator */
- if(file_iter!=NULL) {
- if ((*file_space->select.iter_release)(file_iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- H5FL_FREE(H5S_sel_iter_t,file_iter);
+ if(file_iter_init) {
+ if ((*file_space->select.iter_release)(&file_iter)<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release memory selection iterator */
- if(mem_iter!=NULL) {
- if ((*mem_space->select.iter_release)(mem_iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- H5FL_FREE(H5S_sel_iter_t,mem_iter);
+ if(mem_iter_init) {
+ if ((*mem_space->select.iter_release)(&mem_iter)<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Free vector arrays */
@@ -1373,16 +1383,17 @@ done:
*/
herr_t
H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *file_space,
- const H5S_t *mem_space, hid_t dxpl_id, const void *_buf/*out*/)
+ const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space,
+ const H5S_t *mem_space, hid_t dxpl_id, const void *_buf/*out*/)
{
- H5P_genplist_t *dx_plist; /* Dataset transfer property list */
- H5S_sel_iter_t *mem_iter=NULL; /* Memory selection iteration info */
- H5S_sel_iter_t *file_iter=NULL; /* File selection iteration info */
+ H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
+ hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
+ H5S_sel_iter_t file_iter; /* File selection iteration info */
+ hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
const uint8_t *buf=NULL; /* Local buffer pointer, for address arithmetic */
hsize_t *mem_off=NULL; /* Array to store sequence offsets in memory */
hsize_t *file_off=NULL; /* Array to store sequence offsets in the file */
- size_t vector_size; /* Value for vector size */
+ ssize_t vector_size; /* Value for vector size */
size_t *mem_len=NULL; /* Array to store sequence lengths in memory */
size_t *file_len=NULL; /* Array to store sequence lengths in the file */
size_t maxbytes; /* Number of bytes in selection */
@@ -1403,40 +1414,33 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Check args */
assert(f);
+ assert(efl);
assert(_buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
/* Get the hyperslab vector size */
- if(NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
- if (H5P_get(dx_plist,H5D_XFER_HYPER_VECTOR_SIZE_NAME,&vector_size)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value");
+ if((vector_size=H5S_get_vector_size(dxpl_id))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
/* Allocate the vector I/O arrays */
- if((mem_len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((mem_len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((mem_off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((mem_off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- if((file_len = H5FL_ARR_ALLOC(size_t,vector_size,0))==NULL)
+ if((file_len = H5FL_ARR_MALLOC(size_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((file_off = H5FL_ARR_ALLOC(hsize_t,vector_size,0))==NULL)
+ if((file_off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- /* Allocate file iterator */
- if((file_iter = H5FL_ALLOC(H5S_sel_iter_t,1))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate selection iterator");
-
/* Initialize file iterator */
- if ((*file_space->select.iter_init)(file_space, elmt_size, file_iter)<0)
+ if ((*file_space->select.iter_init)(file_space, elmt_size, &file_iter)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
-
- /* Allocate memory iterator */
- if((mem_iter = H5FL_ALLOC(H5S_sel_iter_t,1))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate selection iterator");
+ file_iter_init=1; /* File selection iteration info has been initialized */
/* Initialize memory iterator */
- if ((*mem_space->select.iter_init)(mem_space, elmt_size, mem_iter)<0)
+ if ((*mem_space->select.iter_init)(mem_space, elmt_size, &mem_iter)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ mem_iter_init=1; /* Memory selection iteration info has been initialized */
/* Get number of bytes in selection */
maxbytes=(*file_space->select.get_npoints)(file_space)*elmt_size;
@@ -1450,7 +1454,7 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Check if more file sequences are needed */
if(curr_file_seq>=file_nseq) {
/* Get sequences for file selection */
- if((*file_space->select.get_seq_list)(file_space,H5S_GET_SEQ_LIST_SORTED,file_iter,elmt_size,vector_size,maxbytes,&file_nseq,&file_nbytes,file_off,file_len)<0)
+ if((*file_space->select.get_seq_list)(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,elmt_size,(size_t)vector_size,maxbytes,&file_nseq,&file_nbytes,file_off,file_len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Start at the beginning of the sequences again */
@@ -1460,7 +1464,7 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Check if more memory sequences are needed */
if(curr_mem_seq>=mem_nseq) {
/* Get sequences for memory selection */
- if((*mem_space->select.get_seq_list)(mem_space,0,mem_iter,elmt_size,vector_size,maxbytes,&mem_nseq,&mem_nbytes,mem_off,mem_len)<0)
+ if((*mem_space->select.get_seq_list)(mem_space,0,&mem_iter,elmt_size,(size_t)vector_size,maxbytes,&mem_nseq,&mem_nbytes,mem_off,mem_len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
/* Start at the beginning of the sequences again */
@@ -1506,7 +1510,7 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
partial_file=0;
/* Write current memory sequence into file sequences */
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, file_space, elmt_size, tot_file_seq, &file_len[orig_file_seq], &file_off[orig_file_seq], buf)<0)
+ if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tot_file_seq, &file_len[orig_file_seq], &file_off[orig_file_seq], buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
/* Update last file sequence, if it was partially accessed */
@@ -1543,7 +1547,7 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
tmp_file_len=mem_len[curr_mem_seq];
/* Write part of current memory sequence to current file sequence */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, file_space, elmt_size, tmp_file_len, file_off[curr_file_seq], buf)<0)
+ if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tmp_file_len, file_off[curr_file_seq], buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
/* Update current file sequence information */
@@ -1566,17 +1570,15 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
done:
/* Release file selection iterator */
- if(file_iter!=NULL) {
- if ((*file_space->select.iter_release)(file_iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- H5FL_FREE(H5S_sel_iter_t,file_iter);
+ if(file_iter_init) {
+ if ((*file_space->select.iter_release)(&file_iter)<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release memory selection iterator */
- if(mem_iter!=NULL) {
- if ((*mem_space->select.iter_release)(mem_iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- H5FL_FREE(H5S_sel_iter_t,mem_iter);
+ if(mem_iter_init) {
+ if ((*mem_space->select.iter_release)(&mem_iter)<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Free vector arrays */
diff --git a/src/H5T.c b/src/H5T.c
index 51b14d5..64cc2e3 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1522,7 +1522,7 @@ H5T_init_interface(void)
/* Opaque data */
if(H5T_NATIVE_OPAQUE_g<0) {
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Set information */
@@ -1544,7 +1544,7 @@ H5T_init_interface(void)
/* One-byte character string */
if(H5T_C_S1_g<0) {
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->state = H5T_STATE_IMMUTABLE;
@@ -1570,7 +1570,7 @@ H5T_init_interface(void)
/* One-byte character string */
if(H5T_FORTRAN_S1_g<0) {
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->state = H5T_STATE_IMMUTABLE;
@@ -1596,7 +1596,7 @@ H5T_init_interface(void)
/* Object pointer (i.e. object header address in file) */
if(H5T_STD_REF_OBJ_g<0) {
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->state = H5T_STATE_IMMUTABLE;
@@ -1616,7 +1616,7 @@ H5T_init_interface(void)
/* Dataset Region pointer (i.e. selection inside a dataset) */
if(H5T_STD_REF_DSETREG_g<0) {
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
dt->state = H5T_STATE_IMMUTABLE;
@@ -1897,7 +1897,7 @@ H5T_term_interface(void)
H5T_print_stats(path, &nprint/*in,out*/);
path->cdata.command = H5T_CONV_FREE;
if ((path->func)(FAIL, FAIL, &(path->cdata),
- (hsize_t)0, 0, 0, NULL, NULL,H5P_DEFAULT)<0) {
+ (hsize_t)0, 0, 0, NULL, NULL,H5P_DATASET_XFER_DEFAULT)<0) {
#ifdef H5T_DEBUG
if (H5DEBUG(T)) {
fprintf (H5DEBUG(T), "H5T: conversion function "
@@ -2688,7 +2688,7 @@ hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if(direction!=H5T_DIR_DEFAULT && direction!=H5T_DIR_ASCEND
- && direction!=H5T_DIR_DESCEND)
+ && direction!=H5T_DIR_DESCEND)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not valid direction value");
if((new_dt = H5T_get_native_type(dt, direction, NULL, NULL, &comp_size))==NULL)
@@ -2732,7 +2732,7 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
int nmemb; /* Number of members in compound & enum types */
H5T_t *super_type; /* Super type of VL, array and enum datatypes */
H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */
- H5T_t *new_type; /* New native datatype */
+ H5T_t *new_type=NULL; /* New native datatype */
int i; /* Local index variable */
H5T_t *ret_value; /* Return value */
@@ -2771,7 +2771,7 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
size_t pointer_size;
if(H5T_is_variable_str(dtype)) {
- if(NULL==(dt=H5I_object_verify(H5T_C_S1, H5I_DATATYPE)))
+ if(NULL==(dt=H5I_object(H5T_C_S1)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
@@ -2788,7 +2788,7 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
} else {
/*size_t char_size;*/
- if(NULL==(dt=H5I_object_verify(H5T_NATIVE_UCHAR, H5I_DATATYPE)))
+ if(NULL==(dt=H5I_object(H5T_NATIVE_UCHAR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
@@ -2801,8 +2801,6 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, align, struct_align)<0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
- if(H5T_close(dt)<0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't close data type");
}
}
break;
@@ -2821,13 +2819,12 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
size_t align;
size_t ref_size;
int not_equal;
- H5T_t *dt;
if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
/* Decide if the data type is object or dataset region reference. */
- if(NULL==(dt=H5I_object_verify(H5T_STD_REF_OBJ_g, H5I_DATATYPE)))
+ if(NULL==(dt=H5I_object(H5T_STD_REF_OBJ_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
not_equal = H5T_cmp(ret_value, dt);
@@ -2975,7 +2972,6 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
size_t super_offset=0;
size_t super_size=0;
size_t super_align=0;
- int i;
/* Retrieve dimension information for array data type */
if((array_rank=H5T_get_array_ndims(dtype))<=0)
@@ -3006,7 +3002,8 @@ H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *stru
for(i=0; i<array_rank; i++)
nelems *= dims[i];
- if(H5T_cmp_offset(comp_size, offset, super_size, nelems, super_align, struct_align)<0)
+ H5_CHECK_OVERFLOW(nelems,hsize_t,size_t);
+ if(H5T_cmp_offset(comp_size, offset, super_size, (size_t)nelems, super_align, struct_align)<0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset");
H5MM_xfree(dims);
@@ -3086,8 +3083,8 @@ H5T_t* H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t dire
size_t *struct_align, size_t *offset, size_t *comp_size)
{
H5T_t *dt; /* Appropriate native datatype to copy */
- hid_t tid; /* Datatype ID of appropriate native datatype */
- size_t align; /* Alignment necessary for native datatype */
+ hid_t tid=(-1); /* Datatype ID of appropriate native datatype */
+ size_t align=0; /* Alignment necessary for native datatype */
enum match_type { /* The different kinds of integers we can match */
H5T_NATIVE_INT_MATCH_CHAR,
H5T_NATIVE_INT_MATCH_SHORT,
@@ -3183,7 +3180,8 @@ H5T_t* H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t dire
} /* end switch */
/* Create new native type */
- if(NULL==(dt=H5I_object_verify(tid, H5I_DATATYPE)))
+ assert(tid>=0);
+ if(NULL==(dt=H5I_object(tid)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
@@ -3216,8 +3214,8 @@ done:
H5T_t* H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size)
{
H5T_t *dt=NULL; /* Appropriate native datatype to copy */
- hid_t tid; /* Datatype ID of appropriate native datatype */
- size_t align; /* Alignment necessary for native datatype */
+ hid_t tid=(-1); /* Datatype ID of appropriate native datatype */
+ size_t align=0; /* Alignment necessary for native datatype */
enum match_type { /* The different kinds of floating point types we can match */
H5T_NATIVE_FLOAT_MATCH_FLOAT,
H5T_NATIVE_FLOAT_MATCH_DOUBLE,
@@ -3273,7 +3271,8 @@ H5T_t* H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *stru
} /* end switch */
/* Create new native type */
- if(NULL==(dt=H5I_object_verify(tid, H5I_DATATYPE)))
+ assert(tid>=0);
+ if(NULL==(dt=H5I_object(tid)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type");
@@ -5201,7 +5200,7 @@ H5T_enum_create(H5T_t *parent)
assert(parent);
/* Build new type */
- if (NULL==(ret_value = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(ret_value = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
ret_value->type = H5T_ENUM;
ret_value->parent = H5T_copy(parent, H5T_COPY_ALL);
@@ -5546,7 +5545,7 @@ H5T_vlen_create(H5T_t *base)
assert(base);
/* Build new type */
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
dt->ent.header = HADDR_UNDEF;
dt->type = H5T_VLEN;
@@ -5797,7 +5796,7 @@ H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data types for conv query");
HDmemset(&cdata, 0, sizeof cdata);
cdata.command = H5T_CONV_INIT;
- if ((func)(tmp_sid, tmp_did, &cdata, (hsize_t)0, 0, 0, NULL, NULL, H5P_DEFAULT)<0) {
+ if ((func)(tmp_sid, tmp_did, &cdata, (hsize_t)0, 0, 0, NULL, NULL, H5P_DATASET_XFER_DEFAULT)<0) {
H5I_dec_ref(tmp_sid);
H5I_dec_ref(tmp_did);
tmp_sid = tmp_did = -1;
@@ -5806,7 +5805,7 @@ H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
} /* end if */
/* Create a new conversion path */
- if (NULL==(new_path=H5FL_ALLOC(H5T_path_t,1)))
+ if (NULL==(new_path=H5FL_CALLOC(H5T_path_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
HDstrncpy(new_path->name, name, H5T_NAMELEN);
new_path->name[H5T_NAMELEN-1] = '\0';
@@ -5824,7 +5823,7 @@ H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
/* Free old path */
H5T_print_stats(old_path, &nprint);
old_path->cdata.command = H5T_CONV_FREE;
- if ((old_path->func)(tmp_sid, tmp_did, &(old_path->cdata), (hsize_t)0, 0, 0, NULL, NULL, H5P_DEFAULT)<0) {
+ if ((old_path->func)(tmp_sid, tmp_did, &(old_path->cdata), (hsize_t)0, 0, 0, NULL, NULL, H5P_DATASET_XFER_DEFAULT)<0) {
#ifdef H5T_DEBUG
if (H5DEBUG(T)) {
fprintf (H5DEBUG(T), "H5T: conversion function 0x%08lx "
@@ -5986,7 +5985,7 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
H5T_print_stats(path, &nprint);
path->cdata.command = H5T_CONV_FREE;
if ((path->func)(FAIL, FAIL, &(path->cdata), (hsize_t)0, 0, 0, NULL, NULL,
- H5P_DEFAULT)<0) {
+ H5P_DATASET_XFER_DEFAULT)<0) {
#ifdef H5T_DEBUG
if (H5DEBUG(T)) {
fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx failed "
@@ -6141,9 +6140,13 @@ H5Tconvert(hid_t src_id, hid_t dst_id, hsize_t nelmts, void *buf,
/* Check args */
if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)) ||
- (H5P_DEFAULT!=plist_id && TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER)))
+ NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if(H5P_DEFAULT == plist_id)
+ plist_id = H5P_DATASET_XFER_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset transfer property list");
/* Find the conversion function */
if (NULL==(tpath=H5T_path_find(src, dst, NULL, NULL)))
@@ -6272,7 +6275,7 @@ H5T_create(H5T_class_t type, size_t size)
case H5T_OPAQUE:
case H5T_COMPOUND:
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
dt->type = type;
break;
@@ -6291,7 +6294,7 @@ H5T_create(H5T_class_t type, size_t size)
} else {
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no applicable native integer type");
}
- if (NULL==(dt = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
dt->type = type;
if (NULL==(dt->parent=H5T_copy(H5I_object(subtype), H5T_COPY_ALL)))
@@ -6506,7 +6509,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
assert(old_dt);
/* Allocate space */
- if (NULL==(new_dt = H5FL_ALLOC(H5T_t,0)))
+ if (NULL==(new_dt = H5FL_MALLOC(H5T_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Copy actual information */
@@ -6725,7 +6728,7 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type)
*/
if (H5O_create (file, 64, &(type->ent))<0)
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create data type object header");
- if (H5O_modify (&(type->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT, type)<0)
+ if (H5O_modify (&(type->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT, 1, type)<0)
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message");
if (H5G_insert (loc, name, &(type->ent))<0)
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to name data type");
@@ -6789,36 +6792,27 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5T_close
+ * Function: H5T_release
*
- * Purpose: Frees a data type and all associated memory. If the data
- * type is locked then nothing happens.
+ * Purpose: Frees all memory associated with a datatype, but does not
+ * free the H5T_t structure (which should be done in H5T_close).
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Monday, December 8, 1997
+ * Programmer: Quincey Koziol
+ * Monday, January 6, 2003
*
* Modifications:
- * Robb Matzke, 1999-04-27
- * This function fails if the datatype state is IMMUTABLE.
- *
- * Robb Matzke, 1999-05-20
- * Closes opaque types also.
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added "ID to name" support
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_close(H5T_t *dt)
+H5T_free(H5T_t *dt)
{
int i;
- H5T_t *parent = dt->parent;
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_close, FAIL);
+ FUNC_ENTER_NOAPI(H5T_free, FAIL);
assert(dt);
@@ -6866,15 +6860,58 @@ H5T_close(H5T_t *dt)
/* Free the ID to name info */
H5G_free_ent_name(&(dt->ent));
- /* Free the datatype struct */
- H5FL_FREE(H5T_t,dt);
-
/* Close the parent */
- if (parent && H5T_close(parent)<0)
+ if (dt->parent && H5T_close(dt->parent)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to close parent data type");
done:
FUNC_LEAVE(ret_value);
+} /* end H5T_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_close
+ *
+ * Purpose: Frees a data type and all associated memory. If the data
+ * type is locked then nothing happens.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Monday, December 8, 1997
+ *
+ * Modifications:
+ * Robb Matzke, 1999-04-27
+ * This function fails if the datatype state is IMMUTABLE.
+ *
+ * Robb Matzke, 1999-05-20
+ * Closes opaque types also.
+ *
+ * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
+ * Added "ID to name" support
+ *
+ * Quincey Koziol, 2003-01-06
+ * Moved "guts" of function to H5T_free()
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_close(H5T_t *dt)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5T_close, FAIL);
+
+ assert(dt);
+
+ if(H5T_free(dt)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype");
+
+ /* Free the datatype struct */
+ H5FL_FREE(H5T_t,dt);
+
+done:
+ FUNC_LEAVE(ret_value);
}
@@ -8267,13 +8304,13 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
if (NULL==(H5T_g.path=H5MM_malloc(128*sizeof(H5T_path_t*))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path table");
H5T_g.apaths = 128;
- if (NULL==(H5T_g.path[0]=H5FL_ALLOC(H5T_path_t,1)))
+ if (NULL==(H5T_g.path[0]=H5FL_CALLOC(H5T_path_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for no-op conversion path");
HDstrcpy(H5T_g.path[0]->name, "no-op");
H5T_g.path[0]->func = H5T_conv_noop;
H5T_g.path[0]->cdata.command = H5T_CONV_INIT;
if (H5T_conv_noop(FAIL, FAIL, &(H5T_g.path[0]->cdata), (hsize_t)0, 0, 0,
- NULL, NULL, H5P_DEFAULT)<0) {
+ NULL, NULL, H5P_DATASET_XFER_DEFAULT)<0) {
#ifdef H5T_DEBUG
if (H5DEBUG(T)) {
fprintf(H5DEBUG(T), "H5T: unable to initialize no-op "
@@ -8330,7 +8367,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
* the path.
*/
if (!table || func) {
- if (NULL==(path=H5FL_ALLOC(H5T_path_t,1)))
+ if (NULL==(path=H5FL_CALLOC(H5T_path_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path");
if (name && *name) {
HDstrncpy(path->name, name, H5T_NAMELEN);
@@ -8360,7 +8397,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination conversion type for query");
path->cdata.command = H5T_CONV_INIT;
if ((func)(src_id, dst_id, &(path->cdata), (hsize_t)0, 0, 0, NULL, NULL,
- H5P_DEFAULT)<0)
+ H5P_DATASET_XFER_DEFAULT)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function");
if (src_id>=0) H5I_dec_ref(src_id);
if (dst_id>=0) H5I_dec_ref(dst_id);
@@ -8388,7 +8425,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register conversion types for query");
path->cdata.command = H5T_CONV_INIT;
if ((H5T_g.soft[i].func) (src_id, dst_id, &(path->cdata),
- (hsize_t)0, 0, 0, NULL, NULL, H5P_DEFAULT)<0) {
+ (hsize_t)0, 0, 0, NULL, NULL, H5P_DATASET_XFER_DEFAULT)<0) {
HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t));
H5E_clear(); /*ignore the error*/
} else {
@@ -8432,7 +8469,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
H5T_print_stats(table, &nprint/*in,out*/);
table->cdata.command = H5T_CONV_FREE;
if ((table->func)(FAIL, FAIL, &(table->cdata), (hsize_t)0, 0, 0, NULL, NULL,
- H5P_DEFAULT)<0) {
+ H5P_DATASET_XFER_DEFAULT)<0) {
#ifdef H5T_DEBUG
if (H5DEBUG(T)) {
fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx free "
@@ -8794,7 +8831,7 @@ H5T_array_create(H5T_t *base, int ndims, const hsize_t dim[/* ndims */],
assert(dim);
/* Build new type */
- if (NULL==(ret_value = H5FL_ALLOC(H5T_t,1)))
+ if (NULL==(ret_value = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
ret_value->ent.header = HADDR_UNDEF;
diff --git a/src/H5TB.c b/src/H5TB.c
index 391101f..5f04732 100644
--- a/src/H5TB.c
+++ b/src/H5TB.c
@@ -90,7 +90,7 @@
/* Local Function Prototypes */
static H5TB_NODE * H5TB_end(H5TB_NODE * root, int side);
-static H5TB_NODE *H5TB_ffind(H5TB_NODE * root, void * key, unsigned fast_compare,
+static H5TB_NODE *H5TB_ffind(H5TB_NODE * root, const void * key, unsigned fast_compare,
H5TB_NODE ** pp);
static herr_t H5TB_balance(H5TB_NODE ** root, H5TB_NODE * ptr, int side, int added);
static H5TB_NODE *H5TB_swapkid(H5TB_NODE ** root, H5TB_NODE * ptr, int side);
@@ -105,12 +105,148 @@ static herr_t H5TB_dumpNode(H5TB_NODE *node, void (*key_dump)(void *,void *),
/* Declare a free list to manage the H5TB_NODE struct */
H5FL_DEFINE_STATIC(H5TB_NODE);
+/* Declare a free list to manage the H5TB_TREE struct */
+H5FL_DEFINE_STATIC(H5TB_TREE);
+
#define PABLO_MASK H5TB_mask
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
/*-------------------------------------------------------------------------
+ * Function: H5TB_strcmp
+ *
+ * Purpose: Key comparison routine for TBBT routines
+ *
+ * Return: same as strcmp()
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, December 4, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5TB_strcmp(const void *k1, const void *k2, int UNUSED cmparg)
+{
+ FUNC_ENTER_NOINIT(H5TB_strcmp);
+
+ assert(k1);
+ assert(k2);
+
+ FUNC_LEAVE(HDstrcmp(k1,k2));
+} /* end H5TB_strcmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TB_addr_cmp
+ *
+ * Purpose: Key comparison routine for TBBT routines
+ *
+ * Return: same as H5F_addr_cmp()
+ *
+ * Programmer: Quincey Koziol
+ * Friday, December 20, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5TB_addr_cmp(const void *k1, const void *k2, int UNUSED cmparg)
+{
+ FUNC_ENTER_NOINIT(H5TB_addr_cmp);
+
+ assert(k1);
+ assert(k2);
+
+ FUNC_LEAVE(H5F_addr_cmp(*(const haddr_t *)k1,*(const haddr_t *)k2));
+} /* end H5TB_addr_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TB_int_cmp
+ *
+ * Purpose: Key comparison routine for TBBT routines
+ *
+ * Return: same as comparing two integers
+ *
+ * Programmer: Quincey Koziol
+ * Friday, December 20, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5TB_int_cmp(const void *k1, const void *k2, int UNUSED cmparg)
+{
+ FUNC_ENTER_NOINIT(H5TB_int_cmp);
+
+ assert(k1);
+ assert(k2);
+
+ FUNC_LEAVE(*(const int *)k1 - *(const int *)k2);
+} /* end H5TB_int_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TB_fast_dmake
+ *
+ * Purpose: Wrapper around H5TB_dmake for callers which want to use
+ * a "fast comparison" key.
+ *
+ * Return: Success: Pointer to a valid H5TB tree
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, December 20, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5TB_TREE *
+H5TB_fast_dmake(unsigned fast_compare)
+{
+ H5TB_cmp_t compar; /* Key comparison function */
+ int cmparg; /* Key comparison value */
+ H5TB_TREE *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5TB_fast_dmake, NULL);
+
+ /* Get the corret fast comparison routine */
+ switch(fast_compare) {
+ case H5TB_FAST_HADDR_COMPARE:
+ compar=H5TB_addr_cmp;
+ cmparg=-1;
+ break;
+
+ case H5TB_FAST_INTN_COMPARE:
+ compar=H5TB_int_cmp;
+ cmparg=-1;
+ break;
+
+ case H5TB_FAST_STR_COMPARE:
+ compar=H5TB_strcmp;
+ cmparg=-1;
+ break;
+
+ default:
+ HGOTO_ERROR (H5E_TBBT, H5E_BADVALUE, NULL, "invalid fast comparison type");
+ } /* end switch */
+
+ /* Set return value */
+ if((ret_value=H5TB_dmake(compar,cmparg,fast_compare))==NULL)
+ HGOTO_ERROR (H5E_TBBT, H5E_CANTCREATE, NULL, "can't create TBBT");
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* end H5TB_fast_dmake() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5TB_dmake
*
* Purpose: Allocates and initializes an empty threaded, balanced, binary tree
@@ -192,7 +328,7 @@ H5TB_dmake(H5TB_cmp_t cmp, int arg, unsigned fast_compare)
FUNC_ENTER_NOAPI(H5TB_dmake, NULL);
- if (NULL == (tree = H5MM_malloc(sizeof(H5TB_TREE))))
+ if (NULL == (tree = H5FL_MALLOC(H5TB_TREE)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
tree->root = NULL;
@@ -234,7 +370,7 @@ done:
*-------------------------------------------------------------------------
*/
H5TB_NODE *
-H5TB_dfind(H5TB_TREE * tree, void * key, H5TB_NODE ** pp)
+H5TB_dfind(H5TB_TREE * tree, const void * key, H5TB_NODE ** pp)
{
H5TB_NODE *ret_value;
@@ -242,10 +378,16 @@ H5TB_dfind(H5TB_TREE * tree, void * key, H5TB_NODE ** pp)
assert(tree);
- if(tree->fast_compare!=0)
- ret_value=H5TB_ffind(tree->root, key, tree->fast_compare, pp);
- else
- ret_value=H5TB_find(tree->root, key, tree->compar, tree->cmparg, pp);
+ if(tree->root)
+ if(tree->fast_compare!=0)
+ ret_value=H5TB_ffind(tree->root, key, tree->fast_compare, pp);
+ else
+ ret_value=H5TB_find(tree->root, key, tree->compar, tree->cmparg, pp);
+ else {
+ if (NULL != pp)
+ *pp = NULL;
+ ret_value=NULL;
+ } /* end else */
done:
FUNC_LEAVE (ret_value);
@@ -280,7 +422,7 @@ done:
*-------------------------------------------------------------------------
*/
H5TB_NODE *
-H5TB_find(H5TB_NODE * root, void * key,
+H5TB_find(H5TB_NODE * root, const void * key,
H5TB_cmp_t compar, int arg, H5TB_NODE ** pp)
{
H5TB_NODE *ptr = root;
@@ -461,7 +603,7 @@ H5TB_index(H5TB_NODE * root, unsigned indx)
if (NULL != ptr) {
/* Termination condition is if the index equals the number of children on
out left plus the current node */
- while (ptr != NULL && indx != ((unsigned) LeftCnt(ptr)) + 1 ) {
+ while (ptr != NULL && indx != ((unsigned) LeftCnt(ptr)) ) {
if (indx <= (unsigned) LeftCnt(ptr)) {
ptr = ptr->Lchild;
} /* end if */
@@ -564,7 +706,7 @@ H5TB_ins(H5TB_NODE ** root, void * item, void * key, H5TB_cmp_t compar, int arg)
if (NULL != H5TB_find(*root, (key ? key : item), compar, arg, &parent))
HGOTO_ERROR (H5E_TBBT, H5E_EXISTS, NULL, "node already in tree");
- if (NULL == (ptr = H5FL_ALLOC(H5TB_NODE,0)))
+ if (NULL == (ptr = H5FL_MALLOC(H5TB_NODE)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
ptr->data = item;
ptr->key = key ? key : item;
@@ -760,12 +902,13 @@ H5TB_rem(H5TB_NODE ** root, H5TB_NODE * node, void * *kp)
H5FL_FREE(H5TB_NODE,leaf);
H5TB_balance(root, par, side, -1);
- ((H5TB_TREE *) root)->count--;
-
/* Set return value */
ret_value=data;
done:
+ if(ret_value)
+ ((H5TB_TREE *) root)->count--;
+
FUNC_LEAVE(ret_value);
} /* end H5TB_rem() */
@@ -945,7 +1088,7 @@ H5TB_dfree(H5TB_TREE * tree, void(*fd) (void * /* item */), void(*fk) (void * /*
H5TB_free(&tree->root, fd, fk);
/* Free the tree root */
- H5MM_xfree(tree);
+ H5FL_FREE(H5TB_TREE,tree);
} /* end if */
done:
@@ -1254,7 +1397,7 @@ done:
/* This routine is based on tbbtfind (fix bugs in both places!) */
/* Returns a pointer to the found node (or NULL) */
static H5TB_NODE *
-H5TB_ffind(H5TB_NODE * root, void * key, unsigned fast_compare, H5TB_NODE ** pp)
+H5TB_ffind(H5TB_NODE * root, const void * key, unsigned fast_compare, H5TB_NODE ** pp)
{
H5TB_NODE *ptr = root;
H5TB_NODE *parent = NULL;
@@ -1267,7 +1410,7 @@ H5TB_ffind(H5TB_NODE * root, void * key, unsigned fast_compare, H5TB_NODE ** pp)
switch(fast_compare) {
case H5TB_FAST_HADDR_COMPARE:
if (ptr) {
- while (0 != (cmp = H5F_addr_cmp(*(haddr_t *)key,*(haddr_t *)ptr->key))) {
+ while (0 != (cmp = H5F_addr_cmp(*(const haddr_t *)key,*(haddr_t *)ptr->key))) {
parent = ptr;
side = (cmp < 0) ? LEFT : RIGHT;
if (!HasChild(ptr, side))
@@ -1284,7 +1427,24 @@ H5TB_ffind(H5TB_NODE * root, void * key, unsigned fast_compare, H5TB_NODE ** pp)
case H5TB_FAST_INTN_COMPARE:
if (ptr) {
- while (0 != (cmp = (*(int *)key - *(int *)ptr->key))) {
+ while (0 != (cmp = (*(const int *)key - *(int *)ptr->key))) {
+ parent = ptr;
+ side = (cmp < 0) ? LEFT : RIGHT;
+ if (!HasChild(ptr, side))
+ break;
+ ptr = ptr->link[side];
+ } /* end while */
+ } /* end if */
+ if (NULL != pp)
+ *pp = parent;
+
+ /* Set return value */
+ ret_value= (0 == cmp) ? ptr : NULL;
+ break;
+
+ case H5TB_FAST_STR_COMPARE:
+ if (ptr) {
+ while (0 != (cmp = HDstrcmp(key,ptr->key))) {
parent = ptr;
side = (cmp < 0) ? LEFT : RIGHT;
if (!HasChild(ptr, side))
diff --git a/src/H5TBprivate.h b/src/H5TBprivate.h
index f1d6bef..9c2ccc5 100644
--- a/src/H5TBprivate.h
+++ b/src/H5TBprivate.h
@@ -23,7 +23,7 @@
#endif /* LATER */
/* Typedef for key comparison function */
-typedef int (*H5TB_cmp_t)(void *k1, void *k2, int cmparg);
+typedef int (*H5TB_cmp_t)(const void *k1, const void *k2, int cmparg);
/* Shortcut macros for links */
# define PARENT 0
@@ -89,6 +89,10 @@ typedef struct H5TB_tree
/* Define the "fast compare" values */
#define H5TB_FAST_HADDR_COMPARE 1
#define H5TB_FAST_INTN_COMPARE 2
+#define H5TB_FAST_STR_COMPARE 3
+
+/* Define an access macro for getting a node's data */
+#define H5TB_NODE_DATA(n) ((n)->data)
#if defined c_plusplus || defined __cplusplus
extern "C"
@@ -96,8 +100,9 @@ extern "C"
#endif /* c_plusplus || __cplusplus */
H5_DLL H5TB_TREE *H5TB_dmake (H5TB_cmp_t cmp, int arg, unsigned fast_compare);
-H5_DLL H5TB_NODE *H5TB_dfind (H5TB_TREE * tree, void * key, H5TB_NODE ** pp);
-H5_DLL H5TB_NODE *H5TB_find(H5TB_NODE * root, void * key, H5TB_cmp_t cmp,
+H5_DLL H5TB_TREE *H5TB_fast_dmake (unsigned fast_compare);
+H5_DLL H5TB_NODE *H5TB_dfind (H5TB_TREE * tree, const void * key, H5TB_NODE ** pp);
+H5_DLL H5TB_NODE *H5TB_find(H5TB_NODE * root, const void * key, H5TB_cmp_t cmp,
int arg, H5TB_NODE ** pp);
H5_DLL H5TB_NODE *H5TB_dless (H5TB_TREE * tree, void * key, H5TB_NODE ** pp);
H5_DLL H5TB_NODE *H5TB_less (H5TB_NODE * root, void * key, H5TB_cmp_t cmp,
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 0444d2c..7f389ec 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -283,8 +283,8 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
case H5T_CONV_INIT: \
/* Sanity check and initialize statistics */ \
cdata->need_bkg = H5T_BKG_NO; \
- if (NULL==(st=H5I_object_verify(src_id,H5I_DATATYPE)) || \
- NULL==(dt=H5I_object_verify(dst_id,H5I_DATATYPE))) { \
+ if (NULL==(st=H5I_object(src_id)) || \
+ NULL==(dt=H5I_object(dst_id))) { \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \
"unable to dereference data type object ID"); \
} \
@@ -292,13 +292,13 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \
"disagreement about data type size"); \
} \
- CI_ALLOC_PRIV \
+ CI_ALLOC_PRIV \
break; \
\
case H5T_CONV_FREE: \
/* Print and free statistics */ \
CI_PRINT_STATS(STYPE,DTYPE); \
- CI_FREE_PRIV \
+ CI_FREE_PRIV \
break; \
\
case H5T_CONV_CONV: \
@@ -488,8 +488,8 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
switch (cdata->command) {
case H5T_CONV_INIT:
/* Capability query */
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (src->size != dst->size ||
0 != src->u.atomic.offset ||
@@ -528,8 +528,8 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
case H5T_CONV_CONV:
/* The conversion */
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
buf_stride = buf_stride ? buf_stride : src->size;
@@ -872,8 +872,8 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
switch (cdata->command) {
case H5T_CONV_INIT:
/* Capability query */
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (src->size != dst->size || 0 != src->u.atomic.offset ||
0 != dst->u.atomic.offset ||
@@ -909,8 +909,8 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
case H5T_CONV_CONV:
/* The conversion */
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
buf_stride = buf_stride ? buf_stride : src->size;
@@ -974,8 +974,8 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
switch(cdata->command) {
case H5T_CONV_INIT:
/* Capability query */
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (H5T_ORDER_LE!=src->u.atomic.order &&
H5T_ORDER_BE!=src->u.atomic.order)
@@ -991,8 +991,8 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
case H5T_CONV_CONV:
/* Get the data types */
- if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src=H5I_object(src_id)) ||
+ NULL==(dst=H5I_object(dst_id)))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/*
@@ -1339,8 +1339,8 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
* otherwise initialize the `priv' field of `cdata' with information
* that remains (almost) constant for this conversion path.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (H5T_COMPOUND==src->type);
assert (H5T_COMPOUND==dst->type);
@@ -1364,8 +1364,8 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
/*
* Conversion.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (priv);
assert (bkg && cdata->need_bkg);
@@ -1571,8 +1571,8 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
* otherwise initialize the `priv' field of `cdata' with information
* that remains (almost) constant for this conversion path.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (H5T_COMPOUND==src->type);
assert (H5T_COMPOUND==dst->type);
@@ -1638,8 +1638,8 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
/*
* Conversion.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/* Update cached data if necessary */
@@ -1934,8 +1934,8 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
* the `priv' field of `cdata' with information about the underlying
* integer conversion.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (H5T_ENUM==src->type);
assert (H5T_ENUM==dst->type);
@@ -1959,8 +1959,8 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
break;
case H5T_CONV_CONV:
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (H5T_ENUM==src->type);
assert (H5T_ENUM==dst->type);
@@ -2132,8 +2132,8 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
* information that remains (almost) constant for this
* conversion path.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (H5T_VLEN==src->type);
assert (H5T_VLEN==dst->type);
@@ -2151,8 +2151,8 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
/*
* Conversion.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/*
@@ -2209,7 +2209,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
/* Get initial conversion buffer */
conv_buf_size=MAX(src_base_size,dst_base_size);
- if ((conv_buf=H5FL_BLK_ALLOC(vlen_seq,conv_buf_size,1))==NULL)
+ if ((conv_buf=H5FL_BLK_CALLOC(vlen_seq,conv_buf_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
/* Set up conversion path for base elements */
@@ -2225,7 +2225,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
if(tpath->cdata.need_bkg||H5T_detect_class(dst->parent,H5T_VLEN)) {
/* Set up initial background buffer */
tmp_buf_size=MAX(src_base_size,dst_base_size);
- if ((tmp_buf=H5FL_BLK_ALLOC(vlen_seq,tmp_buf_size,1))==NULL)
+ if ((tmp_buf=H5FL_BLK_CALLOC(vlen_seq,tmp_buf_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
@@ -2340,13 +2340,6 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
} /* end if */
}
- /* Release the conversion buffer (always allocated) */
- H5FL_BLK_FREE(vlen_seq,conv_buf);
-
- /* Release the background buffer, if we have one */
- if(tmp_buf!=NULL)
- H5FL_BLK_FREE(vlen_seq,tmp_buf);
-
/* Release the temporary datatype IDs used */
if (tsrc_id >= 0)
H5I_dec_ref(tsrc_id);
@@ -2359,6 +2352,13 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
} /* end switch */
done:
+ /* Release the conversion buffer (always allocated, except on errors) */
+ if(conv_buf!=NULL)
+ H5FL_BLK_FREE(vlen_seq,conv_buf);
+ /* Release the background buffer, if we have one */
+ if(tmp_buf!=NULL)
+ H5FL_BLK_FREE(vlen_seq,tmp_buf);
+
FUNC_LEAVE (ret_value);
}
@@ -2407,8 +2407,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
* information that remains (almost) constant for this
* conversion path.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
assert (H5T_ARRAY==src->type);
assert (H5T_ARRAY==dst->type);
@@ -2438,8 +2438,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
/*
* Conversion.
*/
- if (NULL == (src = H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL == (dst = H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/*
@@ -2477,7 +2477,7 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
if(tpath->cdata.need_bkg) {
/* Allocate background buffer */
bkg_buf_size=src->u.array.nelem*MAX(src->size,dst->size);
- if ((bkg_buf=H5FL_BLK_ALLOC(array_seq,bkg_buf_size,0))==NULL)
+ if ((bkg_buf=H5FL_BLK_MALLOC(array_seq,bkg_buf_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
@@ -2560,8 +2560,8 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
switch (cdata->command) {
case H5T_CONV_INIT:
- if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src=H5I_object(src_id)) ||
+ NULL==(dst=H5I_object(dst_id)))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (H5T_ORDER_LE!=src->u.atomic.order &&
H5T_ORDER_BE!=src->u.atomic.order)
@@ -2579,8 +2579,8 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
case H5T_CONV_CONV:
/* Get the data types */
- if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src=H5I_object(src_id)) ||
+ NULL==(dst=H5I_object(dst_id)))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/*
@@ -2899,8 +2899,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
switch (cdata->command) {
case H5T_CONV_INIT:
- if (NULL==(src_p=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst_p=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src_p=H5I_object(src_id)) ||
+ NULL==(dst_p=H5I_object(dst_id)))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
src = src_p->u.atomic;
dst = dst_p->u.atomic;
@@ -2920,8 +2920,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
case H5T_CONV_CONV:
/* Get the data types */
- if (NULL==(src_p=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst_p=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src_p=H5I_object(src_id)) ||
+ NULL==(dst_p=H5I_object(dst_id)))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
src = src_p->u.atomic;
dst = dst_p->u.atomic;
@@ -3308,8 +3308,8 @@ H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
switch (cdata->command) {
case H5T_CONV_INIT:
- if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src=H5I_object(src_id)) ||
+ NULL==(dst=H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (8*src->size != src->u.atomic.prec || 8*dst->size != dst->u.atomic.prec)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision");
@@ -3328,8 +3328,8 @@ H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
case H5T_CONV_CONV:
/* Get the data types */
- if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dst=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(src=H5I_object(src_id)) ||
+ NULL==(dst=H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/*
@@ -6473,8 +6473,8 @@ H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
switch (cdata->command) {
case H5T_CONV_INIT:
cdata->need_bkg = H5T_BKG_NO;
- if (NULL==(st=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dt=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(st=H5I_object(src_id)) ||
+ NULL==(dt=H5I_object(dst_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to dereference data type object ID");
if (st->size!=sizeof(float) || dt->size!=sizeof(double))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "disagreement about data type size");
@@ -6593,8 +6593,8 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
switch (cdata->command) {
case H5T_CONV_INIT:
cdata->need_bkg = H5T_BKG_NO;
- if (NULL==(st=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==(dt=H5I_object_verify(dst_id,H5I_DATATYPE)))
+ if (NULL==(st=H5I_object(src_id)) ||
+ NULL==(dt=H5I_object(dst_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to dereference data type object ID");
if (st->size!=sizeof(double) || dt->size!=sizeof(float))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "disagreement about data type size");
@@ -6731,8 +6731,8 @@ H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
case H5T_CONV_CONV:
/* The conversion */
- if (NULL==(src=H5I_object_verify(src_id,H5I_DATATYPE)) ||
- NULL==H5I_object_verify(dst_id,H5I_DATATYPE))
+ if (NULL==(src=H5I_object(src_id)) ||
+ NULL==H5I_object(dst_id))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
s = (uint8_t*)buf + (buf_stride?buf_stride:4)*(nelmts-1);
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index d9f4520..7491749 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -101,6 +101,7 @@ H5_DLL H5T_t *H5T_create(H5T_class_t type, size_t size);
H5_DLL H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method);
H5_DLL herr_t H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type);
H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable);
+H5_DLL herr_t H5T_free(H5T_t *dt);
H5_DLL herr_t H5T_close(H5T_t *dt);
H5_DLL herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src,
H5T_t *dst, H5T_conv_t func);
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 2bfc7da..a96d2bb 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -196,13 +196,21 @@ typedef herr_t (*H5T_overflow_t)(hid_t src_id, hid_t dst_id,
extern "C" {
#endif
+/* When this header is included from H5Tprivate.h, don't make calls to H5open() */
+#undef H5OPEN
+#ifndef _H5Tprivate_H
+#define H5OPEN H5open(),
+#else /* _H5Tprivate_H */
+#define H5OPEN
+#endif /* _H5Tprivate_H */
+
/*
* The IEEE floating point types in various byte orders.
*/
-#define H5T_IEEE_F32BE (H5open(), H5T_IEEE_F32BE_g)
-#define H5T_IEEE_F32LE (H5open(), H5T_IEEE_F32LE_g)
-#define H5T_IEEE_F64BE (H5open(), H5T_IEEE_F64BE_g)
-#define H5T_IEEE_F64LE (H5open(), H5T_IEEE_F64LE_g)
+#define H5T_IEEE_F32BE (H5OPEN H5T_IEEE_F32BE_g)
+#define H5T_IEEE_F32LE (H5OPEN H5T_IEEE_F32LE_g)
+#define H5T_IEEE_F64BE (H5OPEN H5T_IEEE_F64BE_g)
+#define H5T_IEEE_F64LE (H5OPEN H5T_IEEE_F64LE_g)
H5_DLLVAR hid_t H5T_IEEE_F32BE_g;
H5_DLLVAR hid_t H5T_IEEE_F32LE_g;
H5_DLLVAR hid_t H5T_IEEE_F64BE_g;
@@ -212,32 +220,32 @@ H5_DLLVAR hid_t H5T_IEEE_F64LE_g;
* These are "standard" types. For instance, signed (2's complement) and
* unsigned integers of various sizes and byte orders.
*/
-#define H5T_STD_I8BE (H5open(), H5T_STD_I8BE_g)
-#define H5T_STD_I8LE (H5open(), H5T_STD_I8LE_g)
-#define H5T_STD_I16BE (H5open(), H5T_STD_I16BE_g)
-#define H5T_STD_I16LE (H5open(), H5T_STD_I16LE_g)
-#define H5T_STD_I32BE (H5open(), H5T_STD_I32BE_g)
-#define H5T_STD_I32LE (H5open(), H5T_STD_I32LE_g)
-#define H5T_STD_I64BE (H5open(), H5T_STD_I64BE_g)
-#define H5T_STD_I64LE (H5open(), H5T_STD_I64LE_g)
-#define H5T_STD_U8BE (H5open(), H5T_STD_U8BE_g)
-#define H5T_STD_U8LE (H5open(), H5T_STD_U8LE_g)
-#define H5T_STD_U16BE (H5open(), H5T_STD_U16BE_g)
-#define H5T_STD_U16LE (H5open(), H5T_STD_U16LE_g)
-#define H5T_STD_U32BE (H5open(), H5T_STD_U32BE_g)
-#define H5T_STD_U32LE (H5open(), H5T_STD_U32LE_g)
-#define H5T_STD_U64BE (H5open(), H5T_STD_U64BE_g)
-#define H5T_STD_U64LE (H5open(), H5T_STD_U64LE_g)
-#define H5T_STD_B8BE (H5open(), H5T_STD_B8BE_g)
-#define H5T_STD_B8LE (H5open(), H5T_STD_B8LE_g)
-#define H5T_STD_B16BE (H5open(), H5T_STD_B16BE_g)
-#define H5T_STD_B16LE (H5open(), H5T_STD_B16LE_g)
-#define H5T_STD_B32BE (H5open(), H5T_STD_B32BE_g)
-#define H5T_STD_B32LE (H5open(), H5T_STD_B32LE_g)
-#define H5T_STD_B64BE (H5open(), H5T_STD_B64BE_g)
-#define H5T_STD_B64LE (H5open(), H5T_STD_B64LE_g)
-#define H5T_STD_REF_OBJ (H5open(), H5T_STD_REF_OBJ_g)
-#define H5T_STD_REF_DSETREG (H5open(), H5T_STD_REF_DSETREG_g)
+#define H5T_STD_I8BE (H5OPEN H5T_STD_I8BE_g)
+#define H5T_STD_I8LE (H5OPEN H5T_STD_I8LE_g)
+#define H5T_STD_I16BE (H5OPEN H5T_STD_I16BE_g)
+#define H5T_STD_I16LE (H5OPEN H5T_STD_I16LE_g)
+#define H5T_STD_I32BE (H5OPEN H5T_STD_I32BE_g)
+#define H5T_STD_I32LE (H5OPEN H5T_STD_I32LE_g)
+#define H5T_STD_I64BE (H5OPEN H5T_STD_I64BE_g)
+#define H5T_STD_I64LE (H5OPEN H5T_STD_I64LE_g)
+#define H5T_STD_U8BE (H5OPEN H5T_STD_U8BE_g)
+#define H5T_STD_U8LE (H5OPEN H5T_STD_U8LE_g)
+#define H5T_STD_U16BE (H5OPEN H5T_STD_U16BE_g)
+#define H5T_STD_U16LE (H5OPEN H5T_STD_U16LE_g)
+#define H5T_STD_U32BE (H5OPEN H5T_STD_U32BE_g)
+#define H5T_STD_U32LE (H5OPEN H5T_STD_U32LE_g)
+#define H5T_STD_U64BE (H5OPEN H5T_STD_U64BE_g)
+#define H5T_STD_U64LE (H5OPEN H5T_STD_U64LE_g)
+#define H5T_STD_B8BE (H5OPEN H5T_STD_B8BE_g)
+#define H5T_STD_B8LE (H5OPEN H5T_STD_B8LE_g)
+#define H5T_STD_B16BE (H5OPEN H5T_STD_B16BE_g)
+#define H5T_STD_B16LE (H5OPEN H5T_STD_B16LE_g)
+#define H5T_STD_B32BE (H5OPEN H5T_STD_B32BE_g)
+#define H5T_STD_B32LE (H5OPEN H5T_STD_B32LE_g)
+#define H5T_STD_B64BE (H5OPEN H5T_STD_B64BE_g)
+#define H5T_STD_B64LE (H5OPEN H5T_STD_B64LE_g)
+#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g)
+#define H5T_STD_REF_DSETREG (H5OPEN H5T_STD_REF_DSETREG_g)
H5_DLLVAR hid_t H5T_STD_I8BE_g;
H5_DLLVAR hid_t H5T_STD_I8LE_g;
H5_DLLVAR hid_t H5T_STD_I16BE_g;
@@ -268,10 +276,10 @@ H5_DLLVAR hid_t H5T_STD_REF_DSETREG_g;
/*
* Types which are particular to Unix.
*/
-#define H5T_UNIX_D32BE (H5open(), H5T_UNIX_D32BE_g)
-#define H5T_UNIX_D32LE (H5open(), H5T_UNIX_D32LE_g)
-#define H5T_UNIX_D64BE (H5open(), H5T_UNIX_D64BE_g)
-#define H5T_UNIX_D64LE (H5open(), H5T_UNIX_D64LE_g)
+#define H5T_UNIX_D32BE (H5OPEN H5T_UNIX_D32BE_g)
+#define H5T_UNIX_D32LE (H5OPEN H5T_UNIX_D32LE_g)
+#define H5T_UNIX_D64BE (H5OPEN H5T_UNIX_D64BE_g)
+#define H5T_UNIX_D64LE (H5OPEN H5T_UNIX_D64LE_g)
H5_DLLVAR hid_t H5T_UNIX_D32BE_g;
H5_DLLVAR hid_t H5T_UNIX_D32LE_g;
H5_DLLVAR hid_t H5T_UNIX_D64BE_g;
@@ -281,13 +289,13 @@ H5_DLLVAR hid_t H5T_UNIX_D64LE_g;
* Types particular to the C language. String types use `bytes' instead
* of `bits' as their size.
*/
-#define H5T_C_S1 (H5open(), H5T_C_S1_g)
+#define H5T_C_S1 (H5OPEN H5T_C_S1_g)
H5_DLLVAR hid_t H5T_C_S1_g;
/*
* Types particular to Fortran.
*/
-#define H5T_FORTRAN_S1 (H5open(), H5T_FORTRAN_S1_g)
+#define H5T_FORTRAN_S1 (H5OPEN H5T_FORTRAN_S1_g)
H5_DLLVAR hid_t H5T_FORTRAN_S1_g;
/*
@@ -357,29 +365,29 @@ H5_DLLVAR hid_t H5T_FORTRAN_S1_g;
* same as `LONG' and `DOUBLE' respectively.
*/
#define H5T_NATIVE_CHAR (CHAR_MIN?H5T_NATIVE_SCHAR:H5T_NATIVE_UCHAR)
-#define H5T_NATIVE_SCHAR (H5open(), H5T_NATIVE_SCHAR_g)
-#define H5T_NATIVE_UCHAR (H5open(), H5T_NATIVE_UCHAR_g)
-#define H5T_NATIVE_SHORT (H5open(), H5T_NATIVE_SHORT_g)
-#define H5T_NATIVE_USHORT (H5open(), H5T_NATIVE_USHORT_g)
-#define H5T_NATIVE_INT (H5open(), H5T_NATIVE_INT_g)
-#define H5T_NATIVE_UINT (H5open(), H5T_NATIVE_UINT_g)
-#define H5T_NATIVE_LONG (H5open(), H5T_NATIVE_LONG_g)
-#define H5T_NATIVE_ULONG (H5open(), H5T_NATIVE_ULONG_g)
-#define H5T_NATIVE_LLONG (H5open(), H5T_NATIVE_LLONG_g)
-#define H5T_NATIVE_ULLONG (H5open(), H5T_NATIVE_ULLONG_g)
-#define H5T_NATIVE_FLOAT (H5open(), H5T_NATIVE_FLOAT_g)
-#define H5T_NATIVE_DOUBLE (H5open(), H5T_NATIVE_DOUBLE_g)
-#define H5T_NATIVE_LDOUBLE (H5open(), H5T_NATIVE_LDOUBLE_g)
-#define H5T_NATIVE_B8 (H5open(), H5T_NATIVE_B8_g)
-#define H5T_NATIVE_B16 (H5open(), H5T_NATIVE_B16_g)
-#define H5T_NATIVE_B32 (H5open(), H5T_NATIVE_B32_g)
-#define H5T_NATIVE_B64 (H5open(), H5T_NATIVE_B64_g)
-#define H5T_NATIVE_OPAQUE (H5open(), H5T_NATIVE_OPAQUE_g)
-#define H5T_NATIVE_HADDR (H5open(), H5T_NATIVE_HADDR_g)
-#define H5T_NATIVE_HSIZE (H5open(), H5T_NATIVE_HSIZE_g)
-#define H5T_NATIVE_HSSIZE (H5open(), H5T_NATIVE_HSSIZE_g)
-#define H5T_NATIVE_HERR (H5open(), H5T_NATIVE_HERR_g)
-#define H5T_NATIVE_HBOOL (H5open(), H5T_NATIVE_HBOOL_g)
+#define H5T_NATIVE_SCHAR (H5OPEN H5T_NATIVE_SCHAR_g)
+#define H5T_NATIVE_UCHAR (H5OPEN H5T_NATIVE_UCHAR_g)
+#define H5T_NATIVE_SHORT (H5OPEN H5T_NATIVE_SHORT_g)
+#define H5T_NATIVE_USHORT (H5OPEN H5T_NATIVE_USHORT_g)
+#define H5T_NATIVE_INT (H5OPEN H5T_NATIVE_INT_g)
+#define H5T_NATIVE_UINT (H5OPEN H5T_NATIVE_UINT_g)
+#define H5T_NATIVE_LONG (H5OPEN H5T_NATIVE_LONG_g)
+#define H5T_NATIVE_ULONG (H5OPEN H5T_NATIVE_ULONG_g)
+#define H5T_NATIVE_LLONG (H5OPEN H5T_NATIVE_LLONG_g)
+#define H5T_NATIVE_ULLONG (H5OPEN H5T_NATIVE_ULLONG_g)
+#define H5T_NATIVE_FLOAT (H5OPEN H5T_NATIVE_FLOAT_g)
+#define H5T_NATIVE_DOUBLE (H5OPEN H5T_NATIVE_DOUBLE_g)
+#define H5T_NATIVE_LDOUBLE (H5OPEN H5T_NATIVE_LDOUBLE_g)
+#define H5T_NATIVE_B8 (H5OPEN H5T_NATIVE_B8_g)
+#define H5T_NATIVE_B16 (H5OPEN H5T_NATIVE_B16_g)
+#define H5T_NATIVE_B32 (H5OPEN H5T_NATIVE_B32_g)
+#define H5T_NATIVE_B64 (H5OPEN H5T_NATIVE_B64_g)
+#define H5T_NATIVE_OPAQUE (H5OPEN H5T_NATIVE_OPAQUE_g)
+#define H5T_NATIVE_HADDR (H5OPEN H5T_NATIVE_HADDR_g)
+#define H5T_NATIVE_HSIZE (H5OPEN H5T_NATIVE_HSIZE_g)
+#define H5T_NATIVE_HSSIZE (H5OPEN H5T_NATIVE_HSSIZE_g)
+#define H5T_NATIVE_HERR (H5OPEN H5T_NATIVE_HERR_g)
+#define H5T_NATIVE_HBOOL (H5OPEN H5T_NATIVE_HBOOL_g)
H5_DLLVAR hid_t H5T_NATIVE_SCHAR_g;
H5_DLLVAR hid_t H5T_NATIVE_UCHAR_g;
H5_DLLVAR hid_t H5T_NATIVE_SHORT_g;
@@ -405,12 +413,12 @@ H5_DLLVAR hid_t H5T_NATIVE_HERR_g;
H5_DLLVAR hid_t H5T_NATIVE_HBOOL_g;
/* C9x integer types */
-#define H5T_NATIVE_INT8 (H5open(), H5T_NATIVE_INT8_g)
-#define H5T_NATIVE_UINT8 (H5open(), H5T_NATIVE_UINT8_g)
-#define H5T_NATIVE_INT_LEAST8 (H5open(), H5T_NATIVE_INT_LEAST8_g)
-#define H5T_NATIVE_UINT_LEAST8 (H5open(), H5T_NATIVE_UINT_LEAST8_g)
-#define H5T_NATIVE_INT_FAST8 (H5open(), H5T_NATIVE_INT_FAST8_g)
-#define H5T_NATIVE_UINT_FAST8 (H5open(), H5T_NATIVE_UINT_FAST8_g)
+#define H5T_NATIVE_INT8 (H5OPEN H5T_NATIVE_INT8_g)
+#define H5T_NATIVE_UINT8 (H5OPEN H5T_NATIVE_UINT8_g)
+#define H5T_NATIVE_INT_LEAST8 (H5OPEN H5T_NATIVE_INT_LEAST8_g)
+#define H5T_NATIVE_UINT_LEAST8 (H5OPEN H5T_NATIVE_UINT_LEAST8_g)
+#define H5T_NATIVE_INT_FAST8 (H5OPEN H5T_NATIVE_INT_FAST8_g)
+#define H5T_NATIVE_UINT_FAST8 (H5OPEN H5T_NATIVE_UINT_FAST8_g)
H5_DLLVAR hid_t H5T_NATIVE_INT8_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT8_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST8_g;
@@ -418,12 +426,12 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_LEAST8_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_FAST8_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST8_g;
-#define H5T_NATIVE_INT16 (H5open(), H5T_NATIVE_INT16_g)
-#define H5T_NATIVE_UINT16 (H5open(), H5T_NATIVE_UINT16_g)
-#define H5T_NATIVE_INT_LEAST16 (H5open(), H5T_NATIVE_INT_LEAST16_g)
-#define H5T_NATIVE_UINT_LEAST16 (H5open(), H5T_NATIVE_UINT_LEAST16_g)
-#define H5T_NATIVE_INT_FAST16 (H5open(), H5T_NATIVE_INT_FAST16_g)
-#define H5T_NATIVE_UINT_FAST16 (H5open(), H5T_NATIVE_UINT_FAST16_g)
+#define H5T_NATIVE_INT16 (H5OPEN H5T_NATIVE_INT16_g)
+#define H5T_NATIVE_UINT16 (H5OPEN H5T_NATIVE_UINT16_g)
+#define H5T_NATIVE_INT_LEAST16 (H5OPEN H5T_NATIVE_INT_LEAST16_g)
+#define H5T_NATIVE_UINT_LEAST16 (H5OPEN H5T_NATIVE_UINT_LEAST16_g)
+#define H5T_NATIVE_INT_FAST16 (H5OPEN H5T_NATIVE_INT_FAST16_g)
+#define H5T_NATIVE_UINT_FAST16 (H5OPEN H5T_NATIVE_UINT_FAST16_g)
H5_DLLVAR hid_t H5T_NATIVE_INT16_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT16_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST16_g;
@@ -431,12 +439,12 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_LEAST16_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_FAST16_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST16_g;
-#define H5T_NATIVE_INT32 (H5open(), H5T_NATIVE_INT32_g)
-#define H5T_NATIVE_UINT32 (H5open(), H5T_NATIVE_UINT32_g)
-#define H5T_NATIVE_INT_LEAST32 (H5open(), H5T_NATIVE_INT_LEAST32_g)
-#define H5T_NATIVE_UINT_LEAST32 (H5open(), H5T_NATIVE_UINT_LEAST32_g)
-#define H5T_NATIVE_INT_FAST32 (H5open(), H5T_NATIVE_INT_FAST32_g)
-#define H5T_NATIVE_UINT_FAST32 (H5open(), H5T_NATIVE_UINT_FAST32_g)
+#define H5T_NATIVE_INT32 (H5OPEN H5T_NATIVE_INT32_g)
+#define H5T_NATIVE_UINT32 (H5OPEN H5T_NATIVE_UINT32_g)
+#define H5T_NATIVE_INT_LEAST32 (H5OPEN H5T_NATIVE_INT_LEAST32_g)
+#define H5T_NATIVE_UINT_LEAST32 (H5OPEN H5T_NATIVE_UINT_LEAST32_g)
+#define H5T_NATIVE_INT_FAST32 (H5OPEN H5T_NATIVE_INT_FAST32_g)
+#define H5T_NATIVE_UINT_FAST32 (H5OPEN H5T_NATIVE_UINT_FAST32_g)
H5_DLLVAR hid_t H5T_NATIVE_INT32_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT32_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST32_g;
@@ -444,12 +452,12 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_LEAST32_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_FAST32_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST32_g;
-#define H5T_NATIVE_INT64 (H5open(), H5T_NATIVE_INT64_g)
-#define H5T_NATIVE_UINT64 (H5open(), H5T_NATIVE_UINT64_g)
-#define H5T_NATIVE_INT_LEAST64 (H5open(), H5T_NATIVE_INT_LEAST64_g)
-#define H5T_NATIVE_UINT_LEAST64 (H5open(), H5T_NATIVE_UINT_LEAST64_g)
-#define H5T_NATIVE_INT_FAST64 (H5open(), H5T_NATIVE_INT_FAST64_g)
-#define H5T_NATIVE_UINT_FAST64 (H5open(), H5T_NATIVE_UINT_FAST64_g)
+#define H5T_NATIVE_INT64 (H5OPEN H5T_NATIVE_INT64_g)
+#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g)
+#define H5T_NATIVE_INT_LEAST64 (H5OPEN H5T_NATIVE_INT_LEAST64_g)
+#define H5T_NATIVE_UINT_LEAST64 (H5OPEN H5T_NATIVE_UINT_LEAST64_g)
+#define H5T_NATIVE_INT_FAST64 (H5OPEN H5T_NATIVE_INT_FAST64_g)
+#define H5T_NATIVE_UINT_FAST64 (H5OPEN H5T_NATIVE_UINT_FAST64_g)
H5_DLLVAR hid_t H5T_NATIVE_INT64_g;
H5_DLLVAR hid_t H5T_NATIVE_UINT64_g;
H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST64_g;
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index b8a4a25..145fc3b 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -232,10 +232,6 @@ H5T_vlen_seq_mem_write(hid_t plist_id, H5F_t UNUSED *f, void *vl_addr, void *buf
/* Use the user's memory allocation routine is one is defined */
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == plist_id)
- plist_id= H5P_DATASET_XFER_DEFAULT;
-
/* Get the allocation function & info */
if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
@@ -367,10 +363,6 @@ H5T_vlen_str_mem_write(hid_t plist_id, H5F_t UNUSED *f, void *vl_addr, void *buf
/* Use the user's memory allocation routine if one is defined */
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == plist_id)
- plist_id= H5P_DATASET_XFER_DEFAULT;
-
/* Get the allocation function & info */
if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
@@ -706,10 +698,6 @@ H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t UNUSED
if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == plist_id)
- plist_id= H5P_DATASET_XFER_DEFAULT;
-
/* Get the free func & information */
if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
diff --git a/src/H5detect.c b/src/H5detect.c
index 0d19208..39ee57b 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -495,7 +495,7 @@ H5TN_init_interface(void)\n\
/* The part common to fixed and floating types */
printf("\
- if (NULL==(dt = H5FL_ALLOC (H5T_t,1)))\n\
+ if (NULL==(dt = H5FL_CALLOC (H5T_t)))\n\
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,\"memory allocation failed\");\n\
dt->state = H5T_STATE_IMMUTABLE;\n\
dt->ent.header = HADDR_UNDEF;\n\
diff --git a/src/Makefile.in b/src/Makefile.in
index 1d4f82f..76b7152 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -32,13 +32,14 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcontig.c \
H5Fcompact.c H5Fistore.c H5Fseq.c H5FD.c H5FDcore.c H5FDfamily.c \
H5FDgass.c H5FDlog.c H5FDmpio.c H5FDmpiposix.c H5FDmulti.c H5FDsec2.c \
H5FDsrb.c H5FDstdio.c H5FDstream.c H5FL.c H5FP.c H5FPclient.c \
- H5FPserver.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c \
- H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c \
+ H5FO.c H5FPserver.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c \
+ H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocont.c H5Odtype.c H5Oefl.c \
H5Ofill.c H5Ofphdf5.c H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c \
- H5Oplist.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c \
- H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5R.c H5S.c H5Sall.c H5Shyper.c \
- H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5T.c H5Tbit.c H5Tconv.c \
- H5Tinit.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c H5Zdeflate.c H5Zshuffle.c
+ H5Opline.c H5Oplist.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c \
+ H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5R.c H5RS.c H5S.c H5Sall.c \
+ H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5ST.c H5T.c \
+ H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c \
+ H5Zdeflate.c H5Zshuffle.c
LIB_OBJ=$(LIB_SRC:.c=.lo)
@@ -47,7 +48,7 @@ MOSTLYCLEAN=H5detect.o H5detect.lo H5detect H5Tinit.o H5Tinit.lo H5Tinit.c
## Public header files (to be installed)...
PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \
- H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDfamily.h \
+ H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDfamily.h \
H5FDgass.h H5FDlog.h H5FDmpio.h H5FDmpiposix.h H5FDmulti.h H5FDsec2.h \
H5FDsrb.h H5FDstdio.h H5FDstream.h H5FPpublic.h H5Gpublic.h \
H5HGpublic.h H5HLpublic.h H5Ipublic.h H5MMpublic.h H5Opublic.h \
@@ -57,11 +58,12 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \
## Other header files (not to be installed)...
PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h \
- H5FLprivate.h H5FPprivate.h H5Gprivate.h H5Gpkg.h H5HGprivate.h \
- H5HLprivate.h H5Iprivate.h H5MFprivate.h H5MMprivate.h \
- H5Oprivate.h H5Pprivate.h H5Ppkg.h H5Rprivate.h H5Sprivate.h \
- H5Tprivate.h H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h \
- H5Zprivate.h H5config.h
+ H5FLprivate.h H5FOprivate.h H5FPprivate.h H5Gprivate.h H5Gpkg.h \
+ H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h \
+ H5MMprivate.h H5Oprivate.h H5Pprivate.h H5Ppkg.h H5Rprivate.h \
+ H5RSprivate.h H5Sprivate.h H5STprivate.h H5Tprivate.h \
+ H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h H5Zprivate.h \
+ H5config.h
## Number format detection
## The LD_LIBRARY_PATH setting is a klutch.
diff --git a/test/Makefile.in b/test/Makefile.in
index 0ea2fa5..860c4cc 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -65,11 +65,12 @@ TEST_SRC=big.c bittests.c cmpd_dset.c dsets.c dtypes.c extend.c \
external.c fillval.c flush1.c flush2.c gheap.c h5test.c hyperslab.c \
istore.c lheap.c links.c mount.c mtime.c ohdr.c stab.c tarray.c \
tattr.c tconfig.c testhdf5.c testmeta.c tfile.c tgenprop.c th5s.c \
- titerate.c tmeta.c trefer.c tselect.c ttime.c ttbbt.c tvltypes.c \
- tvlstr.c tmisc.c unlink.c enum.c ttsafe.c ttsafe_dcreate.c \
- ttsafe_error.c ttsafe_cancel.c ttsafe_acreate.c gass_write.c \
- gass_read.c gass_append.c srb_read.c srb_write.c srb_append.c \
- stream_test.c set_extent.c getname.c file_handle.c ntypes.c
+ titerate.c tmeta.c trefer.c trefstr.c tselect.c ttime.c ttbbt.c \
+ ttst.c tvltypes.c tvlstr.c tmisc.c unlink.c enum.c ttsafe.c \
+ ttsafe_dcreate.c ttsafe_error.c ttsafe_cancel.c ttsafe_acreate.c \
+ gass_write.c gass_read.c gass_append.c srb_read.c srb_write.c \
+ srb_append.c stream_test.c set_extent.c getname.c file_handle.c \
+ ntypes.c
TEST_OBJ=$(TEST_SRC:.c=.lo)
@@ -90,8 +91,8 @@ timings _timings: $(TIMINGS)
$(TEST_PROGS): $(LIB) $(LIBHDF5)
TESTHDF5_OBJ=testhdf5.lo tarray.lo tattr.lo tconfig.lo tfile.lo tgenprop.lo \
- th5s.lo titerate.lo tmeta.lo ttime.lo trefer.lo tselect.lo ttbbt.lo \
- tvltypes.lo tvlstr.lo tmisc.lo
+ th5s.lo titerate.lo tmeta.lo ttime.lo trefer.lo trefstr.lo tselect.lo \
+ ttbbt.lo ttst.lo tvltypes.lo tvlstr.lo tmisc.lo
TTS_OBJ=ttsafe.lo ttsafe_dcreate.lo ttsafe_error.lo ttsafe_cancel.lo \
ttsafe_acreate.lo
diff --git a/test/dsets.c b/test/dsets.c
index 3a7e561..e41748e 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -327,9 +327,8 @@ test_userblock_offset(hid_t fapl)
{
char filename[32];
hid_t file, fcpl, dataset, space;
- int i, j, n;
+ int i, j;
hsize_t dims[2];
-/* FILE *f;*/
int f;
haddr_t offset;
int rdata[100][200];
@@ -339,19 +338,11 @@ test_userblock_offset(hid_t fapl)
h5_fixname(FILENAME[2], fapl, filename, sizeof filename);
if((fcpl=H5Pcreate(H5P_FILE_CREATE))<0) goto error;
- if(H5Pset_userblock(fcpl, USER_BLOCK)<0) goto error;
+ if(H5Pset_userblock(fcpl, (hsize_t)USER_BLOCK)<0) goto error;
- if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl))<0) {
+ if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl))<0)
goto error;
- }
- /* Initialize the dataset */
- /*for (i = n = 0; i < 100; i++) {
- for (j = 0; j < 200; j++) {
- points[i][j] = n++;
- }
- }*/
-
/* Create the data space */
dims[0] = 100;
dims[1] = 200;
diff --git a/test/fillval.c b/test/fillval.c
index 587999a..d15bfc5 100644
--- a/test/fillval.c
+++ b/test/fillval.c
@@ -1264,7 +1264,7 @@ test_compatible(void)
char *srcdir = getenv("srcdir"); /*where the src code is located*/
char testfile[512]=""; /* test file name */
- TESTING("contiguous dataset compatibility with v. 1.5");
+ TESTING("contiguous dataset compatibility with v. 1.4");
/* Generate correct name for test file by prepending the source path */
if(srcdir && ((strlen(srcdir) + strlen(FILE_COMPATIBLE) + 1) <
diff --git a/test/gen_new_mtime.c b/test/gen_new_mtime.c
new file mode 100644
index 0000000..1bf1ef9
--- /dev/null
+++ b/test/gen_new_mtime.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Friday, January 3, 2003
+ *
+ * Purpose: Create a dataset, which should have the newer mtime information
+ * stored in it.
+ * This program is used to create the test file `tmtimen.h5' which
+ * has the new format for mtime information.
+ * To build the test file, this program MUST be compiled and linked with
+ * the hdf5-1.5+ series of libraries and the generated test file must be
+ * put into the 'test' directory in the 1.5+ branch of the library.
+ */
+
+#include "hdf5.h"
+
+#define TESTFILE "tmtimen.h5"
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose:
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Quincey Koziol
+ * Friday, January 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(void)
+{
+ hid_t file, space, dset;
+
+ /* Create the file */
+ file = H5Fcreate(TESTFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ if(file<0)
+ printf("file<0!\n");
+
+ /* Create the dataspace (for dataset) */
+ space = H5Screate(H5S_SCALAR);
+ if(space<0)
+ printf("space<0!\n");
+
+ /* Create the dataset with compound array fields */
+ dset = H5Dcreate(file, "Dataset1", H5T_NATIVE_INT, space, H5P_DEFAULT);
+ if(dset<0)
+ printf("dset<0!\n");
+
+ H5Dclose(dset);
+ H5Sclose(space);
+ H5Fclose(file);
+
+ return 0;
+}
+
+
diff --git a/test/gen_old_mtime.c b/test/gen_old_mtime.c
new file mode 100644
index 0000000..b9a8186
--- /dev/null
+++ b/test/gen_old_mtime.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2003 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Friday, January 3, 2003
+ *
+ * Purpose: Create a dataset, which should have the older mtime information
+ * stored in it.
+ * This program is used to create the test file `tmtimeo.h5' which
+ * has the new format for mtime information.
+ * To build the test file, this program MUST be compiled and linked with
+ * the hdf5-1.4+ series of libraries and the generated test file must be
+ * put into the 'test' directory in the 1.5+ branch of the library.
+ */
+
+#include "hdf5.h"
+
+#define TESTFILE "tmtimeo.h5"
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose:
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Quincey Koziol
+ * Friday, January 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(void)
+{
+ hid_t file, space, dset;
+
+ /* Create the file */
+ file = H5Fcreate(TESTFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ if(file<0)
+ printf("file<0!\n");
+
+ /* Create the dataspace (for dataset) */
+ space = H5Screate(H5S_SCALAR);
+ if(space<0)
+ printf("space<0!\n");
+
+ /* Create the dataset with compound array fields */
+ dset = H5Dcreate(file, "Dataset1", H5T_NATIVE_INT, space, H5P_DEFAULT);
+ if(dset<0)
+ printf("dset<0!\n");
+
+ H5Dclose(dset);
+ H5Sclose(space);
+ H5Fclose(file);
+
+ return 0;
+}
+
+
+
diff --git a/test/istore.c b/test/istore.c
index e79754a..3dfb8cf 100644
--- a/test/istore.c
+++ b/test/istore.c
@@ -100,6 +100,7 @@ new_object(H5F_t *f, const char *name, unsigned ndims, H5G_entry_t *ent/*out*/)
unsigned u;
/* Create the object header */
+ HDmemset(ent,0,sizeof(H5G_entry_t));
if (H5O_create(f, 64, ent)) {
H5_FAILED();
puts(" H5O_create() = NULL");
@@ -118,7 +119,7 @@ new_object(H5F_t *f, const char *name, unsigned ndims, H5G_entry_t *ent/*out*/)
}
/* Create the root of the B-tree that describes chunked storage */
H5F_istore_create (f, &layout/*in,out*/);
- if (H5O_modify(ent, H5O_LAYOUT, H5O_NEW_MESG, 0, &layout) < 0) {
+ if (H5O_modify(ent, H5O_LAYOUT, H5O_NEW_MESG, 0, 1, &layout) < 0) {
H5_FAILED();
puts(" H5O_modify istore message failure.");
goto error;
diff --git a/test/mtime.c b/test/mtime.c
index 55e0c21..b94cadf 100644
--- a/test/mtime.c
+++ b/test/mtime.c
@@ -17,6 +17,11 @@ const char *FILENAME[] = {
NULL
};
+#define TESTFILE1 "tmtimeo.h5"
+#define MTIME1 1041605080
+#define TESTFILE2 "tmtimen.h5"
+#define MTIME2 1041606478
+
/*-------------------------------------------------------------------------
* Function: main
@@ -31,6 +36,11 @@ const char *FILENAME[] = {
* Thursday, July 30, 1998
*
* Modifications:
+ * Added checks for old and new modification time messages
+ * in pre-created datafiles (generated with gen_old_mtime.c and
+ * gen_new_mtime.c).
+ * Quincey Koziol
+ * Friday, January 3, 2003
*
*-------------------------------------------------------------------------
*/
@@ -101,9 +111,65 @@ main(void)
printf(" got: %s\n ans: %s\n", buf1, buf2);
return 1;
}
+ PASSED();
- /* All looks good */
+ /* Check opening existing file with old-style modification time information
+ * and make certain that the time is correct
+ */
+ TESTING("accessing old modification time messages");
+
+ {
+ char testfile[512]="";
+ char *srcdir = HDgetenv("srcdir");
+ if (srcdir && ((HDstrlen(srcdir) + strlen(TESTFILE1) + 1) < sizeof(testfile))){
+ HDstrcpy(testfile, srcdir);
+ HDstrcat(testfile, "/");
+ }
+ HDstrcat(testfile, TESTFILE1);
+ file = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT);
+ if (file >= 0){
+ if(H5Gget_objinfo(file, "/Dataset1", TRUE, &sb1)<0)
+ return 1;
+ if(sb1.mtime!=MTIME1) return 1;
+ if (H5Fclose(file)<0) return 1;
+ }
+ else {
+ printf("***cannot open the pre-created old modification test file (%s)\n",
+ testfile);
+ return 1;
+ } /* end else */
+ }
PASSED();
+
+ /* Check opening existing file with new-style modification time information
+ * and make certain that the time is correct
+ */
+ TESTING("accessing new modification time messages");
+
+ {
+ char testfile[512]="";
+ char *srcdir = HDgetenv("srcdir");
+ if (srcdir && ((HDstrlen(srcdir) + strlen(TESTFILE2) + 1) < sizeof(testfile))){
+ HDstrcpy(testfile, srcdir);
+ HDstrcat(testfile, "/");
+ }
+ HDstrcat(testfile, TESTFILE2);
+ file = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT);
+ if (file >= 0){
+ if(H5Gget_objinfo(file, "/Dataset1", TRUE, &sb2)<0)
+ return 1;
+ if(sb2.mtime!=MTIME2) return 1;
+ if (H5Fclose(file)<0) return 1;
+ }
+ else {
+ printf("***cannot open the pre-created old modification test file (%s)\n",
+ testfile);
+ return 1;
+ } /* end else */
+ }
+ PASSED();
+
+ /* All looks good */
puts("All modification time tests passed.");
h5_cleanup(FILENAME, fapl);
return 0;
diff --git a/test/ntypes.c b/test/ntypes.c
index 69d56c9..fcdd9fb 100644
--- a/test/ntypes.c
+++ b/test/ntypes.c
@@ -1503,7 +1503,6 @@ test_refer_dtype2(hid_t file)
*drbuf; /* Buffer for reading numeric data from disk */
uint8_t *tu8; /* Temporary pointer to uint8 data */
int i; /* counting variables */
- herr_t ret; /* Generic return value */
/* Output message about test being performed */
TESTING("dataset region reference");
diff --git a/test/ohdr.c b/test/ohdr.c
index 69d7f10..ddd4ed6 100644
--- a/test/ohdr.c
+++ b/test/ohdr.c
@@ -62,6 +62,7 @@ main(void)
* Test object header creation
*/
TESTING("object header creation");
+ HDmemset(&oh_ent,0,sizeof(H5G_entry_t));
if (H5O_create(f, 64, &oh_ent/*out*/)<0) {
H5_FAILED();
H5Eprint(stdout);
@@ -73,7 +74,7 @@ main(void)
TESTING("message creation");
stab.btree_addr = 11111111;
stab.heap_addr = 22222222;
- if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, &stab)<0) {
+ if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, 1, &stab)<0) {
H5_FAILED();
H5Eprint(stdout);
goto error;
@@ -105,7 +106,7 @@ main(void)
TESTING("message modification");
stab.btree_addr = 33333333;
stab.heap_addr = 44444444;
- if (H5O_modify(&oh_ent, H5O_STAB, 0, 0, &stab)<0) {
+ if (H5O_modify(&oh_ent, H5O_STAB, 0, 0, 1, &stab)<0) {
H5_FAILED();
H5Eprint(stdout);
goto error;
@@ -138,7 +139,7 @@ main(void)
TESTING("duplicate message creation");
stab.btree_addr = 55555555;
stab.heap_addr = 66666666;
- if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, &stab)<0) {
+ if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, 1, &stab)<0) {
H5_FAILED();
H5Eprint(stdout);
goto error;
@@ -170,7 +171,7 @@ main(void)
TESTING("duplicate message modification");
stab.btree_addr = 77777777;
stab.heap_addr = 88888888;
- if (H5O_modify(&oh_ent, H5O_STAB, 1, 0, &stab)<0) {
+ if (H5O_modify(&oh_ent, H5O_STAB, 1, 0, 1, &stab)<0) {
H5_FAILED();
H5Eprint(stdout);
goto error;
@@ -204,7 +205,7 @@ main(void)
for (i=0; i<40; i++) {
stab.btree_addr = (i+1)*1000+1;
stab.heap_addr = (i+1)*1000+2;
- if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, &stab)<0) {
+ if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, 1, &stab)<0) {
H5_FAILED();
H5Eprint(stdout);
goto error;
@@ -225,7 +226,7 @@ main(void)
for (i=0; i<10; i++) {
stab.btree_addr = (i + 1) * 1000 + 10;
stab.heap_addr = (i + 1) * 1000 + 20;
- if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, &stab)<0) {
+ if (H5O_modify(&oh_ent, H5O_STAB, H5O_NEW_MESG, 0, 1, &stab)<0) {
H5_FAILED();
H5Eprint(stdout);
goto error;
diff --git a/test/tattr.c b/test/tattr.c
index aea6287..e375ccf 100644
--- a/test/tattr.c
+++ b/test/tattr.c
@@ -100,7 +100,7 @@ test_attr_basic_write(void)
hid_t attr, attr2; /* Attribute ID */
hsize_t attr_size; /* storage size for attribute */
ssize_t attr_name_size; /* size of attribute name */
- char *attr_name; /* name of attribute */
+ char *attr_name=NULL; /* name of attribute */
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
hsize_t dims2[] = {ATTR1_DIM1};
hsize_t dims3[] = {ATTR2_DIM1,ATTR2_DIM2};
@@ -121,6 +121,7 @@ test_attr_basic_write(void)
/* Create a dataset */
dataset=H5Dcreate(fid1,"Dataset1",H5T_NATIVE_UCHAR,sid1,H5P_DEFAULT);
+ CHECK(dataset, FAIL, "H5Dcreate");
/* Create dataspace for attribute */
sid2 = H5Screate_simple(ATTR1_RANK, dims2, NULL);
@@ -161,7 +162,7 @@ test_attr_basic_write(void)
/* Verify values read in */
for(i=0; i<ATTR1_DIM1; i++)
if(attr_data1[i]!=read_data1[i]) {
- printf("attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
num_errs++;
} /* end if */
@@ -203,7 +204,7 @@ test_attr_basic_write(void)
/* Verify values read in */
for(i=0; i<ATTR1_DIM1; i++)
if(attr_data1[i]!=read_data1[i]) {
- printf("2. attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
num_errs++;
} /* end if */
@@ -238,7 +239,7 @@ test_attr_basic_write(void)
/* Verify values read in */
for(i=0; i<ATTR1_DIM1; i++)
if(attr_data1a[i]!=read_data1[i]) {
- printf("2. attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
num_errs++;
} /* end if */
@@ -347,7 +348,7 @@ test_attr_basic_read(void)
/* Verify values read in */
for(i=0; i<ATTR1_DIM1; i++)
if(attr_data1[i]!=read_data1[i]) {
- printf("attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
num_errs++;
} /* end if */
@@ -377,7 +378,7 @@ test_attr_basic_read(void)
for(i=0; i<ATTR2_DIM1; i++)
for(j=0; j<ATTR2_DIM2; j++)
if(attr_data2[i][j]!=read_data2[i][j]) {
- printf("attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",i,j,attr_data2[i][j],i,j,read_data1[i]);
+ printf("%d: attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",__LINE__, i,j,attr_data2[i][j],i,j,read_data1[i]);
num_errs++;
} /* end if */
@@ -605,9 +606,9 @@ test_attr_compound_read(void)
for(i=0; i<ATTR4_DIM1; i++)
for(j=0; j<ATTR4_DIM2; j++)
if(HDmemcmp(&attr_data4[i][j],&read_data4[i][j],sizeof(struct attr4_struct))) {
- printf("attribute data different: attr_data4[%d][%d].i=%d, read_data4[%d][%d].i=%d\n",i,j,attr_data4[i][j].i,i,j,read_data4[i][j].i);
- printf("attribute data different: attr_data4[%d][%d].d=%f, read_data4[%d][%d].d=%f\n",i,j,attr_data4[i][j].d,i,j,read_data4[i][j].d);
- printf("attribute data different: attr_data4[%d][%d].c=%c, read_data4[%d][%d].c=%c\n",i,j,attr_data4[i][j].c,i,j,read_data4[i][j].c);
+ printf("%d: attribute data different: attr_data4[%d][%d].i=%d, read_data4[%d][%d].i=%d\n",__LINE__,i,j,attr_data4[i][j].i,i,j,read_data4[i][j].i);
+ printf("%d: attribute data different: attr_data4[%d][%d].d=%f, read_data4[%d][%d].d=%f\n",__LINE__,i,j,attr_data4[i][j].d,i,j,read_data4[i][j].d);
+ printf("%d: attribute data different: attr_data4[%d][%d].c=%c, read_data4[%d][%d].c=%c\n",__LINE__,i,j,attr_data4[i][j].c,i,j,read_data4[i][j].c);
num_errs++;
} /* end if */
@@ -943,7 +944,7 @@ test_attr_mult_read(void)
/* Verify values read in */
for(i=0; i<ATTR1_DIM1; i++)
if(attr_data1[i]!=read_data1[i]) {
- printf("attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",i,attr_data1[i],i,read_data1[i]);
+ printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
num_errs++;
} /* end if */
@@ -1009,7 +1010,7 @@ test_attr_mult_read(void)
for(i=0; i<ATTR2_DIM1; i++)
for(j=0; j<ATTR2_DIM2; j++)
if(attr_data2[i][j]!=read_data2[i][j]) {
- printf("attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",i,j,attr_data2[i][j],i,j,read_data2[i][j]);
+ printf("%d: attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",__LINE__,i,j,attr_data2[i][j],i,j,read_data2[i][j]);
num_errs++;
} /* end if */
@@ -1080,7 +1081,7 @@ test_attr_mult_read(void)
for(j=0; j<ATTR3_DIM2; j++)
for(k=0; k<ATTR3_DIM3; k++)
if(attr_data3[i][j][k]!=read_data3[i][j][k]) {
- printf("attribute data different: attr_data3[%d][%d][%d]=%f, read_data3[%d][%d][%d]=%f\n",i,j,k,attr_data3[i][j][k],i,j,k,read_data3[i][j][k]);
+ printf("%d: attribute data different: attr_data3[%d][%d][%d]=%f, read_data3[%d][%d][%d]=%f\n",__LINE__,i,j,k,attr_data3[i][j][k],i,j,k,read_data3[i][j][k]);
num_errs++;
} /* end if */
diff --git a/test/testhdf5.c b/test/testhdf5.c
index 190cdf3..08d718a 100644
--- a/test/testhdf5.c
+++ b/test/testhdf5.c
@@ -157,6 +157,8 @@ main(int argc, char *argv[])
InitTest("configure", test_configure, cleanup_configure, "Configure definitions");
InitTest("metadata", test_metadata, cleanup_metadata, "Encode/decode metadata code");
InitTest("tbbt", test_tbbt, NULL, "Threaded, Balanced, Binary Trees");
+ InitTest("tst", test_tst, NULL, "Ternary Search Trees");
+ InitTest("refstr", test_refstr, NULL, "Reference Counted Strings");
InitTest("file", test_file, cleanup_file, "Low-Level File I/O");
InitTest("h5s", test_h5s, cleanup_h5s, "Dataspaces");
InitTest("attr", test_attr, cleanup_attr, "Attributes");
diff --git a/test/testhdf5.h b/test/testhdf5.h
index 0868983..f89e1dc 100644
--- a/test/testhdf5.h
+++ b/test/testhdf5.h
@@ -121,6 +121,8 @@ int print_func(const char *,...);
/* Prototypes for the test routines */
void test_metadata(void);
void test_tbbt(void);
+void test_tst(void);
+void test_refstr(void);
void test_file(void);
void test_h5t(void);
void test_h5s(void);
diff --git a/test/tgenprop.c b/test/tgenprop.c
index 4ea91e4..9192a82 100644
--- a/test/tgenprop.c
+++ b/test/tgenprop.c
@@ -33,11 +33,9 @@
/* Property definitions */
#define CLASS1_NAME "Class 1"
#define CLASS1_PATH "root/Class 1"
-#define CLASS1_HASHSIZE 25
#define CLASS2_NAME "Class 2"
#define CLASS2_PATH "root/Class 1/Class 2"
-#define CLASS2_HASHSIZE 25
/* Property definitions */
#define PROP1_NAME "Property 1"
@@ -79,7 +77,7 @@ test_genprop_basic_class(void)
MESSAGE(5, ("Testing Basic Generic Property List Class Creation Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Check class name */
@@ -112,7 +110,7 @@ test_genprop_basic_class(void)
CHECK_I(ret, "H5Pclose_class");
/* Create another new generic class, derived from file creation class */
- cid1 = H5Pcreate_class(H5P_FILE_CREATE,CLASS2_NAME,CLASS2_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_FILE_CREATE,CLASS2_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Check class name */
@@ -171,7 +169,7 @@ test_genprop_basic_class_prop(void)
MESSAGE(5, ("Testing Basic Generic Property List Class Properties Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Check the number of properties in class */
@@ -327,7 +325,7 @@ test_genprop_class_iter(void)
MESSAGE(5, ("Testing Basic Generic Property List Class Property Iteration Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with no callbacks) */
@@ -423,7 +421,7 @@ test_genprop_class_callback(void)
MESSAGE(5, ("Testing Basic Generic Property List Class Callback Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,test_genprop_cls_cb1,&crt_cb_struct,NULL,NULL,test_genprop_cls_cb1,&cls_cb_struct);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,test_genprop_cls_cb1,&crt_cb_struct,NULL,NULL,test_genprop_cls_cb1,&cls_cb_struct);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with no callbacks) */
@@ -522,7 +520,7 @@ test_genprop_basic_list(void)
MESSAGE(5, ("Testing Basic Generic Property List Creation Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Add several properties (w/default values) */
@@ -624,7 +622,7 @@ test_genprop_basic_list_prop(void)
MESSAGE(5, ("Testing Basic Generic Property List Property Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Add several properties (several w/default values) */
@@ -771,17 +769,18 @@ test_genprop_list_iter(void)
const char **names;
} iter_struct;
const char *pnames[4]={ /* Names of properties for iterator */
- PROP1_NAME,
- PROP2_NAME,
PROP3_NAME,
- PROP4_NAME};
+ PROP4_NAME,
+ PROP1_NAME,
+ PROP2_NAME
+ };
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Generic Property List Iteration Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Add several properties (several w/default values) */
@@ -1020,7 +1019,7 @@ test_genprop_list_callback(void)
MESSAGE(5, ("Testing Basic Generic Property List Property Callback Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,test_genprop_cls_cb2,&cop_cb_struct,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,test_genprop_cls_cb2,&cop_cb_struct,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with callbacks) */
@@ -1308,7 +1307,7 @@ test_genprop_class_addprop(void)
CHECK(sid, FAIL, "H5Screate");
/* Create a new class, dervied from the dataset creation property list class */
- cid = H5Pcreate_class(H5P_DATASET_CREATE,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid = H5Pcreate_class(H5P_DATASET_CREATE,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid, "H5Pcreate_class");
/* Check existence of an original property */
@@ -1389,8 +1388,7 @@ test_genprop_equal(void)
MESSAGE(5, ("Testing Basic Generic Property List Equal Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- /* (Use a hash size of 1 to force the properties into the same hash chain) */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,1,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with no callbacks) */
@@ -1438,7 +1436,7 @@ test_genprop_path(void)
MESSAGE(5, ("Testing Generic Property List Class Path Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with no callbacks) */
@@ -1455,7 +1453,7 @@ test_genprop_path(void)
free(path);
/* Create another new generic class, derived from first class */
- cid2 = H5Pcreate_class(cid1,CLASS2_NAME,CLASS2_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid2 = H5Pcreate_class(cid1,CLASS2_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid2, "H5Pcreate_class");
/* Insert second property into class (with no callbacks) */
@@ -1513,7 +1511,7 @@ test_genprop_refcount(void)
MESSAGE(5, ("Testing Generic Property List Reference Count Functionality\n"));
/* Create a new generic class, derived from the root of the class hierarchy */
- cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL);
+ cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL);
CHECK_I(cid1, "H5Pcreate_class");
/* Insert first property into class (with no callbacks) */
diff --git a/test/titerate.c b/test/titerate.c
index 02819a0..8f5d3c8 100644
--- a/test/titerate.c
+++ b/test/titerate.c
@@ -194,12 +194,12 @@ static void test_iter_group(void)
ret = H5Gget_objname_by_idx(root_group, (hsize_t)i, dataset_name, 32);
CHECK(ret, FAIL, "H5Gget_objsname_by_idx");
- ret = H5Gget_objtype_by_idx(root_group, (hsize_t)i);
- CHECK(ret, H5G_UNKNOWN, "H5Gget_objsname_by_idx");
+ ret = (herr_t)H5Gget_objtype_by_idx(root_group, (hsize_t)i);
+ CHECK(ret, FAIL, "H5Gget_objsname_by_idx");
}
H5E_BEGIN_TRY {
- ret = H5Gget_objname_by_idx(root_group, (hsize_t)(NDATASETS+3), dataset_name, 16);
+ ret = (herr_t)H5Gget_objname_by_idx(root_group, (hsize_t)(NDATASETS+3), dataset_name, 16);
} H5E_END_TRY;
VERIFY(ret, FAIL, "H5Gget_objsname_by_idx");
@@ -664,7 +664,7 @@ static void test_grp_memb_funcs(void)
VERIFY(num_membs,NDATASETS+2,"H5Gget_num_objs");
for(i=0; i< (int)num_membs; i++) {
- ret = H5Gget_objname_by_idx(root_group, (hsize_t)i, dataset_name, 32);
+ ret = (herr_t)H5Gget_objname_by_idx(root_group, (hsize_t)i, dataset_name, 32);
CHECK(ret, FAIL, "H5Gget_objsname_by_idx");
/* Keep a copy of the dataset names around for later */
@@ -683,7 +683,7 @@ static void test_grp_memb_funcs(void)
}
H5E_BEGIN_TRY {
- ret = H5Gget_objname_by_idx(root_group, (hsize_t)(NDATASETS+3), dataset_name, 16);
+ ret = (herr_t)H5Gget_objname_by_idx(root_group, (hsize_t)(NDATASETS+3), dataset_name, 16);
} H5E_END_TRY;
VERIFY(ret, FAIL, "H5Gget_objsname_by_idx");
@@ -704,8 +704,10 @@ static void test_grp_memb_funcs(void)
CHECK(ret, FAIL, "H5Fclose");
/* Free the dataset names */
- for(i=0; i< NDATASETS+2; i++)
+ for(i=0; i< NDATASETS+2; i++) {
free(dnames[i]);
+ free(obj_names[i]);
+ }
} /* test_grp_memb_funcs() */
diff --git a/test/tmtimen.h5 b/test/tmtimen.h5
new file mode 100644
index 0000000..96e5fb3
--- /dev/null
+++ b/test/tmtimen.h5
Binary files differ
diff --git a/test/tmtimeo.h5 b/test/tmtimeo.h5
new file mode 100644
index 0000000..8c0f02d
--- /dev/null
+++ b/test/tmtimeo.h5
Binary files differ
diff --git a/test/trefstr.c b/test/trefstr.c
new file mode 100644
index 0000000..374e954
--- /dev/null
+++ b/test/trefstr.c
@@ -0,0 +1,378 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/* $Id$ */
+
+/*
+ FILE
+ refstr.c
+ Test HDF reference counted string routines.
+
+ REMARKS
+
+ DESIGN
+
+ BUGS/LIMITATIONS
+
+ EXPORTED ROUTINES
+
+ AUTHOR
+ Quincey Koziol
+
+ MODIFICATION HISTORY
+ 12/17/02 - Started coding
+ */
+
+#include "testhdf5.h"
+#include "H5FLprivate.h"
+#include "H5RSprivate.h"
+
+/* Declare extern the PQ free list for the wrapped strings */
+H5FL_BLK_EXTERN(str_buf);
+
+/****************************************************************
+**
+** test_refstr_init(): Test basic H5RS (ref-counted strings) code.
+** Initialize data for RS testing
+**
+****************************************************************/
+static void
+test_refstr_init(void)
+{
+} /* end test_refstr_init() */
+
+/****************************************************************
+**
+** test_refstr_create(): Test basic H5RS (ref-counted strings) code.
+** Tests creating and closing ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_create(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ unsigned count; /* Reference count on string */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Creating & Closing Ref-Counted Strings\n"));
+
+ /* Try creating a ref-counted string */
+ rs=H5RS_create("foo");
+ CHECK(rs, NULL, "H5RS_create");
+
+ /* Get the reference count on the string */
+ count=H5RS_GET_COUNT(rs);
+ VERIFY(count, 1, "H5RS_GET_COUNT");
+
+ /* Try closing a real ref-counted string */
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_create() */
+
+/****************************************************************
+**
+** test_refstr_count(): Test basic H5RS (ref-counted strings) code.
+** Tests reference counting on ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_count(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ unsigned count; /* Reference count on string */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Incrementing & Decrementing Ref-Counted Strings\n"));
+
+ /* Try creating a ref-counted string */
+ rs=H5RS_create("foo");
+ CHECK(rs, NULL, "H5RS_create");
+
+ /* Get the reference count on the string */
+ count=H5RS_GET_COUNT(rs);
+ VERIFY(count, 1, "H5RS_GET_COUNT");
+
+ /* Increment reference count */
+ ret=H5RS_incr(rs);
+ CHECK(ret, FAIL, "H5RS_incr");
+
+ /* Get the reference count on the string */
+ count=H5RS_GET_COUNT(rs);
+ VERIFY(count, 2, "H5RS_GET_COUNT");
+
+ /* Decrement reference count for string */
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+ /* Get the reference count on the string */
+ count=H5RS_GET_COUNT(rs);
+ VERIFY(count, 1, "H5RS_GET_COUNT");
+
+ /* Decrement reference count for string */
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_count() */
+
+/****************************************************************
+**
+** test_refstr_dup(): Test basic H5RS (ref-counted strings) code.
+** Tests duplicating ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_dup(void)
+{
+ H5RS_str_t *rs1; /* Ref-counted string created */
+ H5RS_str_t *rs2; /* Ref-counted string created */
+ unsigned count; /* Reference count on string */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Duplicating Ref-Counted Strings\n"));
+
+ /* Try creating a ref-counted string */
+ rs1=H5RS_create("foo");
+ CHECK(rs1, NULL, "H5RS_create");
+
+ /* Get the reference count on the string */
+ count=H5RS_GET_COUNT(rs1);
+ VERIFY(count, 1, "H5RS_GET_COUNT");
+
+ /* Duplicate r-string */
+ rs2=H5RS_dup(rs1);
+ CHECK(rs2, NULL, "H5RS_dup");
+
+ /* Get the reference count on the strings */
+ count=H5RS_GET_COUNT(rs1);
+ VERIFY(count, 2, "H5RS_GET_COUNT");
+ count=H5RS_GET_COUNT(rs2);
+ VERIFY(count, 2, "H5RS_GET_COUNT");
+
+ /* Decrement reference count for string */
+ ret=H5RS_decr(rs2);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+ /* Get the reference count on the string */
+ count=H5RS_GET_COUNT(rs1);
+ VERIFY(count, 1, "H5RS_GET_COUNT");
+
+ /* Decrement reference count for string */
+ ret=H5RS_decr(rs1);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_dup() */
+
+/****************************************************************
+**
+** test_refstr_cmp(): Test basic H5RS (ref-counted strings) code.
+** Tests comparing ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_cmp(void)
+{
+ H5RS_str_t *rs1; /* Ref-counted string created */
+ H5RS_str_t *rs2; /* Ref-counted string created */
+ int cmp; /* Comparison value */
+ ssize_t len; /* Length of string */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Comparing Ref-Counted Strings\n"));
+
+ /* Create first reference counted string */
+ rs1=H5RS_create("foo");
+ CHECK(rs1, NULL, "H5RS_create");
+
+ /* Create second reference counted string */
+ rs2=H5RS_create("foo2");
+ CHECK(rs2, NULL, "H5RS_create");
+
+ /* Compare the strings in various ways */
+ cmp=H5RS_cmp(rs1,rs1);
+ VERIFY(cmp, 0, "H5RS_cmp");
+ cmp=H5RS_cmp(rs2,rs2);
+ VERIFY(cmp, 0, "H5RS_cmp");
+ cmp=H5RS_cmp(rs1,rs2);
+ if(cmp>=0) {
+ num_errs++;
+ printf("%d: string comparison incorrect!\n",__LINE__);
+ } /* end if */
+
+ /* Check the lengths of the strings also */
+ len=H5RS_len(rs1);
+ VERIFY(len, 3, "H5RS_len");
+ len=H5RS_len(rs2);
+ VERIFY(len, 4, "H5RS_len");
+
+ /* Decrement reference count for strings */
+ ret=H5RS_decr(rs2);
+ CHECK(ret, FAIL, "H5RS_decr");
+ ret=H5RS_decr(rs1);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_cmp() */
+
+/****************************************************************
+**
+** test_refstr_wrap(): Test basic H5RS (ref-counted strings) code.
+** Tests wrapping ref-counted strings around existing strings.
+**
+****************************************************************/
+static void
+test_refstr_wrap(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ const char *s; /* Pointer to raw string in ref-counted string */
+ char buf[16]; /* Buffer to wrap */
+ int cmp; /* Comparison value */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Wrapping Ref-Counted Strings\n"));
+
+ /* Initialize buffer */
+ HDstrcpy(buf,"foo");
+
+ /* Wrap ref-counted string around existing buffer */
+ rs=H5RS_wrap(buf);
+ CHECK(rs, NULL, "H5RS_wrap");
+
+ /* Get pointer to raw string in ref-counted string */
+ s=H5RS_GET_STR(rs);
+ CHECK(s, NULL, "H5RS_GET_STR");
+ VERIFY(s, buf, "wrapping");
+ cmp=HDstrcmp(s,buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Increment reference count (should duplicate string) */
+ ret=H5RS_incr(rs);
+ CHECK(ret, FAIL, "H5RS_incr");
+
+ /* Change the buffer initially wrapped */
+ buf[0]='F';
+
+ /* Get pointer to raw string in ref-counted string */
+ s=H5RS_GET_STR(rs);
+ CHECK(s, NULL, "H5RS_GET_STR");
+ CHECK(s, buf, "wrapping");
+ cmp=HDstrcmp(s,buf);
+ if(cmp<=0) {
+ num_errs++;
+ printf("%d: string comparison incorrect!\n",__LINE__);
+ } /* end if */
+
+ /* Decrement reference count for string */
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_wrap() */
+
+/****************************************************************
+**
+** test_refstr_own(): Test basic H5RS (ref-counted strings) code.
+** Tests transferring ownership of dynamically allocated strings
+** to ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_own(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ char *s; /* Pointer to string to transfer */
+ const char *t; /* Temporary pointers to string */
+ int cmp; /* Comparison value */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Transferring Ref-Counted Strings\n"));
+
+ /* Initialize buffer */
+ s = H5FL_BLK_MALLOC(str_buf,HDstrlen("foo") + 1);
+ HDstrcpy(s, "foo");
+
+ /* Transfer ownership of dynamically allocated string to ref-counted string */
+ rs=H5RS_own(s);
+ CHECK(rs, NULL, "H5RS_own");
+
+ /* Get pointer to raw string in ref-counted string */
+ t=H5RS_GET_STR(rs);
+ CHECK(t, NULL, "H5RS_GET_STR");
+ VERIFY(t, s, "transferring");
+ cmp=HDstrcmp(s,t);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Increment reference count (should NOT duplicate string) */
+ ret=H5RS_incr(rs);
+ CHECK(ret, FAIL, "H5RS_incr");
+
+ /* Change the buffer initially wrapped */
+ *s='F';
+
+ /* Get pointer to raw string in ref-counted string */
+ t=H5RS_GET_STR(rs);
+ CHECK(t, NULL, "H5RS_GET_STR");
+ VERIFY(t, s, "transferring");
+ cmp=HDstrcmp(t,s);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Decrement reference count for string */
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+ ret=H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_own() */
+
+/****************************************************************
+**
+** test_refstr_finalize(): Test basic H5RS (ref-counted strings) code.
+** Wrap up data for ref-counted string testing
+**
+****************************************************************/
+static void
+test_refstr_finalize(void)
+{
+} /* end test_refstr_finalize() */
+
+/****************************************************************
+**
+** test_refstr(): Main H5RS testing routine.
+**
+****************************************************************/
+void
+test_refstr(void)
+{
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Reference Counted Strings\n"));
+
+ /* Initialize ref-counted strings testing data */
+ test_refstr_init();
+
+ /* Actual ref-counted strings tests */
+ test_refstr_create(); /* Test ref-counted string creation */
+ test_refstr_count(); /* Test ref-counted string counting */
+ test_refstr_dup(); /* Test ref-counted string duplication */
+ test_refstr_cmp(); /* Test ref-counted string comparison */
+ test_refstr_wrap(); /* Test ref-counted string wrapping */
+ test_refstr_own(); /* Test ref-counted string ownership transfer */
+
+ /* Finalize ref-counted strings testing data */
+ test_refstr_finalize();
+} /* end test_refstr() */
+
diff --git a/test/ttst.c b/test/ttst.c
new file mode 100644
index 0000000..eb9ebef
--- /dev/null
+++ b/test/ttst.c
@@ -0,0 +1,400 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/* $Id$ */
+
+/*
+ FILE
+ tst.c
+ Test HDF Ternary Search Tree (tst) routines.
+
+ REMARKS
+
+ DESIGN
+
+ BUGS/LIMITATIONS
+
+ EXPORTED ROUTINES
+
+ AUTHOR
+ Quincey Koziol
+
+ MODIFICATION HISTORY
+ 12/9/02 - Started coding
+ */
+
+#include <time.h>
+
+#include "testhdf5.h"
+#include "H5STprivate.h"
+
+/* Test words to insert into s TST */
+static const char *words[]={
+ "We", "hold", "these", "truths", "to", "be", "self-evident,", "that",
+ "all", "men", "are", "created", "equal,", "that", "they", "are", "endowed",
+ "by", "their", "Creator", "with", "certain", "unalienable", "Rights,",
+ "that", "among", "these", "are", "Life,", "Liberty", "and", "the",
+ "pursuit", "of", "Happiness."
+};
+/* Number of words in test words set */
+size_t num_words;
+
+/* Number of unique words in test word set */
+size_t num_uniq_words;
+/* Unique words in test word set */
+char **uniq_words;
+/* Randomized order version of words in test word set */
+char **rand_uniq_words;
+/* Sorted order version of words in test word set */
+char **sort_uniq_words;
+
+static int tst_strcmp(const void *_s1, const void *_s2)
+{
+ return(HDstrcmp(*(const char **)_s1,*(const char **)_s2));
+}
+
+/****************************************************************
+**
+** test_tst_init(): Test basic H5ST (ternary search tree) selection code.
+** Initialize data for TST testing
+**
+****************************************************************/
+static void
+test_tst_init(void)
+{
+ time_t curr_time; /* Current time, for seeding random number generator */
+ char *tmp_word=NULL;/* Temporary pointer to word in word set */
+ size_t u,v,w; /* Local index variables */
+
+ /* Compute the number of words in the test set */
+ num_words=sizeof(words)/sizeof(words[0]);
+
+ /* Determine the number of unique words in test set */
+ /* (Not particularly efficient, be careful if many words are added to set) */
+ num_uniq_words=0;
+ for(u=0; u<num_words; u++) {
+ /* Assume word is unique */
+ num_uniq_words++;
+ for(v=0; v<u; v++)
+ /* If word is already found in words looked at, decrement unique count */
+ if(!HDstrcmp(words[u],words[v])) {
+ num_uniq_words--;
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* Allocate space for the array of unique words */
+ uniq_words=HDmalloc(sizeof(char *)*num_uniq_words);
+
+ /* Allocate space for the array of randomized order unique words also */
+ rand_uniq_words=HDmalloc(sizeof(char *)*num_uniq_words);
+
+ /* Allocate space for the array of sorted order unique words also */
+ sort_uniq_words=HDmalloc(sizeof(char *)*num_uniq_words);
+
+ /* Insert unique words from test set into unique word set */
+ w=0;
+ for(u=0; u<num_words; u++) {
+ /* Assume word is unique */
+ tmp_word=(char *)words[u];
+ for(v=0; v<u; v++)
+ /* If word is already found in words looked at, decrement unique count */
+ if(!HDstrcmp(words[u],words[v])) {
+ tmp_word=NULL;
+ break;
+ } /* end if */
+
+ /* Check if word was actually unique */
+ if(tmp_word!=NULL)
+ uniq_words[w++]=tmp_word;
+ } /* end for */
+
+ /* Create randomized set of unique words */
+ for(u=0; u<num_uniq_words; u++)
+ rand_uniq_words[u]=uniq_words[u];
+ curr_time=time(NULL);
+ srandom((unsigned long)curr_time);
+ for(u=0; u<num_uniq_words; u++) {
+ v=u+(random()%(num_uniq_words-u));
+ if(u!=v) {
+ tmp_word=rand_uniq_words[u];
+ rand_uniq_words[u]=rand_uniq_words[v];
+ rand_uniq_words[v]=tmp_word;
+ } /* end if */
+ } /* end for */
+
+ /* Create sorted set of unique words */
+ for(u=0; u<num_uniq_words; u++)
+ sort_uniq_words[u]=uniq_words[u];
+ HDqsort(sort_uniq_words,num_uniq_words,sizeof(char *),tst_strcmp);
+} /* end test_tst_init() */
+
+/****************************************************************
+**
+** test_tst_create(): Test basic H5ST (ternary search tree) selection code.
+** Tests creating and closing TSTs.
+**
+****************************************************************/
+static void
+test_tst_create(void)
+{
+ H5ST_tree_t *tree; /* TST created */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Creating & Closing TSTs\n"));
+
+ /* Try closing a NULL tree */
+ tree=NULL;
+ ret=H5ST_close(tree);
+ VERIFY(ret, FAIL, "H5ST_close");
+
+ /* Try creating a TST */
+ tree=H5ST_create();
+ CHECK(tree, NULL, "H5ST_create");
+
+ /* Try closing a real tree */
+ ret=H5ST_close(tree);
+ CHECK(ret, FAIL, "H5ST_close");
+
+} /* end test_tst_create() */
+
+/****************************************************************
+**
+** test_tst_insert(): Test basic H5ST (ternary search tree) selection code.
+** Tests inserting key/value pairs into TST
+**
+****************************************************************/
+static void
+test_tst_insert(void)
+{
+ H5ST_tree_t *tree; /* TST created */
+ H5ST_ptr_t found; /* Pointer to TST node found */
+ void *obj; /* Pointer to object located in TST */
+ size_t u; /* Local index counter */
+ htri_t check; /* Is string in TST? */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Inserting Values into TSTs\n"));
+
+ /* Create the TST */
+ tree=H5ST_create();
+ CHECK(tree, NULL, "H5ST_create");
+
+ /* Insert unique words into TST, in random order */
+ for(u=0; u<num_uniq_words; u++) {
+ ret=H5ST_insert(tree,rand_uniq_words[u],rand_uniq_words[u]);
+ CHECK(ret, FAIL, "H5ST_insert");
+ } /* end for */
+
+ /* Verify that all words were inserted into TST properly */
+ for(u=0; u<num_uniq_words; u++) {
+ /* Check that the word is present */
+ check=H5ST_search(tree,uniq_words[u]);
+ VERIFY(check, TRUE, "H5ST_search");
+
+ /* Check that the value "payloads" are correct */
+ found=H5ST_find(tree,uniq_words[u]);
+ CHECK(found, NULL, "H5ST_find");
+
+ if(HDstrcmp((const char *)found->eqkid,uniq_words[u])) {
+ num_errs++;
+ printf("%d: TST node values don't match!, found->eqkid=%s, uniq_words[%u]=%s\n",__LINE__,(char *)found->eqkid,(unsigned)u,uniq_words[u]);
+ } /* end if */
+
+ obj=H5ST_locate(tree,uniq_words[u]);
+ CHECK(obj, NULL, "H5ST_locate");
+
+ if(HDstrcmp((const char *)obj,uniq_words[u])) {
+ num_errs++;
+ printf("%d: TST objects don't match!, obj=%s, uniq_words[%u]=%s\n",__LINE__,(char *)obj,(unsigned)u,uniq_words[u]);
+ } /* end if */
+ } /* end for */
+
+ /* Verify that words not in the TST aren't found */
+ check=H5ST_search(tree,"foo");
+ VERIFY(check, FALSE, "H5ST_search");
+ check=H5ST_search(tree,"bar");
+ VERIFY(check, FALSE, "H5ST_search");
+ check=H5ST_search(tree,"baz");
+ VERIFY(check, FALSE, "H5ST_search");
+
+ /* Close the TST */
+ ret=H5ST_close(tree);
+ CHECK(ret, FAIL, "H5ST_close");
+} /* end test_tst_insert() */
+
+/****************************************************************
+**
+** test_tst_iterate(): Test basic H5ST (ternary search tree) code.
+** Tests iterating through key/value pairs in TST
+**
+****************************************************************/
+static void
+test_tst_iterate(void)
+{
+ H5ST_tree_t *tree; /* TST created */
+ H5ST_ptr_t found; /* Pointer to TST node found */
+ size_t u; /* Local index counter */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Iterating Over TSTs\n"));
+
+ /* Create the TST */
+ tree=H5ST_create();
+ CHECK(tree, NULL, "H5ST_create");
+
+ /* Insert unique words into TST, in random order */
+ for(u=0; u<num_uniq_words; u++) {
+ ret=H5ST_insert(tree,rand_uniq_words[u],rand_uniq_words[u]);
+ CHECK(ret, FAIL, "H5ST_insert");
+ } /* end for */
+
+ /* Use findfirst/findnext calls to iterate through TST */
+ found=H5ST_findfirst(tree);
+ CHECK(found, NULL, "H5ST_findfirst");
+ u=0;
+ do {
+ /* Check that the strings in the TST are in the correct order */
+ if(HDstrcmp((const char *)found->eqkid,sort_uniq_words[u])) {
+ num_errs++;
+ printf("%d: TST node values don't match!, found->eqkid=%s, sort_uniq_words[%u]=%s\n",__LINE__,(char *)found->eqkid,(unsigned)u,sort_uniq_words[u]);
+ } /* end if */
+
+ /* Advance to next string in TST */
+ found=H5ST_findnext(found);
+ u++;
+ } while(found!=NULL);
+
+ /* Close the TST */
+ ret=H5ST_close(tree);
+ CHECK(ret, FAIL, "H5ST_close");
+} /* end test_tst_iterate() */
+
+/****************************************************************
+**
+** test_tst_remove(): Test basic H5ST (ternary search tree) code.
+** Tests removing key/value pairs by string value in TST
+**
+****************************************************************/
+static void
+test_tst_remove(void)
+{
+ H5ST_tree_t *tree; /* TST created */
+ H5ST_ptr_t found; /* Pointer to TST node found */
+ void *obj; /* Pointer to object removed from TST */
+ htri_t check; /* Is string in TST? */
+ size_t u; /* Local index counter */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Removing String Values from TSTs\n"));
+
+ /* Create the TST */
+ tree=H5ST_create();
+ CHECK(tree, NULL, "H5ST_create");
+
+ /* Insert unique words into TST, in random order */
+ for(u=0; u<num_uniq_words; u++) {
+ ret=H5ST_insert(tree,rand_uniq_words[u],rand_uniq_words[u]);
+ CHECK(ret, FAIL, "H5ST_insert");
+ } /* end for */
+
+ /* Remove strings from TST in random order */
+ for(u=0; u<num_uniq_words; u++) {
+ obj=H5ST_remove(tree,rand_uniq_words[u]);
+ CHECK(obj, NULL, "H5ST_remove");
+
+ /* Check that the correct string was removed from TST */
+ if(HDstrcmp((const char *)obj,rand_uniq_words[u])) {
+ num_errs++;
+ printf("%d: TST node values don't match!, obj=%s, rand_uniq_words[%u]=%s\n",__LINE__,(char *)obj,(unsigned)u,rand_uniq_words[u]);
+ } /* end if */
+
+ /* Check that the string can't be found in the TST any longer */
+ check=H5ST_search(tree,rand_uniq_words[u]);
+ VERIFY(check, FALSE, "H5ST_search");
+ } /* end for */
+
+ /* Re-insert unique words into TST, in random order */
+ for(u=0; u<num_uniq_words; u++) {
+ ret=H5ST_insert(tree,rand_uniq_words[u],rand_uniq_words[u]);
+ CHECK(ret, FAIL, "H5ST_insert");
+ } /* end for */
+
+ /* Remove TST nodes from TST in random order */
+ for(u=0; u<num_uniq_words; u++) {
+ /* Get the pointer to the node to delete */
+ found=H5ST_find(tree,rand_uniq_words[u]);
+ CHECK(found, NULL, "H5ST_find");
+
+ /* Check that the correct object will be removed from TST */
+ if(HDstrcmp((const char *)found->eqkid,rand_uniq_words[u])) {
+ num_errs++;
+ printf("%d: TST node values don't match!, found->eqkid=%s, rand_uniq_words[%u]=%s\n",__LINE__,(char *)found->eqkid,(unsigned)u,rand_uniq_words[u]);
+ } /* end if */
+
+ /* Remove the node */
+ ret=H5ST_delete(tree,found);
+ CHECK(ret, FAIL, "H5ST_delete");
+
+ /* Check that the string can't be found in the TST any longer */
+ check=H5ST_search(tree,rand_uniq_words[u]);
+ VERIFY(check, FALSE, "H5ST_search");
+ } /* end for */
+
+ /* Close the TST */
+ ret=H5ST_close(tree);
+ CHECK(ret, FAIL, "H5ST_close");
+} /* end test_tst_remove() */
+
+/****************************************************************
+**
+** test_tst_finalize(): Test basic H5ST (ternary search tree) selection code.
+** Wrap up data for TST testing
+**
+****************************************************************/
+static void
+test_tst_finalize(void)
+{
+ /* Release memory for unordered, randomized and sorted order unique words */
+ HDfree(uniq_words);
+ HDfree(rand_uniq_words);
+ HDfree(sort_uniq_words);
+} /* end test_tst_finalize() */
+
+/****************************************************************
+**
+** test_tst(): Main H5ST selection testing routine.
+**
+****************************************************************/
+void
+test_tst(void)
+{
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Ternary Search Trees\n"));
+
+ /* Initialize TST testing data */
+ test_tst_init();
+
+ /* Actual TST tests */
+ test_tst_create(); /* Test TST creation */
+ test_tst_insert(); /* Test TST insertion */
+ test_tst_iterate(); /* Test TST iteration */
+ test_tst_remove(); /* Test TST deletion */
+
+ /* Finalize TST testing data */
+ test_tst_finalize();
+} /* end test_tst() */
+
diff --git a/test/tvlstr.c b/test/tvlstr.c
index cd15fa8..a8cbd84 100644
--- a/test/tvlstr.c
+++ b/test/tvlstr.c
@@ -256,17 +256,12 @@ test_vlstrings_special(void)
const char *wdata[SPACE1_DIM1] = {"one", "two", "", "four"};
const char *wdata2[SPACE1_DIM1] = {NULL, NULL, NULL, NULL};
char *rdata[SPACE1_DIM1]; /* Information read in */
- hid_t dataspace, dataset2;
hid_t fid1; /* HDF5 File IDs */
hid_t dataset; /* Dataset ID */
hid_t sid1; /* Dataspace ID */
hid_t tid1; /* Datatype ID */
- hid_t xfer_pid; /* Dataset transfer property list ID */
hsize_t dims1[] = {SPACE1_DIM1};
- hsize_t size; /* Number of bytes which will be used */
unsigned i; /* counting variable */
- int str_used; /* String data in memory */
- int mem_used=0; /* Memory used during allocation */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
@@ -313,6 +308,10 @@ test_vlstrings_special(void)
} /* end if */
} /* end for */
+ /* Reclaim the read VL data */
+ ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,rdata);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
/* Close Dataset */
ret = H5Dclose(dataset);
CHECK(ret, FAIL, "H5Dclose");
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index c1abc13..9ec4cbd 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -4595,7 +4595,7 @@ xml_print_strs(hid_t did, int source)
hid_t type, space;
void *buf;
char *bp;
- char *onestring;
+ char *onestring=NULL;
hsize_t ssiz;
size_t tsiz, str_size;
size_t i;
diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c
index f0e9515..593dc8d 100644
--- a/tools/h5dump/h5dumpgentest.c
+++ b/tools/h5dump/h5dumpgentest.c
@@ -2850,7 +2850,7 @@ static void gent_vlstr(void)
"Now we are engaged in a great civil war,",
"testing whether that nation or any nation so conceived and so dedicated can long endure."
}; /* Information to write */
- char *string_att= "This is the string for the attribute";
+ const char *string_att= "This is the string for the attribute";
hid_t fid1; /* HDF5 File IDs */
hid_t dataset, root; /* Dataset ID */
hid_t sid1, dataspace;/* Dataspace ID */