summaryrefslogtreecommitdiffstats
path: root/src/H5HFhuge.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-09-11 17:25:26 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-09-11 17:25:26 (GMT)
commite5cad0ef24543e55d164a26dd42a0cc1ba5c2cbe (patch)
tree0a33a38538477c1705f93a0b92a2ba84828ff6f4 /src/H5HFhuge.c
parent9e158b781668387bf82fbab9d60ece304f0e9729 (diff)
downloadhdf5-e5cad0ef24543e55d164a26dd42a0cc1ba5c2cbe.zip
hdf5-e5cad0ef24543e55d164a26dd42a0cc1ba5c2cbe.tar.gz
hdf5-e5cad0ef24543e55d164a26dd42a0cc1ba5c2cbe.tar.bz2
[svn-r12655] Description:
Add "op" routine to perform operation on heap object "in situ", to allow for faster operations on dense links during B-tree traversal & lookup. Refactor the "read" routine to use the internal version of the "op" routine, to keep the code duplication as low as possible. Tested on: Mac OS X.4/PPC (amazon) Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2)
Diffstat (limited to 'src/H5HFhuge.c')
-rw-r--r--src/H5HFhuge.c118
1 files changed, 106 insertions, 12 deletions
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index cc5b824..7675b77 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -78,6 +78,8 @@ herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
/* Local 'huge' object support routines */
static hsize_t H5HF_huge_new_id(H5HF_hdr_t *hdr);
+static herr_t H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ const uint8_t *id, hbool_t is_read, H5HF_operator_t op, void *op_data);
/*********************/
/* Package Variables */
@@ -571,9 +573,9 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_read
+ * Function: H5HF_huge_op_real
*
- * Purpose: Read a 'huge' object from the heap
+ * Purpose: Internal routine to perform an operation on a 'huge' object
*
* Return: SUCCEED/FAIL
*
@@ -583,8 +585,9 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj)
+static herr_t
+H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
+ hbool_t is_read, H5HF_operator_t op, void *op_data)
{
void *read_buf; /* Pointer to buffer for reading */
haddr_t obj_addr; /* Object's address in the file */
@@ -592,14 +595,14 @@ H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj)
unsigned filter_mask = 0; /* Filter mask for object (only used for filtered objects) */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_read)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_op_real)
/*
* Check arguments.
*/
HDassert(hdr);
HDassert(id);
- HDassert(obj);
+ HDassert(is_read || op);
/* Skip over the flag byte */
id++;
@@ -651,14 +654,15 @@ H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj)
} /* end else */
/* Set up buffer for reading */
- if(hdr->filter_len > 0) {
+ if(hdr->filter_len > 0 || !is_read) {
if(NULL == (read_buf = H5MM_malloc((size_t)obj_size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer")
} /* end if */
else
- read_buf = obj;
+ read_buf = op_data;
/* Read the object's (possibly filtered) data from the file */
+ /* (reads directly into application's buffer if no filters are present) */
if(H5F_block_read(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, (size_t)obj_size, dxpl_id, read_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_READERROR, FAIL, "can't read 'huge' object's data from the file")
@@ -672,20 +676,110 @@ H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj)
read_size = nbytes = obj_size;
if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_NO_EDC, filter_cb, &nbytes, &read_size, &read_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "input filter failed")
+ obj_size = nbytes;
+ } /* end if */
- /* Copy object to user's buffer */
- HDmemcpy(obj, read_buf, nbytes);
+ /* Perform correct operation on buffer read in */
+ if(is_read) {
+ /* Copy object to user's buffer if there's filters on heap data */
+ /* (if there's no filters, the object was read directly into the user's buffer) */
+ if(hdr->filter_len > 0)
+ HDmemcpy(op_data, read_buf, (size_t)obj_size);
+ } /* end if */
+ else {
+ /* Call the user's 'op' callback */
+ if(op(read_buf, (size_t)obj_size, op_data) < 0) {
+ /* Release buffer */
+ H5MM_xfree(read_buf);
- /* Release read buffer */
- H5MM_xfree(read_buf);
+ /* Indicate error */
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "application's callback failed")
+ } /* end if */
} /* end if */
+ /* Release the buffer for reading */
+ if(hdr->filter_len > 0 || !is_read)
+ H5MM_xfree(read_buf);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_huge_op_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_huge_read
+ *
+ * Purpose: Read a 'huge' object from the heap
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sept 11 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_read)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(id);
+ HDassert(obj);
+
+ /* Call the internal 'op' routine */
+ if(H5HF_huge_op_real(hdr, dxpl_id, id, TRUE, NULL, obj) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_huge_read() */
/*-------------------------------------------------------------------------
+ * Function: H5HF_huge_op
+ *
+ * Purpose: Operate directly on a 'huge' object
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sept 11 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_huge_op(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
+ H5HF_operator_t op, void *op_data)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_op)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(id);
+ HDassert(op);
+
+ /* Call the internal 'op' routine routine */
+ if(H5HF_huge_op_real(hdr, dxpl_id, id, FALSE, op, op_data) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_huge_op() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_huge_remove
*
* Purpose: Remove a 'huge' object from the file and the v2 B-tree tracker