summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2008-07-22 20:36:31 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2008-07-22 20:36:31 (GMT)
commit8704820d1c56165fcf930ab21adebea0a48c664f (patch)
treeb74991b3c84c1a6d52e1003c7668863b1fd3dfb4 /src
parent717388ea0683ff9db970cd8f8998ba9b94d62cf0 (diff)
downloadhdf5-8704820d1c56165fcf930ab21adebea0a48c664f.zip
hdf5-8704820d1c56165fcf930ab21adebea0a48c664f.tar.gz
hdf5-8704820d1c56165fcf930ab21adebea0a48c664f.tar.bz2
[svn-r15395] When an attribute was opened twice and data was written with one of the handles,
the file didn't have the data. It happened because each handle had its own object structure, and the empty one overwrote the data with fill value. This is fixed by making some attribute information like the data be shared in the attribute structure. Tested on smirom, kagiso, and linew.
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c302
-rw-r--r--src/H5Abtree2.c4
-rw-r--r--src/H5Adense.c32
-rw-r--r--src/H5Aint.c115
-rw-r--r--src/H5Apkg.h24
-rw-r--r--src/H5Atest.c2
-rw-r--r--src/H5Oattr.c297
-rw-r--r--src/H5Oattribute.c281
-rw-r--r--src/H5Tcompound.c4
9 files changed, 648 insertions, 413 deletions
diff --git a/src/H5A.c b/src/H5A.c
index dc00135..aec538f 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -85,9 +85,12 @@ static herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_
/* Local Variables */
/*******************/
-/* Declare the free lists for H5A_t's */
+/* Declare the free lists of H5A_t */
H5FL_DEFINE(H5A_t);
+/* Declare the free lists for H5A_shared_t's */
+H5FL_DEFINE(H5A_shared_t);
+
/* Declare a free list to manage blocks of type conversion data */
H5FL_BLK_DEFINE(attr_buf);
@@ -392,9 +395,12 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
if((attr = H5FL_CALLOC(H5A_t)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
+ if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate shared attr structure")
+
/* If the creation property list is H5P_DEFAULT, use the default character encoding */
if(acpl_id == H5P_DEFAULT)
- attr->encoding = H5F_DEFAULT_CSET;
+ attr->shared->encoding = H5F_DEFAULT_CSET;
else {
H5P_genplist_t *ac_plist; /* ACPL Property list */
@@ -402,59 +408,59 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
if(NULL == (ac_plist = (H5P_genplist_t *)H5I_object(acpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
- if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->encoding)) < 0)
+ if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag")
} /* end else */
/* Copy the attribute name */
- attr->name = H5MM_xstrdup(name);
+ attr->shared->name = H5MM_xstrdup(name);
/* Copy the attribute's datatype */
- attr->dt = H5T_copy(type, H5T_COPY_ALL);
+ attr->shared->dt = H5T_copy(type, H5T_COPY_ALL);
/* Mark any datatypes as being on disk now */
- if(H5T_set_loc(attr->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
+ if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
/* Set the latest format for datatype, if requested */
if(H5F_USE_LATEST_FORMAT(loc->oloc->file))
- if(H5T_set_latest_version(attr->dt) < 0)
+ if(H5T_set_latest_version(attr->shared->dt) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype")
/* Copy the dataspace for the attribute */
- attr->ds = H5S_copy(space, FALSE, TRUE);
+ attr->shared->ds = H5S_copy(space, FALSE, TRUE);
/* Set the latest format for dataspace, if requested */
if(H5F_USE_LATEST_FORMAT(loc->oloc->file))
- if(H5S_set_latest_version(attr->ds) < 0)
+ if(H5S_set_latest_version(attr->shared->ds) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace")
/* Mark it initially set to initialized */
- attr->initialized = TRUE; /*for now, set to false later*/
+ attr->shared->initialized = TRUE; /*for now, set to false later*/
/* Copy the object header information */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy(&(attr->shared->oloc), loc->oloc, H5_COPY_DEEP) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Deep copy of the group hierarchy path */
if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy path")
/* Check if any of the pieces should be (or are already) shared in the
* SOHM table
*/
- if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->dt, NULL) < 0)
+ if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed")
- if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->ds, NULL) < 0)
+ if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed")
/* Check whether datatype is committed & increment ref count
* (to maintain ref. count incr/decr similarity with "shared message"
* type of datatype sharing)
*/
- if(H5T_committed(attr->dt)) {
+ if(H5T_committed(attr->shared->dt)) {
/* Increment the reference count on the shared datatype */
- if(H5T_link(attr->dt, 1, dxpl_id) < 0)
+ if(H5T_link(attr->shared->dt, 1, dxpl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
} /* end if */
@@ -462,29 +468,29 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
* datatype and dataspace messages themselves, or the size of the "shared"
* messages if either or both of them are shared.
*/
- attr->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->dt);
- attr->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->ds);
+ attr->shared->dt_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt);
+ attr->shared->ds_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds);
/* Get # of elements for attribute's dataspace */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
- HDassert(attr->dt_size > 0);
- HDassert(attr->ds_size > 0);
- attr->data_size = nelmts * H5T_get_size(attr->dt);
+ HDassert(attr->shared->dt_size > 0);
+ HDassert(attr->shared->ds_size > 0);
+ attr->shared->data_size = nelmts * H5T_get_size(attr->shared->dt);
/* Hold the symbol table entry (and file) open */
- if(H5O_open(&(attr->oloc)) < 0)
+ if(H5O_open(&(attr->shared->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
attr->obj_opened = TRUE;
/* Set the version to encode the attribute with */
- if(H5A_set_version(attr->oloc.file, attr) < 0)
+ if(H5A_set_version(attr->shared->oloc.file, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version")
/* Insert the attribute into the object header */
- if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0)
+ if(H5O_attr_create(&(attr->shared->oloc), dxpl_id, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header")
/* Register the new attribute and get an ID for it */
@@ -492,12 +498,11 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
/* Now it's safe to say it's uninitialized */
- attr->initialized = FALSE;
+ attr->shared->initialized = FALSE;
done:
/* Cleanup on failure */
- if(ret_value < 0)
- if(attr && H5A_close(attr) < 0)
+ if(ret_value < 0 && attr && H5A_close(attr) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
FUNC_LEAVE_NOAPI(ret_value)
@@ -544,7 +549,7 @@ H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id)
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header")
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(&loc, attr) < 0)
@@ -731,7 +736,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG)
/* Clear object location */
- if(H5O_loc_reset(&(attr->oloc)) < 0)
+ if(H5O_loc_reset(&(attr->shared->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location")
#endif /* H5_USING_MEMCHECKER */
@@ -740,15 +745,15 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
/* Deep copy of the symbol table entry */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy(&(attr->shared->oloc), loc->oloc, H5_COPY_DEEP) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Deep copy of the group hier. path */
if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry")
/* Hold the symbol table entry (and file) open */
- if(H5O_open(&(attr->oloc)) < 0)
+ if(H5O_open(&(attr->shared->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
attr->obj_opened = TRUE;
@@ -799,7 +804,7 @@ H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header")
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(&obj_loc, attr) < 0)
@@ -865,7 +870,7 @@ H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_na
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header")
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(loc, attr) < 0)
@@ -969,7 +974,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HDassert(buf);
/* Get # of elements for attribute's dataspace */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
@@ -977,17 +982,17 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
if(nelmts > 0) {
/* Get the memory and file datatype sizes */
src_type_size = H5T_get_size(mem_type);
- dst_type_size = H5T_get_size(attr->dt);
+ dst_type_size = H5T_get_size(attr->shared->dt);
/* Convert memory buffer into disk buffer */
/* Set up type conversion function */
- if(NULL == (tpath = H5T_path_find(mem_type, attr->dt, NULL, NULL, dxpl_id, FALSE)))
+ if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
/* Check for type conversion required */
if(!H5T_path_noop(tpath)) {
if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL))) < 0)
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
/* Get the maximum buffer size needed and allocate it */
@@ -1003,11 +1008,11 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
/* Free the previous attribute data buffer, if there is one */
- if(attr->data)
- attr->data = H5FL_BLK_FREE(attr_buf, attr->data);
+ if(attr->shared->data)
+ attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
/* Set the pointer to the attribute data to the converted information */
- attr->data = tconv_buf;
+ attr->shared->data = tconv_buf;
tconv_owned = TRUE;
} /* end if */
/* No type conversion necessary */
@@ -1015,21 +1020,21 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HDassert(dst_type_size == src_type_size);
/* Allocate the attribute buffer, if there isn't one */
- if(attr->data == NULL)
- if(NULL == (attr->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts)))
+ if(attr->shared->data == NULL)
+ if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the attribute data into the user's buffer */
- HDmemcpy(attr->data, buf, (dst_type_size * nelmts));
+ HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts));
} /* end else */
/* Modify the attribute in the object header */
- if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0)
+ if(H5O_attr_write(&(attr->shared->oloc), dxpl_id, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute")
} /* end if */
/* Indicate the the attribute doesn't need fill-values */
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
done:
/* Release resources */
@@ -1126,27 +1131,27 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HDassert(buf);
/* Create buffer for data to store on disk */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
if(nelmts > 0) {
/* Get the memory and file datatype sizes */
- src_type_size = H5T_get_size(attr->dt);
+ src_type_size = H5T_get_size(attr->shared->dt);
dst_type_size = H5T_get_size(mem_type);
/* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->obj_opened && !attr->initialized)
+ if(attr->obj_opened && !attr->shared->initialized)
HDmemset(buf, 0, (dst_type_size * nelmts));
else { /* Attribute exists and has a value */
/* Convert memory buffer into disk buffer */
/* Set up type conversion function */
- if(NULL == (tpath = H5T_path_find(attr->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
+ if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
/* Check for type conversion required */
if(!H5T_path_noop(tpath)) {
- if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL))) < 0 ||
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL))) < 0 ||
(dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
@@ -1156,7 +1161,7 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the attribute data into the buffer for conversion */
- HDmemcpy(tconv_buf, attr->data, (src_type_size * nelmts));
+ HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts));
/* Perform datatype conversion. */
if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
@@ -1170,7 +1175,7 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HDassert(dst_type_size == src_type_size);
/* Copy the attribute data into the user's buffer */
- HDmemcpy(buf, attr->data, (dst_type_size * nelmts));
+ HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts));
} /* end else */
} /* end else */
} /* end if */
@@ -1221,7 +1226,7 @@ H5Aget_space(hid_t attr_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Copy the attribute's dataspace */
- if(NULL == (ds = H5S_copy(attr->ds, FALSE, TRUE)))
+ if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace")
/* Atomize */
@@ -1271,7 +1276,7 @@ H5Aget_type(hid_t attr_id)
* reopen the type before returning it to the user. Make the type
* read-only.
*/
- if(NULL == (dt = H5T_copy(attr->dt, H5T_COPY_REOPEN)))
+ if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
@@ -1340,7 +1345,7 @@ H5Aget_create_plist(hid_t attr_id)
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list")
/* Set the character encoding on the new property list */
- if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->encoding)) < 0)
+ if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding")
ret_value = new_plist_id;
@@ -1374,21 +1379,53 @@ done:
ssize_t
H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
{
- H5A_t *attr; /* Attribute object for ID */
- size_t copy_len, nbytes;
+ H5A_t *my_attr; /* Attribute object for ID */
ssize_t ret_value;
FUNC_ENTER_API(H5Aget_name, FAIL)
H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf);
/* check arguments */
- if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (my_attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
if(!buf && buf_size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
+ /* Call private function in turn */
+ if(0 > (ret_value = H5A_get_name(my_attr, buf_size, buf)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aget_name() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5A_get_name
+ PURPOSE
+ Private function for H5Aget_name. Gets a copy of the name for an
+ attribute
+ RETURNS
+ This function returns the length of the attribute's name (which may be
+ longer than 'buf_size') on success or negative for failure.
+ DESCRIPTION
+ This function retrieves the name of an attribute for an attribute ID.
+ Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
+ terminator. If the name of the attribute is longer than 'buf_size'-1,
+ the string terminator is stored in the last position of the buffer to
+ properly terminate the string.
+--------------------------------------------------------------------------*/
+ssize_t
+H5A_get_name(H5A_t *attr, size_t buf_size, char *buf)
+{
+ size_t copy_len, nbytes;
+ ssize_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5A_get_name, FAIL)
+
/* get the real attribute length */
- nbytes = HDstrlen(attr->name);
+ nbytes = HDstrlen(attr->shared->name);
HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/
/* compute the string length which will fit into the user's buffer */
@@ -1396,7 +1433,7 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
/* Copy all/some of the name */
if(buf && copy_len > 0) {
- HDmemcpy(buf, attr->name, copy_len);
+ HDmemcpy(buf, attr->shared->name, copy_len);
/* Terminate the string */
buf[copy_len]='\0';
@@ -1406,8 +1443,8 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
ret_value = (ssize_t)nbytes;
done:
- FUNC_LEAVE_API(ret_value)
-} /* H5Aget_name() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_get_name() */
/*-------------------------------------------------------------------------
@@ -1462,11 +1499,11 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
/* Get the length of the name */
- ret_value = (ssize_t)HDstrlen(attr->name);
+ ret_value = (ssize_t)HDstrlen(attr->shared->name);
/* Copy the name into the user's buffer, if given */
if(name) {
- HDstrncpy(name, attr->name, MIN((size_t)(ret_value + 1), size));
+ HDstrncpy(name, attr->shared->name, MIN((size_t)(ret_value + 1), size));
if((size_t)ret_value >= size)
name[size - 1]='\0';
} /* end if */
@@ -1511,7 +1548,7 @@ H5Aget_storage_size(hid_t attr_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute")
/* Set return value */
- ret_value = attr->data_size;
+ ret_value = attr->shared->data_size;
done:
FUNC_LEAVE_API(ret_value)
@@ -1698,15 +1735,15 @@ H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo)
HDassert(ainfo);
/* Set info for attribute */
- ainfo->cset = attr->encoding;
- ainfo->data_size = attr->data_size;
- if(attr->crt_idx == H5O_MAX_CRT_ORDER_IDX) {
+ ainfo->cset = attr->shared->encoding;
+ ainfo->data_size = attr->shared->data_size;
+ if(attr->shared->crt_idx == H5O_MAX_CRT_ORDER_IDX) {
ainfo->corder_valid = FALSE;
ainfo->corder = 0;
} /* end if */
else {
ainfo->corder_valid = TRUE;
- ainfo->corder = attr->crt_idx;
+ ainfo->corder = attr->shared->crt_idx;
} /* end else */
done:
@@ -2259,6 +2296,10 @@ done:
* Programmer: Robb Matzke
* Thursday, December 4, 1997
*
+ * Modification:Raymond Lu
+ * 4 June 2008
+ * Changed some attribute information to be shared.
+ *
*-------------------------------------------------------------------------
*/
H5A_t *
@@ -2275,7 +2316,7 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr)
/* Allocate attribute structure */
if(_new_attr == NULL) {
- if(NULL == (new_attr = H5FL_MALLOC(H5A_t)))
+ if(NULL == (new_attr = H5FL_CALLOC(H5A_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
allocated_attr = TRUE;
} /* end if */
@@ -2283,44 +2324,20 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr)
new_attr = _new_attr;
/* Copy the top level of the attribute */
- *new_attr = *old_attr;
+ new_attr->sh_loc = old_attr->sh_loc;
- /* Don't open the object header for a copy */
- new_attr->obj_opened = FALSE;
-
- /* Copy the guts of the attribute */
- if(NULL == (new_attr->name = H5MM_xstrdup(old_attr->name)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy attribute name")
- if(NULL == (new_attr->dt = H5T_copy(old_attr->dt, H5T_COPY_ALL)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy attribute datatype")
- if(NULL == (new_attr->ds = H5S_copy(old_attr->ds, FALSE, TRUE)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy attribute dataspace")
-
-#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG)
- /* Clear object location */
- if(H5O_loc_reset(&(new_attr->oloc)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to reset location")
-
- /* Clear path name */
- if(H5G_name_reset(&(new_attr->path)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to reset path")
-#endif /* H5_USING_MEMCHECKER */
-
- /* Copy the object location and group path */
- if(H5O_loc_copy(&(new_attr->oloc), &(old_attr->oloc), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy object location")
+ /* Deep copy of the group hierarchy path */
if(H5G_name_copy(&(new_attr->path), &(old_attr->path), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy path")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path")
- /* Copy the attribute data, if there is any */
- if(old_attr->data) {
- /* Allocate data buffer for new attribute */
- if(NULL == (new_attr->data = H5FL_BLK_MALLOC(attr_buf, old_attr->data_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Share some attribute information */
+ new_attr->shared = old_attr->shared;
- /* Copy the attribute data */
- HDmemcpy(new_attr->data, old_attr->data, old_attr->data_size);
- } /* end if */
+ /* Increment reference count for shared object */
+ new_attr->shared->nrefs++;
+
+ /* Don't open the object header for a copy */
+ new_attr->obj_opened = FALSE;
/* Set the return value */
ret_value = new_attr;
@@ -2359,18 +2376,22 @@ H5A_free(H5A_t *attr)
HDassert(attr);
/* Free dynamicly allocated items */
- if(attr->name)
- H5MM_xfree(attr->name);
- if(attr->dt)
- if(H5T_close(attr->dt) < 0)
+ if(attr->shared->name) {
+ H5MM_xfree(attr->shared->name);
+ attr->shared->name = NULL;
+ }
+ if(attr->shared->dt) {
+ if(H5T_close(attr->shared->dt) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
- if(attr->ds)
- if(H5S_close(attr->ds) < 0)
+ attr->shared->dt = NULL;
+ }
+ if(attr->shared->ds) {
+ if(H5S_close(attr->shared->ds) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
- if(attr->data)
- attr->data = H5FL_BLK_FREE(attr_buf, attr->data);
- if(H5G_name_free(&(attr->path)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
+ attr->shared->ds = NULL;
+ }
+ if(attr->shared->data)
+ attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2388,7 +2409,9 @@ done:
* Monday, December 8, 1997
*
* Modifications:
- *
+ * Raymond Lu
+ * 4 June 2008
+ * Changed some attribute object information to be shared.
*-------------------------------------------------------------------------
*/
herr_t
@@ -2399,30 +2422,31 @@ H5A_close(H5A_t *attr)
FUNC_ENTER_NOAPI(H5A_close, FAIL)
HDassert(attr);
-
- /* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->obj_opened && !attr->initialized && attr->data_size) {
- uint8_t *tmp_buf = H5FL_BLK_CALLOC(attr_buf, attr->data_size);
- if(NULL == tmp_buf)
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed for attribute fill-value")
-
- /* Go write the fill data to the attribute */
- if(H5A_write(attr, attr->dt, tmp_buf, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
-
- /* Free temporary buffer */
- H5FL_BLK_FREE(attr_buf, tmp_buf);
- } /* end if */
-
- /* Free dynamicly allocated items */
- if(H5A_free(attr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
+ HDassert(attr->shared);
/* Close the object's symbol-table entry */
- if(attr->obj_opened)
- if(H5O_close(&(attr->oloc)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
+ if(attr->obj_opened && (H5O_close(&(attr->shared->oloc)) < 0))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
+
+ /* Reference count can be 0. It only happens when H5A_create fails. */
+ if(1 >= attr->shared->nrefs) {
+ /* Free dynamicly allocated items */
+ if(H5A_free(attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
+
+ /* Destroy shared attribute struct */
+ attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
+ } else if(attr->shared->nrefs > 1) {
+ /* There are other references to the shared part of the attribute.
+ * Only decrement the reference count. */
+ --attr->shared->nrefs;
+ }
+
+ /* Free group hierarchy path */
+ if(H5G_name_free(&(attr->path)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
+ attr->shared = NULL;
H5FL_FREE(H5A_t, attr);
done:
@@ -2455,7 +2479,7 @@ H5A_oloc(H5A_t *attr)
HDassert(attr);
/* Set return value */
- ret_value = &(attr->oloc);
+ ret_value = &(attr->shared->oloc);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c
index b685af7..07550da 100644
--- a/src/H5Abtree2.c
+++ b/src/H5Abtree2.c
@@ -172,7 +172,7 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode attribute")
/* Compare the string values */
- udata->cmp = HDstrcmp(udata->name, attr->name);
+ udata->cmp = HDstrcmp(udata->name, attr->shared->name);
/* Check for correct attribute & callback to make */
if(udata->cmp == 0 && udata->found_op) {
@@ -181,7 +181,7 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
H5SM_reconstitute(&(attr->sh_loc), udata->f, H5O_ATTR_ID, udata->record->id);
/* Set the creation order index for the attribute */
- attr->crt_idx = udata->record->corder;
+ attr->shared->crt_idx = udata->record->corder;
/* Make callback */
if((udata->found_op)(attr, &took_ownership, udata->found_op_data) < 0)
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 45537be..79cd6fe 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -502,10 +502,10 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
udata.common.dxpl_id = dxpl_id;
udata.common.fheap = fheap;
udata.common.shared_fheap = shared_fheap;
- udata.common.name = attr->name;
- udata.common.name_hash = H5_checksum_lookup3(attr->name, HDstrlen(attr->name), 0);
+ udata.common.name = attr->shared->name;
+ udata.common.name_hash = H5_checksum_lookup3(attr->shared->name, HDstrlen(attr->shared->name), 0);
H5_ASSIGN_OVERFLOW(udata.common.flags, mesg_flags, unsigned, uint8_t);
- udata.common.corder = attr->crt_idx;
+ udata.common.corder = attr->shared->crt_idx;
udata.common.found_op = NULL;
udata.common.found_op_data = NULL;
/* udata.id already set */
@@ -624,7 +624,7 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
udata.name = NULL;
udata.name_hash = 0;
udata.flags = 0;
- udata.corder = op_data->attr->crt_idx;
+ udata.corder = op_data->attr->shared->crt_idx;
udata.found_op = NULL;
udata.found_op_data = NULL;
@@ -744,8 +744,8 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
udata.dxpl_id = dxpl_id;
udata.fheap = fheap;
udata.shared_fheap = shared_fheap;
- udata.name = attr->name;
- udata.name_hash = H5_checksum_lookup3(attr->name, HDstrlen(attr->name), 0);
+ udata.name = attr->shared->name;
+ udata.name_hash = H5_checksum_lookup3(attr->shared->name, HDstrlen(attr->shared->name), 0);
udata.flags = 0;
udata.corder = 0;
udata.found_op = NULL;
@@ -807,7 +807,7 @@ H5A_dense_copy_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, FAIL, "can't decode attribute")
/* Set the creation order index for the attribute */
- udata->attr->crt_idx = udata->record->corder;
+ udata->attr->shared->crt_idx = udata->record->corder;
/* Check whether we should "reconstitute" the shared message info */
if(udata->record->flags & H5O_MSG_FLAG_SHARED)
@@ -904,8 +904,8 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
} /* end if */
/* Change name of attribute */
- H5MM_xfree(attr_copy->name);
- attr_copy->name = H5MM_xstrdup(new_name);
+ H5MM_xfree(attr_copy->shared->name);
+ attr_copy->shared->name = H5MM_xstrdup(new_name);
/* Recompute the version to encode the attribute with */
if(H5A_set_version(f, attr_copy) < 0)
@@ -1020,14 +1020,14 @@ H5A_dense_iterate_bt2_cb(const void *_record, void *_bt2_udata)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5_ITER_ERROR, "unable to get attribute info")
/* Make the application callback */
- ret_value = (bt2_udata->attr_op->u.app_op2)(bt2_udata->loc_id, fh_udata.attr->name, &ainfo, bt2_udata->op_data);
+ ret_value = (bt2_udata->attr_op->u.app_op2)(bt2_udata->loc_id, fh_udata.attr->shared->name, &ainfo, bt2_udata->op_data);
break;
}
#ifndef H5_NO_DEPRECATED_SYMBOLS
case H5A_ATTR_OP_APP:
/* Make the application callback */
- ret_value = (bt2_udata->attr_op->u.app_op)(bt2_udata->loc_id, fh_udata.attr->name, bt2_udata->op_data);
+ ret_value = (bt2_udata->attr_op->u.app_op)(bt2_udata->loc_id, fh_udata.attr->shared->name, bt2_udata->op_data);
break;
#endif /* H5_NO_DEPRECATED_SYMBOLS */
@@ -1220,7 +1220,7 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_udata)
/* Check for removing the link from the creation order index */
if(H5F_addr_defined(udata->corder_bt2_addr)) {
/* Set up the user data for the v2 B-tree 'record remove' callback */
- udata->common.corder = attr->crt_idx;
+ udata->common.corder = attr->shared->crt_idx;
/* Remove the record from the creation order index v2 B-tree */
if(H5B2_remove(udata->common.f, udata->common.dxpl_id, H5A_BT2_CORDER, udata->corder_bt2_addr, udata, NULL, NULL) < 0)
@@ -1400,7 +1400,7 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
other_bt2_class = H5A_BT2_CORDER;
/* Set up the user data for the v2 B-tree 'record remove' callback */
- other_bt2_udata.corder = fh_udata.attr->crt_idx;
+ other_bt2_udata.corder = fh_udata.attr->shared->crt_idx;
} /* end if */
else {
HDassert(bt2_udata->idx_type == H5_INDEX_CRT_ORDER);
@@ -1413,8 +1413,8 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
other_bt2_udata.dxpl_id = bt2_udata->dxpl_id;
other_bt2_udata.fheap = bt2_udata->fheap;
other_bt2_udata.shared_fheap = bt2_udata->shared_fheap;
- other_bt2_udata.name = fh_udata.attr->name;
- other_bt2_udata.name_hash = H5_checksum_lookup3(fh_udata.attr->name, HDstrlen(fh_udata.attr->name), 0);
+ other_bt2_udata.name = fh_udata.attr->shared->name;
+ other_bt2_udata.name_hash = H5_checksum_lookup3(fh_udata.attr->shared->name, HDstrlen(fh_udata.attr->shared->name), 0);
other_bt2_udata.found_op = NULL;
other_bt2_udata.found_op_data = NULL;
} /* end else */
@@ -1570,7 +1570,7 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
/* Delete appropriate attribute from dense storage */
- if(H5A_dense_remove(f, dxpl_id, ainfo, atable.attrs[n].name) < 0)
+ if(H5A_dense_remove(f, dxpl_id, ainfo, ((atable.attrs[n])->shared)->name) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute in dense storage")
} /* end else */
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 71b6689..23a4e15 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -100,6 +100,8 @@ static herr_t H5A_attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type,
/* Local Variables */
/*******************/
+typedef H5A_t* H5A_t_ptr;
+H5FL_SEQ_DEFINE(H5A_t_ptr);
/*-------------------------------------------------------------------------
@@ -114,6 +116,10 @@ static herr_t H5A_attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type,
* koziol@hdfgroup.org
* Dec 18 2006
*
+ * Modification:Raymond Lu
+ * 24 June 2008
+ * Changed the table of attribute objects to be the table of
+ * pointers to attribute objects for the ease of operation.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -128,11 +134,23 @@ H5A_compact_build_table_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
/* check args */
HDassert(mesg);
- /* Check for re-allocating table */
+ /* Re-allocate the table if necessary */
if(udata->curr_attr == udata->atable->nattrs) {
+ size_t i;
size_t n = MAX(1, 2 * udata->atable->nattrs);
- H5A_t *table = (H5A_t *)H5MM_realloc(udata->atable->attrs,
- n * sizeof(H5A_t));
+ H5A_t **table = (H5A_t **)H5FL_SEQ_CALLOC(H5A_t_ptr, n);
+
+ /* Use attribute functions for operation */
+ for(i=0; i<udata->atable->nattrs; i++) {
+ table[i] = (H5A_t *)H5FL_CALLOC(H5A_t);
+ if(NULL == H5A_copy(table[i], udata->atable->attrs[i]))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+ if(H5A_close(udata->atable->attrs[i]) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "can't close attribute")
+ }
+
+ if(udata->atable->nattrs)
+ udata->atable->attrs = (H5A_t **)H5FL_SEQ_FREE(H5A_t_ptr, udata->atable->attrs);
if(!table)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "unable to extend attribute table")
@@ -141,12 +159,14 @@ H5A_compact_build_table_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
} /* end if */
/* Copy attribute into table */
- if(NULL == H5A_copy(&udata->atable->attrs[udata->curr_attr], (const H5A_t *)mesg->native))
+ udata->atable->attrs[udata->curr_attr] = (H5A_t *)H5FL_CALLOC(H5A_t);
+
+ if(NULL == H5A_copy(udata->atable->attrs[udata->curr_attr], (const H5A_t *)mesg->native))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
/* Assign [somewhat arbitrary] creation order value, if requested */
if(udata->bogus_crt_idx)
- udata->atable->attrs[udata->curr_attr].crt_idx = sequence;
+ ((udata->atable->attrs[udata->curr_attr])->shared)->crt_idx = sequence;
/* Increment current attribute */
udata->curr_attr++;
@@ -246,8 +266,8 @@ H5A_dense_build_table_cb(const H5A_t *attr, void *_udata)
HDassert(udata);
HDassert(udata->curr_attr < udata->atable->nattrs);
- /* Copy attribute information */
- if(NULL == H5A_copy(&udata->atable->attrs[udata->curr_attr], attr))
+ /* Copy attribute information. Share the attribute object in copying. */
+ if(NULL == H5A_copy(udata->atable->attrs[udata->curr_attr], attr))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
/* Increment number of attributes stored */
@@ -305,11 +325,17 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
if(atable->nattrs > 0) {
H5A_dense_bt_ud_t udata; /* User data for iteration callback */
H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ unsigned i;
/* Allocate the table to store the attributes */
- if((atable->attrs = (H5A_t *)H5MM_malloc(sizeof(H5A_t) * atable->nattrs)) == NULL)
+ if((atable->attrs = (H5A_t **)H5FL_SEQ_MALLOC(H5A_t_ptr, atable->nattrs)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Allocate pointers for each entry in the table */
+ for(i=0; i<atable->nattrs; i++)
+ if((atable->attrs[i] = (H5A_t *)H5FL_CALLOC(H5A_t)) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
/* Set up user data for iteration */
udata.atable = atable;
udata.curr_attr = 0;
@@ -358,7 +384,8 @@ H5A_attr_cmp_name_inc(const void *attr1, const void *attr2)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_name_inc)
- FUNC_LEAVE_NOAPI(HDstrcmp(((const H5A_t *)attr1)->name, ((const H5A_t *)attr2)->name))
+ FUNC_LEAVE_NOAPI(HDstrcmp((*(const H5A_t **)attr1)->shared->name,
+ (*(const H5A_t **)attr2)->shared->name))
} /* end H5A_attr_cmp_name_inc() */
@@ -385,7 +412,8 @@ H5A_attr_cmp_name_dec(const void *attr1, const void *attr2)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_name_dec)
- FUNC_LEAVE_NOAPI(HDstrcmp(((const H5A_t *)attr2)->name, ((const H5A_t *)attr1)->name))
+ FUNC_LEAVE_NOAPI(HDstrcmp((*(const H5A_t **)attr2)->shared->name,
+ (*(const H5A_t **)attr1)->shared->name))
} /* end H5A_attr_cmp_name_dec() */
@@ -413,9 +441,9 @@ H5A_attr_cmp_corder_inc(const void *attr1, const void *attr2)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_corder_inc)
- if(((const H5A_t *)attr1)->crt_idx < ((const H5A_t *)attr2)->crt_idx)
+ if((*(const H5A_t **)attr1)->shared->crt_idx < (*(const H5A_t **)attr2)->shared->crt_idx)
ret_value = -1;
- else if(((const H5A_t *)attr1)->crt_idx > ((const H5A_t *)attr2)->crt_idx)
+ else if((*(const H5A_t **)attr1)->shared->crt_idx > (*(const H5A_t **)attr2)->shared->crt_idx)
ret_value = 1;
else
ret_value = 0;
@@ -448,9 +476,9 @@ H5A_attr_cmp_corder_dec(const void *attr1, const void *attr2)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_corder_dec)
- if(((const H5A_t *)attr1)->crt_idx < ((const H5A_t *)attr2)->crt_idx)
+ if((*(const H5A_t **)attr1)->shared->crt_idx < (*(const H5A_t **)attr2)->shared->crt_idx)
ret_value = 1;
- else if(((const H5A_t *)attr1)->crt_idx > ((const H5A_t *)attr2)->crt_idx)
+ else if((*(const H5A_t **)attr1)->shared->crt_idx > (*(const H5A_t **)attr2)->shared->crt_idx)
ret_value = -1;
else
ret_value = 0;
@@ -484,18 +512,18 @@ H5A_attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type,
/* Pick appropriate comparison routine */
if(idx_type == H5_INDEX_NAME) {
if(order == H5_ITER_INC)
- HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_name_inc);
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t*), H5A_attr_cmp_name_inc);
else if(order == H5_ITER_DEC)
- HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_name_dec);
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t*), H5A_attr_cmp_name_dec);
else
HDassert(order == H5_ITER_NATIVE);
} /* end if */
else {
HDassert(idx_type == H5_INDEX_CRT_ORDER);
if(order == H5_ITER_INC)
- HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_corder_inc);
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t*), H5A_attr_cmp_corder_inc);
else if(order == H5_ITER_DEC)
- HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_corder_dec);
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t*), H5A_attr_cmp_corder_dec);
else
HDassert(order == H5_ITER_NATIVE);
} /* end else */
@@ -546,24 +574,24 @@ H5A_attr_iterate_table(const H5A_attr_table_t *atable, hsize_t skip,
H5A_info_t ainfo; /* Info for attribute */
/* Get the attribute information */
- if(H5A_get_info(&atable->attrs[u], &ainfo) < 0)
+ if(H5A_get_info(atable->attrs[u], &ainfo) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5_ITER_ERROR, "unable to get attribute info")
/* Make the application callback */
- ret_value = (attr_op->u.app_op2)(loc_id, atable->attrs[u].name, &ainfo, op_data);
+ ret_value = (attr_op->u.app_op2)(loc_id, ((atable->attrs[u])->shared)->name, &ainfo, op_data);
break;
}
#ifndef H5_NO_DEPRECATED_SYMBOLS
case H5A_ATTR_OP_APP:
/* Make the application callback */
- ret_value = (attr_op->u.app_op)(loc_id, atable->attrs[u].name, op_data);
+ ret_value = (attr_op->u.app_op)(loc_id, ((atable->attrs[u])->shared)->name, op_data);
break;
#endif /* H5_NO_DEPRECATED_SYMBOLS */
case H5A_ATTR_OP_LIB:
/* Call the library's callback */
- ret_value = (attr_op->u.lib_op)(&(atable->attrs[u]), op_data);
+ ret_value = (attr_op->u.lib_op)((atable->attrs[u]), op_data);
break;
default:
@@ -588,22 +616,25 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5A_attr_release_table
+ * Function: H5A_attr_release_table
*
- * Purpose: Release table containing a list of attributes for an object
+ * Purpose: Release table containing a list of attributes for an object
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Programmer: Quincey Koziol
- * Dec 11, 2006
+ * Programmer: Quincey Koziol
+ * Dec 11, 2006
*
+ * Modification: Raymond Lu
+ * 4 June 2008
+ * Changed from H5A_free to H5A_close to release attributes.
*-------------------------------------------------------------------------
*/
herr_t
H5A_attr_release_table(H5A_attr_table_t *atable)
{
- size_t u; /* Local index variable */
+ size_t u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_attr_release_table)
@@ -611,19 +642,19 @@ H5A_attr_release_table(H5A_attr_table_t *atable)
/* Sanity check */
HDassert(atable);
- /* Release attribute info, if any */
+ /* Release attribute info, if any. */
if(atable->nattrs > 0) {
/* Free attribute message information */
- for(u = 0; u < atable->nattrs; u++)
- if(H5A_free(&(atable->attrs[u])) < 0)
+ for(u = 0; u < atable->nattrs; u++) {
+ if(H5A_close((atable->attrs[u])) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute")
-
- /* Free table of attributes */
- H5MM_xfree(atable->attrs);
+ }
} /* end if */
else
HDassert(atable->attrs == NULL);
+ atable->attrs = (H5A_t **)H5FL_SEQ_FREE(H5A_t_ptr, atable->attrs);
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_attr_release_table() */
@@ -711,25 +742,25 @@ H5A_set_version(const H5F_t *f, H5A_t *attr)
use_latest_format = H5F_USE_LATEST_FORMAT(f);
/* Check whether datatype and dataspace are shared */
- if(H5O_msg_is_shared(H5O_DTYPE_ID, attr->dt) > 0)
+ if(H5O_msg_is_shared(H5O_DTYPE_ID, attr->shared->dt) > 0)
type_shared = TRUE;
else
type_shared = FALSE;
- if(H5O_msg_is_shared(H5O_SDSPACE_ID, attr->ds) > 0)
+ if(H5O_msg_is_shared(H5O_SDSPACE_ID, attr->shared->ds) > 0)
space_shared = TRUE;
else
space_shared = FALSE;
/* Check which version to encode attribute with */
if(use_latest_format)
- attr->version = H5O_ATTR_VERSION_LATEST; /* Write out latest version of format */
- else if(attr->encoding != H5T_CSET_ASCII)
- attr->version = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */
+ attr->shared->version = H5O_ATTR_VERSION_LATEST; /* Write out latest version of format */
+ else if(attr->shared->encoding != H5T_CSET_ASCII)
+ attr->shared->version = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */
else if(type_shared || space_shared)
- attr->version = H5O_ATTR_VERSION_2; /* Write out version with flag for indicating shared datatype or dataspace */
+ attr->shared->version = H5O_ATTR_VERSION_2; /* Write out version with flag for indicating shared datatype or dataspace */
else
- attr->version = H5O_ATTR_VERSION_1; /* Write out basic version */
+ attr->shared->version = H5O_ATTR_VERSION_1; /* Write out basic version */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5A_set_version() */
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 049877e..a1b5e62 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -72,16 +72,11 @@
/****************************/
/* Package Private Typedefs */
/****************************/
-
-/* Define the main attribute structure */
-struct H5A_t {
- H5O_shared_t sh_loc; /* Shared message info (must be first) */
-
+/* Define the shared attribute structure */
+typedef struct H5A_shared_t {
unsigned version; /* Version to encode attribute with */
hbool_t initialized;/* Indicate whether the attribute has been modified */
- hbool_t obj_opened; /* Object header entry opened? */
H5O_loc_t oloc; /* Object location for object attribute is on */
- H5G_name_t path; /* Group hierarchy path */
char *name; /* Attribute's name */
H5T_cset_t encoding; /* Character encoding of attribute name */
@@ -95,6 +90,15 @@ struct H5A_t {
void *data; /* Attribute data (on a temporary basis) */
size_t data_size; /* Size of data on disk */
H5O_msg_crt_idx_t crt_idx; /* Attribute's creation index in the object header */
+ unsigned nrefs; /* Ref count for times this object is refered */
+} H5A_shared_t;
+
+/* Define the main attribute structure */
+struct H5A_t {
+ H5O_shared_t sh_loc; /* Shared message info (must be first) */
+ hbool_t obj_opened; /* Object header entry opened? */
+ H5G_name_t path; /* Group hierarchy path */
+ H5A_shared_t *shared; /* Shared attribute information */
};
/* Typedefs for "dense" attribute storage */
@@ -152,7 +156,7 @@ typedef struct H5A_bt2_ud_ins_t {
/* Data structure to hold table of attributes for an object */
typedef struct {
size_t nattrs; /* # of attributes in table */
- H5A_t *attrs; /* Pointer to array of attributes */
+ H5A_t **attrs; /* Pointer to array of attribute pointers */
} H5A_attr_table_t;
/* Attribute iteration operator for internal library callbacks */
@@ -184,6 +188,9 @@ struct H5A_attr_iter_op_t {
/* Declare extern the free list for H5A_t's */
H5FL_EXTERN(H5A_t);
+/* Declare the external free lists for H5A_shared_t's */
+H5FL_EXTERN(H5A_shared_t);
+
/* Declare extern a free list to manage blocks of type conversion data */
H5FL_BLK_EXTERN(attr_buf);
@@ -206,6 +213,7 @@ H5_DLL H5A_t * H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name,
const char *attr_name, hid_t lapl_id, hid_t dxpl_id);
H5_DLL H5A_t *H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t dxpl_id);
+H5_DLL ssize_t H5A_get_name(H5A_t *attr, size_t buf_size, char *buf);
H5_DLL H5A_t *H5A_copy(H5A_t *new_attr, const H5A_t *old_attr);
H5_DLL herr_t H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo);
H5_DLL herr_t H5A_free(H5A_t *attr);
diff --git a/src/H5Atest.c b/src/H5Atest.c
index df88472..de03a25 100644
--- a/src/H5Atest.c
+++ b/src/H5Atest.c
@@ -139,7 +139,7 @@ H5A_get_shared_rc_test(hid_t attr_id, hsize_t *ref_count)
HDassert(H5O_msg_is_shared(H5O_ATTR_ID, attr));
/* Retrieve ref count for shared or shareable attribute */
- if(H5SM_get_refcount(attr->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID,
+ if(H5SM_get_refcount(attr->shared->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID,
&attr->sh_loc, ref_count) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count")
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index adca14c..4bfeb3d 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -77,7 +77,7 @@ const H5O_msg_class_t H5O_MSG_ATTR[1] = {{
H5O_attr_shared_encode, /* encode message */
H5O_attr_copy, /* copy the native value */
H5O_attr_shared_size, /* size of raw message */
- H5O_attr_reset, /* reset method */
+ H5O_attr_reset, /* reset method */
H5O_attr_free, /* free method */
H5O_attr_shared_delete, /* file delete method */
H5O_attr_shared_link, /* link method */
@@ -141,13 +141,16 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
if(NULL == (attr = H5FL_CALLOC(H5A_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
+
/* Version number */
- attr->version = *p++;
- if(attr->version < H5O_ATTR_VERSION_1 || attr->version > H5O_ATTR_VERSION_LATEST)
+ attr->shared->version = *p++;
+ if(attr->shared->version < H5O_ATTR_VERSION_1 || attr->shared->version > H5O_ATTR_VERSION_LATEST)
HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "bad version number for attribute message")
/* Get the flags byte if we have a later version of the attribute */
- if(attr->version >= H5O_ATTR_VERSION_2) {
+ if(attr->shared->version >= H5O_ATTR_VERSION_2) {
flags = *p++;
/* Check for unknown flag */
@@ -162,36 +165,36 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
* the file are exact but the parts are aligned on 8-byte boundaries.
*/
UINT16DECODE(p, name_len); /*including null*/
- UINT16DECODE(p, attr->dt_size);
- UINT16DECODE(p, attr->ds_size);
+ UINT16DECODE(p, attr->shared->dt_size);
+ UINT16DECODE(p, attr->shared->ds_size);
/*
* Decode the character encoding for the name for versions 3 or later,
* as well as some reserved bytes.
*/
- if(attr->version >= H5O_ATTR_VERSION_3)
- attr->encoding = *p++;
+ if(attr->shared->version >= H5O_ATTR_VERSION_3)
+ attr->shared->encoding = *p++;
/* Decode and store the name */
- if(NULL == (attr->name = H5MM_strdup((const char *)p)))
+ if(NULL == (attr->shared->name = H5MM_strdup((const char *)p)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- if(attr->version < H5O_ATTR_VERSION_2)
+ if(attr->shared->version < H5O_ATTR_VERSION_2)
p += H5O_ALIGN_OLD(name_len); /* advance the memory pointer */
else
p += name_len; /* advance the memory pointer */
/* Decode the attribute's datatype */
- if((attr->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL)
+ if((attr->shared->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype")
- if(attr->version < H5O_ATTR_VERSION_2)
- p += H5O_ALIGN_OLD(attr->dt_size);
+ if(attr->shared->version < H5O_ATTR_VERSION_2)
+ p += H5O_ALIGN_OLD(attr->shared->dt_size);
else
- p += attr->dt_size;
+ p += attr->shared->dt_size;
/* decode the attribute dataspace. It can be shared in versions >= 3
* What's actually shared, though, is only the extent.
*/
- if(NULL == (attr->ds = H5FL_CALLOC(H5S_t)))
+ if(NULL == (attr->shared->ds = H5FL_CALLOC(H5S_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Decode attribute's dataspace extent */
@@ -199,32 +202,36 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace")
/* Copy the extent information to the dataspace */
- HDmemcpy(&(attr->ds->extent), extent, sizeof(H5S_extent_t));
+ HDmemcpy(&(attr->shared->ds->extent), extent, sizeof(H5S_extent_t));
/* Release temporary extent information */
H5FL_FREE(H5S_extent_t, extent);
/* Default to entire dataspace being selected */
- if(H5S_select_all(attr->ds, FALSE) < 0)
+ if(H5S_select_all(attr->shared->ds, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
- if(attr->version < H5O_ATTR_VERSION_2)
- p += H5O_ALIGN_OLD(attr->ds_size);
+ if(attr->shared->version < H5O_ATTR_VERSION_2)
+ p += H5O_ALIGN_OLD(attr->shared->ds_size);
else
- p += attr->ds_size;
+ p += attr->shared->ds_size;
/* Compute the size of the data */
- H5_ASSIGN_OVERFLOW(attr->data_size, H5S_GET_EXTENT_NPOINTS(attr->ds) * H5T_get_size(attr->dt), hsize_t, size_t);
+ H5_ASSIGN_OVERFLOW(attr->shared->data_size, H5S_GET_EXTENT_NPOINTS(attr->shared->ds) * H5T_get_size(attr->shared->dt), hsize_t, size_t);
/* Go get the data */
- if(attr->data_size) {
- if(NULL == (attr->data = H5FL_BLK_MALLOC(attr_buf, attr->data_size)))
+ if(attr->shared->data_size) {
+ if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, attr->shared->data_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemcpy(attr->data, p, attr->data_size);
+ HDmemcpy(attr->shared->data, p, attr->shared->data_size);
} /* end if */
/* Indicate that the fill values aren't to be written out */
- attr->initialized = 1;
+ attr->shared->initialized = 1;
+
+ /* Increment the reference count for this object header message in cache(compact
+ storage) or for the object from dense storage. */
+ attr->shared->nrefs++;
/* Set return value */
ret_value = attr;
@@ -268,17 +275,17 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
HDassert(attr);
/* Check whether datatype and dataspace are shared */
- if((is_type_shared = H5O_msg_is_shared(H5O_DTYPE_ID, attr->dt)) < 0)
+ if((is_type_shared = H5O_msg_is_shared(H5O_DTYPE_ID, attr->shared->dt)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't determine if datatype is shared")
- if((is_space_shared = H5O_msg_is_shared(H5O_SDSPACE_ID, attr->ds)) < 0)
+ if((is_space_shared = H5O_msg_is_shared(H5O_SDSPACE_ID, attr->shared->ds)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't determine if dataspace is shared")
/* Encode Version */
- *p++ = attr->version;
+ *p++ = attr->shared->version;
/* Set attribute flags if version >1 */
- if(attr->version >= H5O_ATTR_VERSION_2) {
+ if(attr->shared->version >= H5O_ATTR_VERSION_2) {
flags = (is_type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 );
flags |= (is_space_shared ? H5O_ATTR_FLAG_SPACE_SHARED : 0);
*p++ = flags; /* Set flags for attribute */
@@ -291,18 +298,18 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
* encoded lengths are exact but we pad each part except the data to be a
* multiple of eight bytes (in the first version).
*/
- name_len = HDstrlen(attr->name) + 1;
+ name_len = HDstrlen(attr->shared->name) + 1;
UINT16ENCODE(p, name_len);
- UINT16ENCODE(p, attr->dt_size);
- UINT16ENCODE(p, attr->ds_size);
+ UINT16ENCODE(p, attr->shared->dt_size);
+ UINT16ENCODE(p, attr->shared->ds_size);
/* The character encoding for the attribute's name, in later versions */
- if(attr->version >= H5O_ATTR_VERSION_3)
- *p++ = attr->encoding;
+ if(attr->shared->version >= H5O_ATTR_VERSION_3)
+ *p++ = attr->shared->encoding;
/* Write the name including null terminator */
- HDmemcpy(p, attr->name, name_len);
- if(attr->version < H5O_ATTR_VERSION_2) {
+ HDmemcpy(p, attr->shared->name, name_len);
+ if(attr->shared->version < H5O_ATTR_VERSION_2) {
/* Pad to the correct number of bytes */
HDmemset(p + name_len, 0, H5O_ALIGN_OLD(name_len) - name_len);
p += H5O_ALIGN_OLD(name_len);
@@ -311,32 +318,32 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
p += name_len;
/* encode the attribute datatype */
- if((H5O_MSG_DTYPE->encode)(f, FALSE, p, attr->dt) < 0)
+ if((H5O_MSG_DTYPE->encode)(f, FALSE, p, attr->shared->dt) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype")
- if(attr->version < H5O_ATTR_VERSION_2) {
- HDmemset(p + attr->dt_size, 0, H5O_ALIGN_OLD(attr->dt_size) - attr->dt_size);
- p += H5O_ALIGN_OLD(attr->dt_size);
+ if(attr->shared->version < H5O_ATTR_VERSION_2) {
+ HDmemset(p + attr->shared->dt_size, 0, H5O_ALIGN_OLD(attr->shared->dt_size) - attr->shared->dt_size);
+ p += H5O_ALIGN_OLD(attr->shared->dt_size);
} /* end if */
else
- p += attr->dt_size;
+ p += attr->shared->dt_size;
/* encode the attribute dataspace */
- if((H5O_MSG_SDSPACE->encode)(f, FALSE, p, &(attr->ds->extent)) < 0)
+ if((H5O_MSG_SDSPACE->encode)(f, FALSE, p, &(attr->shared->ds->extent)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace")
- if(attr->version < H5O_ATTR_VERSION_2) {
- HDmemset(p + attr->ds_size, 0, H5O_ALIGN_OLD(attr->ds_size) - attr->ds_size);
- p += H5O_ALIGN_OLD(attr->ds_size);
+ if(attr->shared->version < H5O_ATTR_VERSION_2) {
+ HDmemset(p + attr->shared->ds_size, 0, H5O_ALIGN_OLD(attr->shared->ds_size) - attr->shared->ds_size);
+ p += H5O_ALIGN_OLD(attr->shared->ds_size);
} /* end if */
else
- p += attr->ds_size;
+ p += attr->shared->ds_size;
- /* Store attribute data */
- if(attr->data)
- HDmemcpy(p, attr->data, attr->data_size);
+ /* Store attribute data. If there's no data, store 0 as fill value. */
+ if(attr->shared->data)
+ HDmemcpy(p, attr->shared->data, attr->shared->data_size);
else
- HDmemset(p, 0, attr->data_size);
+ HDmemset(p, 0, attr->shared->data_size);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -412,25 +419,25 @@ H5O_attr_size(const H5F_t UNUSED *f, const void *_mesg)
2; /*space size */
/* Length of attribute name */
- name_len = HDstrlen(attr->name) + 1;
+ name_len = HDstrlen(attr->shared->name) + 1;
/* Version-specific size information */
- if(attr->version == H5O_ATTR_VERSION_1)
+ if(attr->shared->version == H5O_ATTR_VERSION_1)
ret_value += H5O_ALIGN_OLD(name_len) + /*attribute name */
- H5O_ALIGN_OLD(attr->dt_size) + /*datatype */
- H5O_ALIGN_OLD(attr->ds_size) + /*dataspace */
- attr->data_size; /*the data itself */
- else if(attr->version == H5O_ATTR_VERSION_2)
+ H5O_ALIGN_OLD(attr->shared->dt_size) + /*datatype */
+ H5O_ALIGN_OLD(attr->shared->ds_size) + /*dataspace */
+ attr->shared->data_size; /*the data itself */
+ else if(attr->shared->version == H5O_ATTR_VERSION_2)
ret_value += name_len + /*attribute name */
- attr->dt_size + /*datatype */
- attr->ds_size + /*dataspace */
- attr->data_size; /*the data itself */
- else if(attr->version == H5O_ATTR_VERSION_3)
+ attr->shared->dt_size + /*datatype */
+ attr->shared->ds_size + /*dataspace */
+ attr->shared->data_size; /*the data itself */
+ else if(attr->shared->version == H5O_ATTR_VERSION_3)
ret_value += 1 + /*character encoding */
name_len + /*attribute name */
- attr->dt_size + /*datatype */
- attr->ds_size + /*dataspace */
- attr->data_size; /*the data itself */
+ attr->shared->dt_size + /*datatype */
+ attr->shared->ds_size + /*dataspace */
+ attr->shared->data_size; /*the data itself */
else
HDassert(0 && "Bad attribute version");
@@ -449,18 +456,20 @@ H5O_attr_size(const H5F_t UNUSED *f, const void *_mesg)
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
*
+ * Modification:Raymond Lu
+ * 25 June 2008
+ * Made this function empty. The freeing action is actually
+ * done in H5O_attr_free (see H5O_msg_free_real). But this
+ * empty reset function needs to be here. Otherwise, the
+ * caller function H5O_msg_reset_real will zero-set the whole
+ * message.
*-------------------------------------------------------------------------
*/
herr_t
H5O_attr_reset(void *_mesg)
{
- H5A_t *attr = (H5A_t *)_mesg;
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_reset)
- if(attr)
- H5A_free(attr);
-
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_attr_reset() */
@@ -475,18 +484,27 @@ H5O_attr_reset(void *_mesg)
* Programmer: Quincey Koziol
* Thursday, November 18, 2004
*
+ * Modification:Raymond Lu
+ * 4 June 2008
+ * Let this function call H5A_close in turn.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
H5O_attr_free(void *mesg)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_free)
+ H5A_t *attr = (H5A_t *)mesg;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_free)
HDassert(mesg);
- H5FL_FREE(H5A_t, mesg);
+ if(H5A_close(attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "unable to close attribute object")
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_free() */
@@ -515,11 +533,11 @@ H5O_attr_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, void *_mesg)
HDassert(attr);
/* Decrement reference count on datatype in file */
- if((H5O_MSG_DTYPE->del)(f, dxpl_id, oh, attr->dt) < 0)
+ if((H5O_MSG_DTYPE->del)(f, dxpl_id, oh, attr->shared->dt) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust datatype link count")
/* Decrement reference count on dataspace in file */
- if((H5O_MSG_SDSPACE->del)(f, dxpl_id, oh, attr->ds) < 0)
+ if((H5O_MSG_SDSPACE->del)(f, dxpl_id, oh, attr->shared->ds) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust dataspace link count")
done:
@@ -558,9 +576,9 @@ H5O_attr_link(H5F_t *f, hid_t dxpl_id, H5O_t *oh, void *_mesg)
* message is deleted.
*/
/* Increment reference count on datatype & dataspace in file */
- if((H5O_MSG_DTYPE->link)(f, dxpl_id, oh, attr->dt) < 0)
+ if((H5O_MSG_DTYPE->link)(f, dxpl_id, oh, attr->shared->dt) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust datatype link count")
- if((H5O_MSG_SDSPACE->link)(f, dxpl_id, oh, attr->ds) < 0)
+ if((H5O_MSG_SDSPACE->link)(f, dxpl_id, oh, attr->shared->ds) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust dataspace link count")
done:
@@ -650,33 +668,39 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
/* Copy the top level of the attribute */
*attr_dst = *attr_src;
+ if(NULL == (attr_dst->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
+
/* Don't have an opened group location for copy */
- H5O_loc_reset(&(attr_dst->oloc));
+ H5O_loc_reset(&(attr_dst->shared->oloc));
H5G_name_reset(&(attr_dst->path));
attr_dst->obj_opened = FALSE;
-
+
+ /* Reference count for the header message in the cache */
+ attr_dst->shared->nrefs = 1;
+
/* Copy attribute's name */
- attr_dst->name = H5MM_strdup(attr_src->name);
- HDassert(attr_dst->name);
+ attr_dst->shared->name = H5MM_strdup(attr_src->shared->name);
+ HDassert(attr_dst->shared->name);
/* Copy attribute's datatype */
/* (Start destination datatype as transient, even if source is named) */
- attr_dst->dt = H5T_copy(attr_src->dt, H5T_COPY_ALL);
- HDassert(attr_dst->dt);
+ attr_dst->shared->dt = H5T_copy(attr_src->shared->dt, H5T_COPY_ALL);
+ HDassert(attr_dst->shared->dt);
/* Set the location of the destination datatype */
- if(H5T_set_loc(attr_dst->dt, file_dst, H5T_LOC_DISK) < 0)
+ if(H5T_set_loc(attr_dst->shared->dt, file_dst, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "cannot mark datatype on disk")
/* Check for named datatype being copied */
- if(H5T_committed(attr_src->dt)) {
+ if(H5T_committed(attr_src->shared->dt)) {
H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
/* Get group entries for source & destination */
- src_oloc = H5T_oloc(attr_src->dt);
+ src_oloc = H5T_oloc(attr_src->shared->dt);
HDassert(src_oloc);
- dst_oloc = H5T_oloc(attr_dst->dt);
+ dst_oloc = H5T_oloc(attr_dst->shared->dt);
HDassert(dst_oloc);
/* Reset object location for new object */
@@ -688,59 +712,59 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
/* Update shared message info from named datatype info */
- H5T_update_shared(attr_dst->dt);
+ H5T_update_shared(attr_dst->shared->dt);
} /* end if */
else {
/* If the datatype is not named, it may have been shared in the
* source file's heap. Un-share it for now. We'll try to shared
* it in the destination file below.
*/
- if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->dt) < 0)
+ if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->shared->dt) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
} /* end else */
/* Copy the dataspace for the attribute */
- attr_dst->ds = H5S_copy(attr_src->ds, FALSE, FALSE);
- HDassert(attr_dst->ds);
+ attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
+ HDassert(attr_dst->shared->ds);
/* Reset the dataspace's sharing in the source file before trying to share
* it in the destination.
*/
- if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->ds) < 0)
+ if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->shared->ds) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset dataspace sharing")
/* Try to share both the datatype and dataset. This does nothing if the
* datatype is committed or sharing is disabled.
*/
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->dt, NULL) < 0)
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute datatype")
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->ds, NULL) < 0)
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute dataspace")
/* Compute the sizes of the datatype and dataspace. This is their raw
* size unless they're shared.
*/
- attr_dst->dt_size = H5O_msg_raw_size(file_dst, H5O_DTYPE_ID, FALSE, attr_dst->dt);
- HDassert(attr_dst->dt_size > 0);
- attr_dst->ds_size = H5O_msg_raw_size(file_dst, H5O_SDSPACE_ID, FALSE, attr_dst->ds);
- HDassert(attr_dst->ds_size > 0);
+ attr_dst->shared->dt_size = H5O_msg_raw_size(file_dst, H5O_DTYPE_ID, FALSE, attr_dst->shared->dt);
+ HDassert(attr_dst->shared->dt_size > 0);
+ attr_dst->shared->ds_size = H5O_msg_raw_size(file_dst, H5O_SDSPACE_ID, FALSE, attr_dst->shared->ds);
+ HDassert(attr_dst->shared->ds_size > 0);
/* Check whether to recompute the size of the attribute */
/* (happens when the datatype or dataspace changes sharing status) */
- if(attr_dst->dt_size != attr_src->dt_size || attr_dst->ds_size != attr_src->ds_size)
+ if(attr_dst->shared->dt_size != attr_src->shared->dt_size || attr_dst->shared->ds_size != attr_src->shared->ds_size)
*recompute_size = TRUE;
/* Compute the size of the data */
- H5_ASSIGN_OVERFLOW(attr_dst->data_size, H5S_GET_EXTENT_NPOINTS(attr_dst->ds) * H5T_get_size(attr_dst->dt), hsize_t, size_t);
+ H5_ASSIGN_OVERFLOW(attr_dst->shared->data_size, H5S_GET_EXTENT_NPOINTS(attr_dst->shared->ds) * H5T_get_size(attr_dst->shared->dt), hsize_t, size_t);
/* Copy (& convert) the data, if necessary */
- if(attr_src->data) {
- if(NULL == (attr_dst->data = H5FL_BLK_MALLOC(attr_buf, attr_dst->data_size)))
+ if(attr_src->shared->data) {
+ if(NULL == (attr_dst->shared->data = H5FL_BLK_MALLOC(attr_buf, attr_dst->shared->data_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Check if we need to convert data */
- if(H5T_detect_class(attr_src->dt, H5T_VLEN) > 0) {
+ if(H5T_detect_class(attr_src->shared->dt, H5T_VLEN) > 0) {
H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
H5T_t *dt_mem; /* Memory datatype */
size_t src_dt_size; /* Source datatype size */
@@ -752,37 +776,37 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
size_t buf_size; /* Size of copy buffer */
/* Create datatype ID for src datatype */
- if((tid_src = H5I_register(H5I_DATATYPE, attr_src->dt)) < 0)
+ if((tid_src = H5I_register(H5I_DATATYPE, attr_src->shared->dt)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source file datatype")
/* create a memory copy of the variable-length datatype */
- if(NULL == (dt_mem = H5T_copy(attr_src->dt, H5T_COPY_TRANSIENT)))
+ if(NULL == (dt_mem = H5T_copy(attr_src->shared->dt, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype")
/* create variable-length datatype at the destinaton file */
- if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->dt)) < 0)
+ if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->shared->dt)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination file datatype")
/* Set up the conversion functions */
- if(NULL == (tpath_src_mem = H5T_path_find(attr_src->dt, dt_mem, NULL, NULL, dxpl_id, FALSE)))
+ if(NULL == (tpath_src_mem = H5T_path_find(attr_src->shared->dt, dt_mem, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and mem datatypes")
- if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, attr_dst->dt, NULL, NULL, dxpl_id, FALSE)))
+ if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, attr_dst->shared->dt, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between mem and dst datatypes")
/* Determine largest datatype size */
- if(0 == (src_dt_size = H5T_get_size(attr_src->dt)))
+ if(0 == (src_dt_size = H5T_get_size(attr_src->shared->dt)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
if(0 == (tmp_dt_size = H5T_get_size(dt_mem)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
max_dt_size = MAX(src_dt_size, tmp_dt_size);
- if(0 == (tmp_dt_size = H5T_get_size(attr_dst->dt)))
+ if(0 == (tmp_dt_size = H5T_get_size(attr_dst->shared->dt)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
max_dt_size = MAX(max_dt_size, tmp_dt_size);
/* Set number of whole elements that fit in buffer */
- if(0 == (nelmts = attr_src->data_size / src_dt_size))
+ if(0 == (nelmts = attr_src->shared->data_size / src_dt_size))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "element size too large")
/* Set up number of bytes to copy, and initial buffer size */
@@ -809,7 +833,7 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
if(NULL == (buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
- HDmemcpy(buf, attr_src->data, attr_src->data_size);
+ HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size);
/* Convert from source file to memory */
if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
@@ -821,23 +845,23 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
- HDmemcpy(attr_dst->data, buf, attr_dst->data_size);
+ HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size);
if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data")
} /* end if */
else {
- HDassert(attr_dst->data_size == attr_src->data_size);
- HDmemcpy(attr_dst->data, attr_src->data, attr_src->data_size);
+ HDassert(attr_dst->shared->data_size == attr_src->shared->data_size);
+ HDmemcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size);
} /* end else */
- } /* end if(attr_src->data) */
+ } /* end if(attr_src->shared->data) */
/* Recompute the version to encode the destination attribute */
if(H5A_set_version(file_dst, attr_dst) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version")
/* Indicate that the fill values aren't to be written out */
- attr_dst->initialized = TRUE;
+ attr_dst->shared->initialized = TRUE;
/* Set return value */
ret_value = attr_dst;
@@ -864,9 +888,8 @@ done:
reclaim_buf = H5FL_BLK_FREE(attr_buf, reclaim_buf);
/* Release destination attribute information on failure */
- if(!ret_value)
- if(attr_dst)
- (void)H5A_free(attr_dst);
+ if(!ret_value && attr_dst && H5A_close(attr_dst) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_attr_copy_file() */
@@ -911,8 +934,8 @@ H5O_attr_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
/* Only need to fix reference attribute with real data being copied to
* another file.
*/
- if((NULL != attr_src->data) &&
- (H5T_get_class(attr_src->dt, FALSE) == H5T_REFERENCE) &&
+ if((NULL != attr_src->shared->data) &&
+ (H5T_get_class(attr_src->shared->dt, FALSE) == H5T_REFERENCE) &&
(file_src != file_dst)) {
/* copy object pointed by reference. The current implementation does not
@@ -924,16 +947,16 @@ H5O_attr_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
size_t ref_count;
/* Determine # of reference elements to copy */
- ref_count = attr_dst->data_size / H5T_get_size(attr_dst->dt);
+ ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt);
/* Copy objects referenced in source buffer to destination file and set destination elements */
- if(H5O_copy_expand_ref(file_src, attr_src->data, dxpl_id,
- file_dst, attr_dst->data, ref_count, H5T_get_ref_type(attr_src->dt), cpy_info) < 0)
+ if(H5O_copy_expand_ref(file_src, attr_src->shared->data, dxpl_id,
+ file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_src->shared->dt), cpy_info) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
} /* end if */
else
/* Reset value to zero */
- HDmemset(attr_dst->data, 0, attr_dst->data_size);
+ HDmemset(attr_dst->shared->data, 0, attr_dst->shared->data_size);
} /* end if */
done:
@@ -965,7 +988,7 @@ H5O_attr_get_crt_index(const void *_mesg, H5O_msg_crt_idx_t *crt_idx /*out*/)
HDassert(crt_idx);
/* Get the attribute's creation index */
- *crt_idx = attr->crt_idx;
+ *crt_idx = attr->shared->crt_idx;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_attr_get_crt_index() */
@@ -994,7 +1017,7 @@ H5O_attr_set_crt_index(void *_mesg, H5O_msg_crt_idx_t crt_idx)
HDassert(attr);
/* Set the creation index */
- attr->crt_idx = crt_idx;
+ attr->shared->crt_idx = crt_idx;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_attr_set_crt_index() */
@@ -1037,8 +1060,8 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
fprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth,
"Name:",
- mesg->name);
- switch(mesg->encoding) {
+ mesg->shared->name);
+ switch(mesg->shared->encoding) {
case H5T_CSET_ASCII:
s = "ASCII";
break;
@@ -1046,7 +1069,7 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
s = "UTF-8";
break;
default:
- sprintf(buf, "H5T_CSET_RESERVED_%d", (int)(mesg->encoding));
+ sprintf(buf, "H5T_CSET_RESERVED_%d", (int)(mesg->shared->encoding));
s = buf;
break;
} /* end switch */
@@ -1055,32 +1078,32 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
s);
HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
"Initialized:",
- mesg->initialized);
+ mesg->shared->initialized);
HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
"Object opened:",
mesg->obj_opened);
HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
"Object:",
- mesg->oloc.addr);
+ mesg->shared->oloc.addr);
/* Check for attribute creation order index on the attribute */
- if(mesg->crt_idx != H5O_MAX_CRT_ORDER_IDX)
+ if(mesg->shared->crt_idx != H5O_MAX_CRT_ORDER_IDX)
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Creation Index:",
- (unsigned)mesg->crt_idx);
+ (unsigned)mesg->shared->crt_idx);
fprintf(stream, "%*sDatatype...\n", indent, "");
fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3),
"Encoded Size:",
- (unsigned long)(mesg->dt_size));
- if((H5O_MSG_DTYPE->debug)(f, dxpl_id, mesg->dt, stream, indent + 3, MAX(0, fwidth - 3)) < 0)
+ (unsigned long)(mesg->shared->dt_size));
+ if((H5O_MSG_DTYPE->debug)(f, dxpl_id, mesg->shared->dt, stream, indent + 3, MAX(0, fwidth - 3)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display datatype message info")
fprintf(stream, "%*sDataspace...\n", indent, "");
fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0, fwidth - 3),
"Encoded Size:",
- (unsigned long)(mesg->ds_size));
- if(H5S_debug(f, dxpl_id, mesg->ds, stream, indent+3, MAX(0, fwidth - 3)) < 0)
+ (unsigned long)(mesg->shared->ds_size));
+ if(H5S_debug(f, dxpl_id, mesg->shared->ds, stream, indent+3, MAX(0, fwidth - 3)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display dataspace message info")
done:
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 5c9f875..307b670 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -40,6 +40,8 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared Object Header Messages */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Fprivate.h" /* File */
/****************/
@@ -136,7 +138,8 @@ typedef struct {
static herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc,
hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
-
+static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr,
+ const char* name_to_open);
/*********************/
/* Package Variables */
@@ -306,11 +309,11 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINC, FAIL, "attribute creation index can't be incremented")
/* Set the creation order index on the attribute & incr. creation order index */
- attr->crt_idx = ainfo.max_crt_idx++;
+ attr->shared->crt_idx = ainfo.max_crt_idx++;
} /* end if */
else
/* Set "bogus" creation index for attribute */
- attr->crt_idx = H5O_MAX_CRT_ORDER_IDX;
+ attr->shared->crt_idx = H5O_MAX_CRT_ORDER_IDX;
/* Add the attribute information message, if one is needed */
if(new_ainfo) {
@@ -325,7 +328,7 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
} /* end if */
else {
/* Set "bogus" creation index for attribute */
- attr->crt_idx = H5O_MAX_CRT_ORDER_IDX;
+ attr->shared->crt_idx = H5O_MAX_CRT_ORDER_IDX;
/* Set attribute info value to get attribute into object header */
ainfo.fheap_addr = HADDR_UNDEF;
@@ -343,6 +346,12 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new attribute in header")
} /* end else */
+ /* Increment reference count for shared attribute object for the
+ * object handle created by the caller function H5A_create. The count
+ * for the cached object header has been incremented in the step above
+ * (in H5O_msg_append_real). The dense storage doesn't need a count. */
+ attr->shared->nrefs += 1;
+
/* Was new attribute shared? */
if((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, attr)) > 0) {
hsize_t attr_rc; /* Attribute's ref count in shared message storage */
@@ -426,14 +435,14 @@ H5O_attr_open_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
HDassert(!udata->attr);
/* Check for correct attribute message to modify */
- if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) {
+ if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->name) == 0) {
/* Make a copy of the attribute to return */
if(NULL == (udata->attr = H5A_copy(NULL, (H5A_t *)mesg->native)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy attribute")
/* Assign [somewhat arbitrary] creation order value, for older versions of the format */
if(oh->version == H5O_VERSION_1)
- udata->attr->crt_idx = sequence;
+ udata->attr->shared->crt_idx = sequence;
/* Stop iterating */
ret_value = H5_ITER_STOP;
@@ -454,6 +463,11 @@ done:
* Programmer: Quincey Koziol
* Monday, December 11, 2006
*
+ * Modification:Raymond Lu
+ * 23 June 2008
+ * If the attribute is in dense storage and has already been
+ * opened, make a copy of already opened object to share some
+ * object information.
*-------------------------------------------------------------------------
*/
H5A_t *
@@ -462,6 +476,8 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
H5O_t *oh = NULL; /* Pointer to actual object header */
H5O_ainfo_t ainfo; /* Attribute information for object */
H5A_t *ret_value; /* Return value */
+ H5A_t *exist_attr = NULL; /* Opened attribute object */
+ htri_t found_open_attr = FALSE; /* Whether opened object is found */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_open_by_name)
@@ -479,34 +495,40 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
/* Clear error stack from not finding attribute info */
H5E_clear_stack(NULL);
- /* Check for opening attribute with dense storage */
- if(H5F_addr_defined(ainfo.fheap_addr)) {
- /* Open attribute in dense storage */
- if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute")
- } /* end if */
- else {
- H5O_iter_opn_t udata; /* User data for callback */
- H5O_mesg_operator_t op; /* Wrapper for operator */
-
- /* Set up user data for callback */
- udata.name = name;
- udata.attr = NULL;
-
- /* Iterate over attributes, to locate correct one to open */
- op.op_type = H5O_MESG_OP_LIB;
- op.u.lib_op = H5O_attr_open_cb;
- if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, &op, &udata, dxpl_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "error updating attribute")
-
- /* Check that we found the attribute */
- if(!udata.attr)
- HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute")
-
- /* Get attribute opened from object header */
- HDassert(udata.attr);
- ret_value = udata.attr;
- } /* end else */
+ /* If found the attribute is already opened, make a copy of it to share the
+ object information. If not, open attribute as a new object */
+ if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, name)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute")
+ else if(found_open_attr == TRUE) {
+ if(NULL == (ret_value = H5A_copy(NULL, exist_attr)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute")
+ } else {
+ if(H5F_addr_defined(ainfo.fheap_addr)) { /* open attribute with dense storage */
+ if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute")
+ } else {
+ H5O_iter_opn_t udata; /* User data for callback */
+ H5O_mesg_operator_t op; /* Wrapper for operator */
+
+ /* Set up user data for callback */
+ udata.name = name;
+ udata.attr = NULL;
+
+ /* Iterate over attributes, to locate correct one to open */
+ op.op_type = H5O_MESG_OP_LIB;
+ op.u.lib_op = H5O_attr_open_cb;
+ if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, &op, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "error updating attribute")
+
+ /* Check that we found the attribute */
+ if(!udata.attr)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute")
+
+ /* Get attribute opened from object header */
+ HDassert(udata.attr);
+ ret_value = udata.attr;
+ } /* end else */
+ }
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
@@ -542,7 +564,7 @@ H5O_attr_open_by_idx_cb(const H5A_t *attr, void *_ret_attr)
HDassert(attr);
HDassert(ret_attr);
- /* Copy attribute information */
+ /* Copy attribute information. Shared some attribute information. */
if(NULL == (*ret_attr = H5A_copy(NULL, attr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
@@ -562,6 +584,11 @@ done:
* Programmer: Quincey Koziol
* Monday, December 18, 2006
*
+ * Modification:Raymond Lu
+ * 23 June 2008
+ * After opening the attribute, check whether it's in dense
+ * storage and has already been opened. If it has, close the
+ * opened object and make a copy of already opened object.
*-------------------------------------------------------------------------
*/
H5A_t *
@@ -569,7 +596,11 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, hid_t dxpl_id)
{
H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ H5A_t *exist_attr = NULL; /* Opened attribute object */
+ htri_t found_open_attr = FALSE; /* Whether opened object is found */
H5A_t *ret_value = NULL; /* Return value */
+ H5O_t *oh = NULL; /* Object header */
+ H5O_ainfo_t ainfo; /* Attribute information for object */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_open_by_idx)
@@ -584,12 +615,113 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
if(H5O_attr_iterate_real((hid_t)-1, loc, dxpl_id, idx_type, order, n, NULL, &attr_op, &ret_value) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADITER, NULL, "can't locate attribute")
+
+ /* Protect the object header to iterate over */
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "unable to load object header")
+
+ /* Check for attribute info stored */
+ ainfo.fheap_addr = HADDR_UNDEF;
+ if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
+ /* Clear error stack from not finding attribute info */
+ H5E_clear_stack(NULL);
+
+ /* Find out whether it has already been opened. If it has, close the object
+ * and make a copy of the already opened object to share the object info. */
+ if(ret_value) {
+ if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr,
+ ret_value->shared->name)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute")
+
+ /* If found that the attribute is already opened, make a copy of it
+ and close the object just opened. */
+ if(found_open_attr && exist_attr) {
+ if(H5A_close(ret_value) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, NULL, "can't close attribute")
+
+ if(NULL == (ret_value = H5A_copy(NULL, exist_attr)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute")
+ }
+ }
+
done:
+ if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh,
+ H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_PROTECT, NULL, "unable to release object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_open_by_idx() */
/*-------------------------------------------------------------------------
+ * Function: H5O_attr_find_opened_attr
+ *
+ * Purpose: Find out whether an attribute has been opened by giving
+ * the name. Return the pointer to the object if found.
+ *
+ * Return: TRUE: found the already opened object
+ * FALSE: didn't find the opened object
+ * FAIL: function failed.
+ *
+ * Programmer: Raymond Lu
+ * 23 June 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static
+htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_to_open)
+{
+ htri_t ret_value = FALSE;
+ int num_open_attr = 0;
+ hid_t *attr_id_list = NULL;
+ unsigned long loc_fnum, attr_fnum;
+ int i;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_find_opened_attr)
+
+ /* Get file serial number for the location of attribute */
+ if(H5F_get_fileno(loc->file, &loc_fnum) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
+
+ /* Count all opened attributes */
+ if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get number of opened attributes")
+
+ /* Find out whether the attribute has been opened */
+ if(num_open_attr) {
+ attr_id_list = (hid_t*)H5MM_malloc(num_open_attr*sizeof(hid_t));
+
+ /* Retrieve the IDs of all opened attributes */
+ if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't IDs of opened attributes")
+
+ for(i=0; i<num_open_attr; i++) {
+ if(NULL == (*attr = (H5A_t *)H5I_object_verify(attr_id_list[i], H5I_ATTR)))
+ HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "not an attribute")
+
+ /* Get file serial number for attribute */
+ if(H5F_get_fileno((*attr)->shared->oloc.file, &attr_fnum) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
+
+ /* Verify whether it's the right object. The attribute name, object address
+ * to which the attribute is attached, and file serial number should all
+ * match. */
+ if(!strcmp(name_to_open, (*attr)->shared->name) &&
+ loc->addr == (*attr)->shared->oloc.addr &&
+ loc_fnum == attr_fnum) {
+ ret_value = TRUE;
+ break;
+ }
+ }
+ H5MM_free(attr_id_list);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_attr_find_opened_attr */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_attr_update_shared
*
* Purpose: Update a shared attribute.
@@ -677,6 +809,10 @@ done:
* koziol@hdfgroup.org
* Dec 4 2006
*
+ * Modification:Raymond Lu
+ * 4 June 2008
+ * Took out the data copying part because the attribute data
+ * is shared between attribute handle and object header.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -694,18 +830,7 @@ H5O_attr_write_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(!udata->found);
/* Check for correct attribute message to modify */
- if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->attr->name) == 0) {
- /* Allocate storage for the message's data, if necessary */
- if(((H5A_t *)mesg->native)->data == NULL)
- if(NULL == (((H5A_t *)mesg->native)->data = H5FL_BLK_MALLOC(attr_buf, udata->attr->data_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed")
-
- /* Copy the data into the header message */
- /* (Needs to occur before updating the shared message, or the hash
- * value on the old & new messages will be the same)
- */
- HDmemcpy(((H5A_t *)mesg->native)->data, udata->attr->data, udata->attr->data_size);
-
+ if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->attr->shared->name) == 0) {
/* Update the shared attribute in the SOHM storage */
if(mesg->flags & H5O_MSG_FLAG_SHARED)
if(H5O_attr_update_shared(udata->f, udata->dxpl_id, oh, udata->attr, (H5O_shared_t *)mesg->native) < 0)
@@ -836,7 +961,7 @@ H5O_attr_rename_chk_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(!udata->found);
/* Check for existing attribute with new name */
- if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->new_name) == 0) {
+ if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->new_name) == 0) {
/* Indicate that we found an existing attribute with the new name*/
udata->found = TRUE;
@@ -882,12 +1007,12 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(!udata->found);
/* Find correct attribute message to rename */
- if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->old_name) == 0) {
- unsigned old_version = ((H5A_t *)mesg->native)->version; /* Old version of the attribute */
+ if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->old_name) == 0) {
+ unsigned old_version = ((H5A_t *)mesg->native)->shared->version; /* Old version of the attribute */
/* Change the name for the attribute */
- H5MM_xfree(((H5A_t *)mesg->native)->name);
- ((H5A_t *)mesg->native)->name = H5MM_xstrdup(udata->new_name);
+ H5MM_xfree(((H5A_t *)mesg->native)->shared->name);
+ ((H5A_t *)mesg->native)->shared->name = H5MM_xstrdup(udata->new_name);
/* Recompute the version to encode the attribute with */
if(H5A_set_version(udata->f, ((H5A_t *)mesg->native)) < 0)
@@ -908,7 +1033,7 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
/* Check for attribute message changing size */
if(HDstrlen(udata->new_name) != HDstrlen(udata->old_name) ||
- old_version != ((H5A_t *)mesg->native)->version) {
+ old_version != ((H5A_t *)mesg->native)->shared->version) {
H5A_t *attr; /* Attribute to re-add */
/* Take ownership of the message's native info (the attribute)
@@ -939,8 +1064,8 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
/* Sanity check */
HDassert(H5O_msg_is_shared(H5O_ATTR_ID, attr) == FALSE);
- /* Release the local copy of the attribute */
- H5O_msg_free_real(H5O_MSG_ATTR, attr);
+ /* Close the local copy of the attribute */
+ H5A_close(attr);
} /* end if */
} /* end else */
@@ -1184,6 +1309,14 @@ done:
* Programmer: Quincey Koziol
* Wednesday, February 14, 2007
*
+ * Modification:Raymond Lu
+ * 24 June 2008
+ * When converting storage from dense to compact, if found
+ * the attribute is already opened, use the opened message
+ * to insert. If not, still use the message in the attribute
+ * table. This will guarantee that the attribute message is
+ * shared between the object in metadata cache and the opened
+ * object.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1217,35 +1350,51 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, H5O_ainfo_t *ainfo,
* can't fit into an object header message)
*/
for(u = 0; u < ainfo->nattrs; u++)
- if(H5O_msg_size_oh(loc->file, oh, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
+ if(H5O_msg_size_oh(loc->file, oh, H5O_ATTR_ID, (atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
can_convert = FALSE;
break;
} /* end if */
/* If ok, insert attributes as object header messages */
if(can_convert) {
+ H5A_t *exist_attr = NULL;
+ htri_t found_open_attr = FALSE;
+
/* Iterate over attributes, to put them into header */
for(u = 0; u < ainfo->nattrs; u++) {
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
/* Check if attribute is shared */
- if((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, &(atable.attrs[u]))) < 0)
+ if((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, (atable.attrs[u]))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error determining if message is shared")
else if(shared_mesg == 0) {
/* Increment reference count on attribute components */
/* (so that they aren't deleted when the dense attribute storage is deleted) */
- if(H5O_attr_link(loc->file, dxpl_id, oh, &(atable.attrs[u])) < 0)
+ if(H5O_attr_link(loc->file, dxpl_id, oh, (atable.attrs[u])) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count")
} /* end if */
else {
/* Reset 'shared' status, so attribute will be shared again */
- atable.attrs[u].sh_loc.type = H5O_SHARE_TYPE_UNSHARED;
+ (atable.attrs[u])->sh_loc.type = H5O_SHARE_TYPE_UNSHARED;
} /* end else */
- /* Insert attribute message into object header */
- /* (Will increment reference count on shared attributes) */
- if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, &(atable.attrs[u])) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message")
+ /* Insert attribute message into object header (Will increment
+ reference count on shared attributes) */
+ /* Find out whether the attribute has been opened */
+ if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr,
+ (atable.attrs[u])->shared->name)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute")
+
+ /* If found the attribute is already opened, use the opened message to insert.
+ If not, still use the message in the attribute table. */
+ if(found_open_attr && exist_attr) {
+ if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, exist_attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message")
+
+ } else {
+ if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, (atable.attrs[u])) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message")
+ }
} /* end for */
/* Remove the dense storage */
@@ -1304,7 +1453,7 @@ H5O_attr_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(!udata->found);
/* Check for correct attribute message to modify */
- if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) {
+ if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->name) == 0) {
/* Convert message into a null message (i.e. delete it) */
if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to convert into null message")
@@ -1468,7 +1617,7 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
/* Set up user data for callback, to remove the attribute by name */
udata.f = loc->file;
udata.dxpl_id = dxpl_id;
- udata.name = atable.attrs[n].name;
+ udata.name = ((atable.attrs[n])->shared)->name;
udata.found = FALSE;
/* Iterate over attributes, to locate correct one to delete */
@@ -1582,7 +1731,7 @@ H5O_attr_exists_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(!udata->found);
/* Check for correct attribute message */
- if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) {
+ if(HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->name) == 0) {
/* Indicate that this message is the attribute sought */
udata->found = TRUE;
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index 3f0046a..dc7ae23 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -560,8 +560,8 @@ H5T_pack(const H5T_t *dt)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound datatype")
/* Update the member size */
- dt->shared->u.compnd.memb[i].size = dt->shared->u.compnd.memb[i].type->shared->size;
- }
+ dt->shared->u.compnd.memb[i].size = (dt->shared->u.compnd.memb[i].type)->shared->size;
+ }
/* Remove padding between members */
if(H5T_sort_value(dt, NULL)<0)