summaryrefslogtreecommitdiffstats
path: root/src/H5A.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-11-17 16:53:38 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-11-17 16:53:38 (GMT)
commit1878ad9c2cc038e1739887b12a26512daf76eefc (patch)
tree948052b3e450ede9f30c2c4db7ba6e6f0657bc53 /src/H5A.c
parent94b852d15a0e2a52251071929e451ea7af414108 (diff)
downloadhdf5-1878ad9c2cc038e1739887b12a26512daf76eefc.zip
hdf5-1878ad9c2cc038e1739887b12a26512daf76eefc.tar.gz
hdf5-1878ad9c2cc038e1739887b12a26512daf76eefc.tar.bz2
[svn-r9537] Purpose:
Code cleanup & optimizations Description: Clean up some of the code in attributes to avoid allocating memory and performing type conversions when the conversion is a noop. Avoid memory allocations of attribute data structures by switching to use library's free list memory allocator routines. Avoid memory allocations of object header continuation data structures by switching to use library's free list memory allocator routines. Rearrange threaded, balanced binary tree macros slightly to avoid some overhead. Platforms tested: FreeBSD 4.10 (sleipnir) w/parallel Solaris 2.7 (arabica) Too minor to require h5committest
Diffstat (limited to 'src/H5A.c')
-rw-r--r--src/H5A.c189
1 files changed, 125 insertions, 64 deletions
diff --git a/src/H5A.c b/src/H5A.c
index a40c402..e264026 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -26,6 +26,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Apkg.h" /* Attributes */
#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Spkg.h" /* Dataspace functions */
@@ -43,6 +44,9 @@ static herr_t H5A_rename(H5G_entry_t *ent, const char *old_name, const char *new
/* The number of reserved IDs in dataset ID group */
#define H5A_RESERVED_ATOMS 0
+/* Declare the free lists for H5A_t's */
+H5FL_DEFINE(H5A_t);
+
/*--------------------------------------------------------------------------
NAME
@@ -229,7 +233,7 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace extent has not been set")
/* Build the attribute information */
- if((attr = H5MM_calloc(sizeof(H5A_t)))==NULL)
+ if((attr = H5FL_CALLOC(H5A_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
/* Copy the attribute name */
@@ -509,7 +513,7 @@ static hid_t
H5A_open(H5G_entry_t *ent, unsigned idx, hid_t dxpl_id)
{
H5A_t *attr = NULL;
- hid_t ret_value = FAIL;
+ hid_t ret_value;
FUNC_ENTER_NOAPI_NOINIT(H5A_open)
@@ -527,9 +531,8 @@ H5A_open(H5G_entry_t *ent, unsigned idx, hid_t dxpl_id)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Hold the symbol table entry (and file) open */
- if (H5O_open(&(attr->ent)) < 0) {
+ if (H5O_open(&(attr->ent)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
- }
attr->ent_opened=1;
/* Register the new attribute and get an ID for it */
@@ -622,7 +625,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
size_t dst_type_size; /* size of destination type*/
size_t buf_size; /* desired buffer size */
int idx; /* index of attribute in object header */
- herr_t ret_value = FAIL;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5A_write)
@@ -635,44 +638,59 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HGOTO_ERROR (H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,size_t);
- /* Check for null dataspace */
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);
- /* Get the maximum buffer size needed and allocate it */
- buf_size=nelmts*MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5MM_malloc (buf_size)) || NULL==(bkg_buf = H5MM_calloc(buf_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Copy the user's data into the buffer for conversion */
- HDmemcpy(tconv_buf,buf,(src_type_size*nelmts));
-
/* 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))) {
+ if (NULL == (tpath = H5T_path_find(mem_type, attr->dt, NULL, NULL, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types")
- } else if (!H5T_path_noop(tpath)) {
+
+ /* 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)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
- }
- /* Perform data type conversion */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed")
+ /* Get the maximum buffer size needed and allocate it */
+ buf_size=nelmts*MAX(src_type_size,dst_type_size);
+ if (NULL==(tconv_buf = H5MM_malloc (buf_size)) || NULL==(bkg_buf = H5MM_calloc(buf_size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy the user's data into the buffer for conversion */
+ HDmemcpy(tconv_buf,buf,(src_type_size*nelmts));
+
+ /* Perform data type conversion */
+ if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed")
+
+ /* Free the previous attribute data buffer, if there is one */
+ if(attr->data)
+ H5MM_xfree(attr->data);
- /* Free the previous attribute data buffer, if there is one */
- if(attr->data)
- H5MM_xfree(attr->data);
+ /* Set the pointer to the attribute data to the converted information */
+ attr->data=tconv_buf;
+ } /* end if */
+ /* No type conversion necessary */
+ else {
+ HDassert(dst_type_size==src_type_size);
+
+ /* Allocate the attribute buffer, if there isn't one */
+ if(attr->data==NULL)
+ if (NULL==(attr->data = H5MM_malloc (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));
+ } /* end else */
/* Look up the attribute for the object */
if((idx=H5A_get_index(&(attr->ent),attr->name,dxpl_id))<0)
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "attribute not found")
/* Modify the attribute data */
- attr->data=tconv_buf; /* Set the data pointer temporarily */
if (H5O_modify(&(attr->ent), H5O_ATTR_ID, idx, 0, 1, attr, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages")
} /* end if */
@@ -680,8 +698,6 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
/* Indicate the the attribute doesn't need fill-values */
attr->initialized=TRUE;
- ret_value=SUCCEED;
-
done:
/* Release resources */
if (src_id >= 0)
@@ -770,7 +786,7 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
size_t src_type_size; /* size of source type */
size_t dst_type_size; /* size of destination type */
size_t buf_size; /* desired buffer size */
- herr_t ret_value = FAIL;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5A_read)
@@ -783,7 +799,6 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HGOTO_ERROR (H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,size_t);
- /* Check for null dataspace */
if(nelmts>0) {
/* Get the memory and file datatype sizes */
src_type_size = H5T_get_size(attr->dt);
@@ -794,35 +809,42 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HDmemset(buf,0,(dst_type_size*nelmts));
} /* end if */
else { /* Attribute exists and has a value */
- /* Get the maximum buffer size needed and allocate it */
- buf_size=nelmts*MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5MM_malloc (buf_size)) || NULL==(bkg_buf = H5MM_calloc(buf_size)))
- 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));
-
/* 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))) {
+ if (NULL == (tpath = H5T_path_find(attr->dt, mem_type, NULL, NULL, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types")
- } else if (!H5T_path_noop(tpath)) {
+
+ /* 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 ||
(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")
- }
- /* Perform data type conversion. */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed")
+ /* Get the maximum buffer size needed and allocate it */
+ buf_size=nelmts*MAX(src_type_size,dst_type_size);
+ if (NULL==(tconv_buf = H5MM_malloc (buf_size)) || NULL==(bkg_buf = H5MM_calloc(buf_size)))
+ 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));
+
+ /* Perform data type conversion. */
+ if (H5T_convert(tpath, src_id, dst_id, nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed")
- /* Copy the converted data into the user's buffer */
- HDmemcpy(buf,tconv_buf,(dst_type_size*nelmts));
+ /* Copy the converted data into the user's buffer */
+ HDmemcpy(buf,tconv_buf,(dst_type_size*nelmts));
+ } /* end if */
+ /* No type conversion necessary */
+ else {
+ HDassert(dst_type_size==src_type_size);
+
+ /* Copy the attribute data into the user's buffer */
+ HDmemcpy(buf,attr->data,(dst_type_size*nelmts));
+ } /* end else */
} /* end else */
} /* end if */
- ret_value=SUCCEED;
-
done:
/* Release resources */
if (src_id >= 0)
@@ -1217,7 +1239,7 @@ H5A_rename(H5G_entry_t *ent, const char *old_name, const char *new_name, hid_t d
assert(new_name);
/* Build the attribute information */
- if((found_attr = HDcalloc(1, sizeof(H5A_t)))==NULL)
+ if((found_attr = H5FL_CALLOC(H5A_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
/* Read in the existing attributes to check for duplicates */
@@ -1489,9 +1511,10 @@ done:
*-------------------------------------------------------------------------
*/
H5A_t *
-H5A_copy(const H5A_t *old_attr)
+H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr)
{
H5A_t *new_attr=NULL;
+ hbool_t allocated_attr=FALSE; /* Whether the attribute was allocated */
H5A_t *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI(H5A_copy, NULL)
@@ -1500,8 +1523,13 @@ H5A_copy(const H5A_t *old_attr)
assert(old_attr);
/* get space */
- if (NULL==(new_attr = H5MM_calloc(sizeof(H5A_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(_new_attr==NULL) {
+ if (NULL==(new_attr = H5FL_MALLOC(H5A_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ allocated_attr=TRUE;
+ } /* end if */
+ else
+ new_attr=_new_attr;
/* Copy the top level of the attribute */
*new_attr = *old_attr;
@@ -1524,7 +1552,7 @@ H5A_copy(const H5A_t *old_attr)
done:
if(ret_value==NULL) {
- if(new_attr!=NULL)
+ if(new_attr!=NULL && allocated_attr)
(void)H5A_close(new_attr);
} /* end if */
@@ -1533,6 +1561,47 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5A_free
+ *
+ * Purpose: Frees all memory associated with an attribute, but does not
+ * free the H5A_t structure (which should be done in H5T_close).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, November 15, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_free(H5A_t *attr)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5A_free, FAIL)
+
+ assert(attr);
+
+ /* Free dynamicly allocated items */
+ if(attr->name)
+ H5MM_xfree(attr->name);
+ if(attr->dt)
+ if(H5T_close(attr->dt)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
+ if(attr->ds)
+ if(H5S_close(attr->ds)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
+ if(attr->data)
+ H5MM_xfree(attr->data);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5A_close
*
* Purpose: Frees an attribute and all associated memory.
@@ -1556,7 +1625,7 @@ H5A_close(H5A_t *attr)
assert(attr);
/* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->ent_opened && !attr->initialized && attr->data_size) {
+ if(attr->ent_opened && !attr->initialized) {
uint8_t *tmp_buf=H5MM_calloc(attr->data_size);
if (NULL == tmp_buf)
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed for attribute fill-value")
@@ -1570,27 +1639,19 @@ H5A_close(H5A_t *attr)
} /* end if */
/* Free dynamicly allocated items */
- if(attr->name)
- H5MM_xfree(attr->name);
- if(attr->dt)
- if(H5T_close(attr->dt)<0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
- if(attr->ds)
- if(H5S_close(attr->ds)<0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
- if(attr->data)
- H5MM_xfree(attr->data);
+ if(H5A_free(attr)<0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
/* Close the object's symbol-table entry */
if(attr->ent_opened)
if(H5O_close(&(attr->ent))<0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
- H5MM_xfree(attr);
+ H5FL_FREE(H5A_t, attr);
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5A_close() */
/*-------------------------------------------------------------------------