diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-12-18 17:52:43 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-12-18 17:52:43 (GMT) |
commit | ddbc06fce64bc49ff6b3e83da3ff74d08251fc2c (patch) | |
tree | 2fd1ab62b539b7c05a2adf461006e1c07d6f3535 /src | |
parent | 9236c9a148aaf206294be0554cf78e7ab769bd51 (diff) | |
download | hdf5-ddbc06fce64bc49ff6b3e83da3ff74d08251fc2c.zip hdf5-ddbc06fce64bc49ff6b3e83da3ff74d08251fc2c.tar.gz hdf5-ddbc06fce64bc49ff6b3e83da3ff74d08251fc2c.tar.bz2 |
[svn-r13067] Description:
Add [quite] limited ability to update (ie. write) data for objects in
fractal heap. Limited to just updating objects in managed heap blocks (i.e.
not 'tiny' or 'huge' objects) and must be updated with data of the same length
as the object in the heap. Updating objects in compressed heaps does work
though [as long as the data isn't 'tiny' or 'huge'].
Needed for changing the data value or the name of an attribute that is
stored in dense or shared storage.
Tested on:
Linux/32 2.6 (chicago)
Linux/64 2.6 (chicago2)
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: |