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 | |
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)
-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 | ||||
-rw-r--r-- | test/fheap.c | 229 |
7 files changed, 419 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: diff --git a/test/fheap.c b/test/fheap.c index 6daa7c0..c8087fa 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -14090,6 +14090,7 @@ error: #endif /* QAK */ #endif /* QAK2 */ +#ifndef QAK /*------------------------------------------------------------------------- * Function: test_filtered_man_root_direct @@ -14564,6 +14565,7 @@ error: } H5E_END_TRY; return(1); } /* test_filtered_man_root_indirect() */ +#endif /* QAK */ #ifndef QAK @@ -14989,6 +14991,213 @@ error: /*------------------------------------------------------------------------- + * Function: test_write + * + * Purpose: Test inserting objects, then changing the value for them. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, December 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_write(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[FHEAP_FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + H5HF_create_t tmp_cparam; /* Local heap creation parameters */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned char tiny_heap_id[HEAP_ID_LEN]; /* Heap ID for 'tiny' object */ + unsigned char huge_heap_id[HEAP_ID_LEN]; /* Heap ID for 'huge' object */ + hbool_t id_changed = FALSE; /* Whether the heap ID changed */ + unsigned char *rewrite_obj; /* Pointer to re-write buffer for objects */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + h5_stat_size_t empty_size; /* Size of a file with an empty heap */ + size_t obj_size; /* Size of object */ + size_t obj_loc; /* Location of object in buffer */ + fheap_heap_state_t state; /* State of fractal heap */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* + * Display testing message + */ + if(tparam->comp == FHEAP_TEST_COMPRESS) + TESTING("writing objects in heap with compressed blocks") + else + TESTING("writing objects in heap") + + /* Copy heap creation properties */ + HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t)); + + /* Check if we are compressing the blocks */ + if(tparam->comp == FHEAP_TEST_COMPRESS) { + unsigned deflate_level; /* Deflation level */ + + /* Set an I/O filter for heap data */ + deflate_level = 6; + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Get information about heap ID lengths */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > MAX_HEAP_ID_LEN) + TEST_ERROR + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + + /* Create 'tiny' and 'huge' objects */ + obj_size = id_len / 2; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, tiny_heap_id) < 0) + FAIL_STACK_ERROR + + obj_size = tmp_cparam.max_man_size + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, huge_heap_id) < 0) + FAIL_STACK_ERROR + + /* Verify that writing to 'tiny' and 'huge' objects return failure (for now) */ + H5E_BEGIN_TRY { + ret = H5HF_write(fh, dxpl, tiny_heap_id, &id_changed, shared_wobj_g); + } H5E_END_TRY; + HDassert(!id_changed); + if(ret >= 0) + TEST_ERROR + + H5E_BEGIN_TRY { + ret = H5HF_write(fh, dxpl, huge_heap_id, &id_changed, shared_wobj_g); + } H5E_END_TRY; + HDassert(!id_changed); + if(ret >= 0) + TEST_ERROR + + /* Initialize data to overwrite with */ + rewrite_obj = H5MM_malloc(shared_obj_size_g); + for(u = 0; u < shared_obj_size_g; u++) + rewrite_obj[u] = shared_wobj_g[u] * 2; + + /* Insert different sized objects, but stay out of "tiny" and "huge" zones */ + obj_size = 20; + for(u = 0; u < 40; u++) { + obj_loc = u; + if(add_obj(fh, dxpl, obj_loc, obj_size, NULL, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Overwrite data just written */ + if(H5HF_write(fh, dxpl, &keep_ids.ids[id_len * u], &id_changed, rewrite_obj) < 0) + FAIL_STACK_ERROR + HDassert(!id_changed); + + /* Read data back in */ + if(H5HF_read(fh, dxpl, &keep_ids.ids[id_len * u], shared_robj_g) < 0) + FAIL_STACK_ERROR + + /* Compare data read in */ + if(HDmemcmp(rewrite_obj, shared_robj_g, obj_size)) + TEST_ERROR + + /* Change size of data to write */ + if(u < 20) + obj_size *= 1.3; + else + obj_size /= 1.3; + } /* end for */ + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Re-open the heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + + /* Verify changed objects */ + obj_size = 20; + for(u = 0; u < 40; u++) { + /* Read data back in */ + if(H5HF_read(fh, dxpl, &keep_ids.ids[id_len * u], shared_robj_g) < 0) + FAIL_STACK_ERROR + + /* Compare data read in */ + if(HDmemcmp(rewrite_obj, shared_robj_g, obj_size)) + TEST_ERROR + + /* Change size of data to write */ + if(u < 20) + obj_size *= 1.3; + else + obj_size /= 1.3; + } /* end for */ + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(rewrite_obj); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(rewrite_obj); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_write() */ + +#ifndef QAK + +/*------------------------------------------------------------------------- * Function: test_bug1 * * Purpose: Test inserting several objects, then deleting one and @@ -15154,6 +15363,7 @@ error: } H5E_END_TRY; return(1); } /* test_bug1() */ +#endif /* QAK */ /*------------------------------------------------------------------------- @@ -15529,6 +15739,7 @@ HDfprintf(stderr, "Uncomment tests!\n"); /* Test I/O filter support */ +#ifndef QAK /* Try several different methods of deleting objects */ { fheap_test_del_dir_t del_dir; /* Deletion direction */ @@ -15550,6 +15761,9 @@ HDfprintf(stderr, "Uncomment tests!\n"); tparam.comp = FHEAP_TEST_NO_COMPRESS; } /* end for */ } /* end block */ +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ #ifndef QAK /* Random object insertion & deletion */ @@ -15598,12 +15812,27 @@ HDfprintf(stderr, "Uncomment tests!\n"); HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ + /* Test object writing support */ + + /* Basic object writing */ + nerrors += test_write(fapl, &small_cparam, &tparam); + + /* Writing objects in heap with filters */ + tparam.comp = FHEAP_TEST_COMPRESS; + nerrors += test_write(fapl, &small_cparam, &tparam); + + /* Reset block compression */ + tparam.comp = FHEAP_TEST_NO_COMPRESS; #ifndef QAK } /* end for */ #endif /* QAK */ /* Tests that address specific bugs */ +#ifndef QAK nerrors += test_bug1(fapl, &small_cparam, &tparam); +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ if(nerrors) goto error; |