diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5HF.c | 121 | ||||
-rw-r--r-- | src/H5HFhuge.c | 6 | ||||
-rw-r--r-- | src/H5HFman.c | 68 | ||||
-rw-r--r-- | src/H5HFpkg.h | 9 | ||||
-rw-r--r-- | src/H5HFprivate.h | 6 | ||||
-rw-r--r-- | src/H5HFtiny.c | 2 |
6 files changed, 190 insertions, 22 deletions
@@ -83,9 +83,9 @@ H5FL_DEFINE_STATIC(H5HF_t); /*------------------------------------------------------------------------- - * Function: H5HF_op_memcpy + * Function: H5HF_op_read * - * Purpose: Performs a 'memcpy' operation for a heap 'op' callback + * Purpose: Performs a 'read' operation for a heap 'op' callback * * Return: SUCCEED/FAIL * @@ -96,15 +96,40 @@ H5FL_DEFINE_STATIC(H5HF_t); *------------------------------------------------------------------------- */ herr_t -H5HF_op_memcpy(const void *obj, size_t obj_len, void *op_data) +H5HF_op_read(const void *obj, size_t obj_len, void *op_data) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_op_memcpy) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_op_read) - /* Perform memcpy() */ + /* Perform "read", using memcpy() */ HDmemcpy(op_data, obj, obj_len); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HF_op_memcpy() */ +} /* end H5HF_op_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_op_write + * + * Purpose: Performs a 'write' operation for a heap 'op' callback + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Dec 18 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_op_write(const void *obj, size_t obj_len, void *op_data) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_op_write) + + /* Perform "write", using memcpy() */ + HDmemcpy((void *)obj, op_data, obj_len); /* Casting away const OK -QAK */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_op_write() */ /*------------------------------------------------------------------------- @@ -516,10 +541,94 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_write + * + * Purpose: Write an object from a buffer into a fractal heap + * + * Notes: Writing objects in "managed" heap blocks is only storage + * method currently supported. (Which could be expanded to + * 'huge' and 'tiny' objects, with some work) + * + * Also, assumes that the 'op' routine modifies the data, and + * marks data to be written back to disk, even if 'op' routine + * didn't actually change anything. (Which could be modified + * to pass "did_modify" flag to callback, if necessary) + * + * Also, assumes that object to write is same size as object in + * heap. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Dec 18 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_write(H5HF_t *fh, hid_t dxpl_id, void *_id, hbool_t UNUSED *id_changed, + const void *obj) +{ + uint8_t *id = (uint8_t *)_id; /* Object ID */ + uint8_t id_flags; /* Heap ID flag bits */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5HF_write, FAIL) + + /* + * Check arguments. + */ + HDassert(fh); + HDassert(id); + HDassert(obj); + + /* Get the ID flags */ + id_flags = *id; + + /* Check for correct heap ID version */ + if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR) + HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "incorrect heap ID version") + + /* Set the shared heap header's file context for this operation */ + fh->hdr->f = fh->f; + + /* Check type of object in heap */ + if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) { + /* Operate on object from managed heap blocks */ + /* (ID can't change and modifying object is "easy" to manage) */ + if(H5HF_man_write(fh->hdr, dxpl_id, id, obj) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "can't operate on object from fractal heap") + } /* end if */ + else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_HUGE) { + /* Check for writing a 'huge' object */ + /* (which isn't supported yet - ID could change and lots of work to re-compress changed object) */ + HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "modifying 'huge' object not supported yet") + } /* end if */ + else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_TINY) { + /* Check for writing a 'tiny' object */ + /* (which isn't supported yet - ID will change) */ + HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "modifying 'tiny' object not supported yet") + } /* end if */ + else { +HDfprintf(stderr, "%s: Heap ID type not supported yet!\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "heap ID type not supported yet") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_write() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_op * * Purpose: Perform an operation directly on a heap object * + * Note: The library routines currently assume that the 'op' callback + * won't modify the object. This can easily be changed later for + * "managed" heap objects, and, with some difficulty, for 'huge' + * and 'tiny' heap objects. + * * Return: SUCCEED/FAIL * * Programmer: Quincey Koziol diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index da9f1a4..e2663cd 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -589,7 +589,7 @@ 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 */ + void *read_buf = NULL; /* Pointer to buffer for reading */ haddr_t obj_addr; /* Object's address in the file */ size_t obj_size = 0; /* Object's size in the file */ unsigned filter_mask = 0; /* Filter mask for object (only used for filtered objects) */ @@ -697,11 +697,11 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, } /* end if */ } /* end if */ +done: /* Release the buffer for reading */ - if(hdr->filter_len > 0 || !is_read) + if(read_buf && read_buf != op_data) H5MM_xfree(read_buf); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_huge_op_real() */ diff --git a/src/H5HFman.c b/src/H5HFman.c index 6270905..43c248b 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -58,7 +58,7 @@ /* Local Prototypes */ /********************/ static herr_t H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, - const uint8_t *id, H5HF_operator_t op, void *op_data); + const uint8_t *id, H5HF_operator_t op, void *op_data, unsigned op_flags); /*********************/ /* Package Variables */ @@ -246,15 +246,17 @@ done: */ static herr_t H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, - H5HF_operator_t op, void *op_data) + H5HF_operator_t op, void *op_data, unsigned op_flags) { H5HF_direct_t *dblock = NULL; /* Pointer to direct block to query */ + H5AC_protect_t dblock_access; /* Access method for direct block */ + haddr_t dblock_addr; /* Direct block address */ + size_t dblock_size; /* Direct block size */ + unsigned dblock_cache_flags; /* Flags for unprotecting direct block */ hsize_t obj_off; /* Object's offset in heap */ size_t obj_len; /* Object's length in heap */ size_t blk_off; /* Offset of object in block */ uint8_t *p; /* Temporary pointer to obj info in block */ - haddr_t dblock_addr; /* Direct block address */ - size_t dblock_size; /* Direct block size */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_op_real) @@ -266,6 +268,16 @@ H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, HDassert(id); HDassert(op); + /* Set the access mode for the direct block */ + if(op_flags & H5HF_OP_MODIFY) { + dblock_access = H5AC_WRITE; + dblock_cache_flags = H5AC__DIRTIED_FLAG; + } /* end if */ + else { + dblock_access = H5AC_READ; + dblock_cache_flags = H5AC__NO_FLAGS_SET; + } /* end else */ + /* Skip over the flag byte */ id++; @@ -298,7 +310,7 @@ HDfprintf(stderr, "%s: hdr->man_dtable.cparam.max_direct_size = %Zu\n", FUNC, hd dblock_size = hdr->man_dtable.cparam.start_block_size; /* Lock direct block */ - if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, NULL, 0, H5AC_READ))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, NULL, 0, dblock_access))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") } /* end if */ else { @@ -327,7 +339,7 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr); } /* end if */ /* Lock direct block */ - if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, iblock, entry, H5AC_READ))) { + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, iblock, entry, dblock_access))) { /* Unlock indirect block */ if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") @@ -365,7 +377,7 @@ HDfprintf(stderr, "%s: dblock_addr = %a, dblock_size = %Zu\n", FUNC, dblock_addr done: /* Unlock direct block */ - if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) + if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, dblock_cache_flags) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block") FUNC_LEAVE_NOAPI(ret_value) @@ -400,7 +412,7 @@ H5HF_man_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj) HDassert(obj); /* Call the internal 'op' routine routine */ - if(H5HF_man_op_real(hdr, dxpl_id, id, H5HF_op_memcpy, obj) < 0) + if(H5HF_man_op_real(hdr, dxpl_id, id, H5HF_op_read, obj, 0) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object") done: @@ -409,6 +421,44 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_man_write + * + * Purpose: Write an object to a managed heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Dec 18 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_write(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, + const void *obj) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_write) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(id); + HDassert(obj); + + /* Call the internal 'op' routine routine */ + /* (Casting away const OK - QAK) */ + if(H5HF_man_op_real(hdr, dxpl_id, id, H5HF_op_write, (void *)obj, H5HF_OP_MODIFY) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_write() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_man_op * * Purpose: Operate directly on an object from a managed heap @@ -437,7 +487,7 @@ H5HF_man_op(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, HDassert(op); /* Call the internal 'op' routine routine */ - if(H5HF_man_op_real(hdr, dxpl_id, id, op, op_data) < 0) + if(H5HF_man_op_real(hdr, dxpl_id, id, op, op_data, 0) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object") done: diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index e927e4d..676a63e 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -178,6 +178,10 @@ #define H5HF_FSPACE_SECT_NORMAL_ROW 2 /* Section is a range of blocks in an indirect block row */ #define H5HF_FSPACE_SECT_INDIRECT 3 /* Section is a span of blocks in an indirect block */ +/* Flags for 'op' operations */ +#define H5HF_OP_MODIFY 0x0001 /* Operation will modify object */ +#define H5HF_OP_FLAGS (H5HF_OP_MODIFY) /* Bit-wise OR of all op flags */ + /****************************/ /* Package Private Typedefs */ /****************************/ @@ -617,6 +621,8 @@ H5_DLL herr_t H5HF_man_insert(H5HF_hdr_t *fh, hid_t dxpl_id, size_t obj_size, const void *obj, void *id); H5_DLL herr_t H5HF_man_read(H5HF_hdr_t *fh, hid_t dxpl_id, const uint8_t *id, void *obj); +H5_DLL herr_t H5HF_man_write(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, + const void *obj); H5_DLL herr_t H5HF_man_op(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, H5HF_operator_t op, void *op_data); H5_DLL herr_t H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id); @@ -709,7 +715,8 @@ H5_DLL herr_t H5HF_sect_indirect_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries); /* Internal operator callbacks */ -H5_DLL herr_t H5HF_op_memcpy(const void *obj, size_t obj_len, void *op_data); +H5_DLL herr_t H5HF_op_read(const void *obj, size_t obj_len, void *op_data); +H5_DLL herr_t H5HF_op_write(const void *obj, size_t obj_len, void *op_data); /* Testing routines */ #ifdef H5HF_TESTING diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index bc6363a..833f939 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -97,11 +97,11 @@ typedef struct H5HF_t H5HF_t; typedef herr_t (*H5HF_operator_t)(const void *obj/*in*/, size_t obj_len, void *op_data/*in,out*/); - /*****************************/ /* Library-private Variables */ /*****************************/ + /***************************************/ /* Library-private Function Prototypes */ /***************************************/ @@ -117,7 +117,9 @@ H5_DLL herr_t H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *id, size_t *obj_len_p/*out*/); H5_DLL herr_t H5HF_read(H5HF_t *fh, hid_t dxpl_id, const void *id, void *obj/*out*/); -H5_DLL herr_t H5HF_op(H5HF_t *fh, hid_t dxpl_id, const void *_id, +H5_DLL herr_t H5HF_write(H5HF_t *fh, hid_t dxpl_id, void *id, hbool_t *id_changed, + const void *obj); +H5_DLL herr_t H5HF_op(H5HF_t *fh, hid_t dxpl_id, const void *id, H5HF_operator_t op, void *op_data); H5_DLL herr_t H5HF_remove(H5HF_t *fh, hid_t dxpl_id, const void *id); H5_DLL herr_t H5HF_close(H5HF_t *fh, hid_t dxpl_id); diff --git a/src/H5HFtiny.c b/src/H5HFtiny.c index e1ce68c..a1458a5 100644 --- a/src/H5HFtiny.c +++ b/src/H5HFtiny.c @@ -322,7 +322,7 @@ H5HF_tiny_read(H5HF_hdr_t *hdr, const uint8_t *id, void *obj) HDassert(obj); /* Call the internal 'op' routine */ - if(H5HF_tiny_op_real(hdr, id, H5HF_op_memcpy, obj) < 0) + if(H5HF_tiny_op_real(hdr, id, H5HF_op_read, obj) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object") done: |