From 1e5e6baad117093c66c922f157dade58b2716f89 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 8 Feb 2007 11:07:56 -0500 Subject: [svn-r13270] Description: Clean up some of the file space allocation formatting. Beef up the attribute creation order tests to make certain they are handling shared atributes correctly (which they apparently are :-) Tested on: FreeBSD/32 6.2 (duty) Mac OS X/32 10.4.8 (amazon) --- src/H5FD.c | 172 +++---- src/H5FDprivate.h | 1 - test/tattr.c | 1335 +++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 1037 insertions(+), 471 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index e5b36a1..c7fc753 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -63,6 +63,7 @@ static haddr_t H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, static haddr_t H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); +static herr_t H5FD_free_freelist(H5FD_t *file); static haddr_t H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); /* Declare a free list to manage the H5FD_free_t struct */ @@ -215,7 +216,7 @@ H5FD_free_cls(H5FD_class_t *cls) H5MM_xfree(cls); FUNC_LEAVE_NOAPI(SUCCEED) -} +} /* end H5FD_free_cls() */ /*------------------------------------------------------------------------- @@ -1154,10 +1155,11 @@ H5FD_close(H5FD_t *file) FUNC_ENTER_NOAPI(H5FD_close, FAIL) /* check args */ - assert(file && file->cls); + HDassert(file && file->cls); - /* Free the freelist (this call never fails) */ - (void)H5FD_free_freelist(file); + /* Free the freelist */ + if(H5FD_free_freelist(file) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't release file space free list") /* Prepare to close file by clearing all public fields */ driver = file->cls; @@ -1168,14 +1170,13 @@ H5FD_close(H5FD_t *file) * Dispatch to the driver for actual close. If the driver fails to * close the file then the file will be in an unusable state. */ - assert(driver->close); - + HDassert(driver->close); if((driver->close)(file) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "close failed") done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_close() */ /*------------------------------------------------------------------------- @@ -1189,7 +1190,7 @@ done: * Modifications: *------------------------------------------------------------------------- */ -herr_t +static herr_t H5FD_free_freelist(H5FD_t *file) { H5FD_mem_t i; @@ -1197,32 +1198,31 @@ H5FD_free_freelist(H5FD_t *file) unsigned nblocks = 0; hsize_t nbytes = 0; #endif /* H5F_DEBUG */ - herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_free_freelist, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_free_freelist) /* check args */ - assert(file && file->cls); + HDassert(file && file->cls); /* * Free all free-lists, leaking any memory thus described. Also leaks * file space allocated but not used when metadata aggregation is * turned on. */ - for (i = H5FD_MEM_DEFAULT; i < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, i)) { + for(i = H5FD_MEM_DEFAULT; i < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, i)) { H5FD_free_t *cur, *next; - for (cur = file->fl[i]; cur; cur = next) { + for( cur = file->fl[i]; cur; cur = next) { #ifdef H5F_DEBUG ++nblocks; nbytes += cur->size; #endif /* H5F_DEBUG */ next = cur->next; H5FL_FREE(H5FD_free_t, cur); - } + } /* end for */ file->fl[i] = NULL; - } + } /* end for */ #ifdef H5F_DEBUG if(nblocks && H5DEBUG(F)) @@ -1241,11 +1241,10 @@ H5FD_free_freelist(H5FD_t *file) file->accum_buf_size = file->accum_size = 0; file->accum_loc = HADDR_UNDEF; file->accum_dirty = 0; - } + } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD_free_freelist() */ /*------------------------------------------------------------------------- @@ -1648,6 +1647,9 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); if(size == file->maxsize) file->maxsize = 0; /*unknown*/ +#ifdef H5FD_ALLOC_DEBUG +HDfprintf(stderr, "%s: Exact size match (aligned)\n", FUNC); +#endif /* H5FD_ALLOC_DEBUG */ HGOTO_DONE(ret_value) } } @@ -1708,6 +1710,9 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); if(size == file->maxsize) file->maxsize = 0; /*unknown*/ +#ifdef H5FD_ALLOC_DEBUG +HDfprintf(stderr, "%s: Exact size match (unaligned)\n", FUNC); +#endif /* H5FD_ALLOC_DEBUG */ HGOTO_DONE(ret_value) } } /* end if */ @@ -1726,6 +1731,9 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); /* Couldn't find exact match, use best fitting piece found */ if(best) { +#ifdef H5FD_ALLOC_DEBUG +HDfprintf(stderr, "%s: Splitting %Hu byte sized block\n", FUNC, best->size); +#endif /* H5FD_ALLOC_DEBUG */ if(best->size == file->maxsize) file->maxsize = 0; /*unknown*/ @@ -2252,9 +2260,9 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type #endif /* H5FD_ALLOC_DEBUG */ /* Check args */ - assert(file); - assert(file->cls); - assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES); + HDassert(file); + HDassert(file->cls); + HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES); if(!H5F_addr_defined(addr) || addr > file->maxaddr || H5F_addr_overflow(addr, size) || (addr + size) > file->maxaddr) @@ -2337,87 +2345,87 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type } /* end if */ /* Scan through the existing blocks for the mapped type to see if we can extend one */ - curr=file->fl[mapped_type]; - last=prev=NULL; - while(curr!=NULL) { + curr = file->fl[mapped_type]; + last = prev = NULL; + while(curr != NULL) { /* Check if the block to free adjoins the start of the current block */ - if((addr+size)==curr->addr) { + if((addr + size) == curr->addr) { /* If we previously found & merged a node, eliminate it from the list & free it */ - if(last!=NULL) { + if(last != NULL) { /* Check if there was a previous block in the list */ - if(last_prev!=NULL) + if(last_prev != NULL) /* Eliminate the merged block from the list */ - last_prev->next=last->next; + last_prev->next = last->next; /* No previous block, this must be the head of the list */ else /* Eliminate the merged block from the list */ file->fl[mapped_type] = last->next; /* Check for eliminating the block before the 'current' one */ - if(last==prev) - prev=last_prev; + if(last == prev) + prev = last_prev; /* Free the memory for the merged block */ - H5FL_FREE(H5FD_free_t,last); + H5FL_FREE(H5FD_free_t, last); } /* end if */ /* Adjust the address and size of the block found */ - curr->addr=addr; - curr->size+=size; + curr->addr = addr; + curr->size += size; /* Adjust the information about to memory block to include the merged block */ - addr=curr->addr; - size=curr->size; + addr = curr->addr; + size = curr->size; /* Update the information about the merged node */ - last=curr; - last_prev=prev; + last = curr; + last_prev = prev; } /* end if */ else { /* Check if the block to free adjoins the end of the current block */ - if((curr->addr+curr->size)==addr) { + if((curr->addr + curr->size) == addr) { /* If we previously found & merged a node, eliminate it from the list & free it */ - if(last!=NULL) { + if(last != NULL) { /* Check if there was a previous block in the list */ - if(last_prev!=NULL) + if(last_prev != NULL) /* Eliminate the merged block from the list */ - last_prev->next=last->next; + last_prev->next = last->next; /* No previous block, this must be the head of the list */ else /* Eliminate the merged block from the list */ file->fl[mapped_type] = last->next; /* Check for eliminating the block before the 'current' one */ - if(last==prev) - prev=last_prev; + if(last == prev) + prev = last_prev; /* Free the memory for the merged block */ - H5FL_FREE(H5FD_free_t,last); + H5FL_FREE(H5FD_free_t, last); } /* end if */ /* Adjust the size of the block found */ - curr->size+=size; + curr->size += size; /* Adjust the information about to memory block to include the merged block */ - addr=curr->addr; - size=curr->size; + addr = curr->addr; + size = curr->size; /* Update the information about the merged node */ - last=curr; - last_prev=prev; + last = curr; + last_prev = prev; } /* end if */ } /* end else */ /* Advance to next node in list */ - prev=curr; - curr=curr->next; + prev = curr; + curr = curr->next; } /* end while */ /* Check if we adjusted an existing block */ - if(last!=NULL) { + if(last != NULL) { /* Move the node found to the front, if it wasn't already there */ - if(last_prev!=NULL) { - last_prev->next=last->next; + if(last_prev != NULL) { + last_prev->next = last->next; last->next = file->fl[mapped_type]; file->fl[mapped_type] = last; } /* end if */ @@ -2442,17 +2450,17 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type haddr_t eoa; eoa = file->cls->get_eoa(file, type); - if(eoa == (last->addr+last->size)) { + if(eoa == (last->addr + last->size)) { if(file->cls->set_eoa(file, type, last->addr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed") /* Remove this free block from the list */ file->fl[mapped_type] = last->next; - if(file->maxsize==last->size) - file->maxsize=0; /*unknown*/ + if(file->maxsize == last->size) + file->maxsize = 0; /*unknown*/ H5FL_FREE(H5FD_free_t, last); - } - } + } /* end if */ + } /* end if */ } else if(file->cls->free) { if((file->cls->free)(file, type, dxpl_id, addr, size) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed") @@ -2461,11 +2469,11 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type #ifdef H5F_DEBUG HDfprintf(stderr, "%s: LEAKED MEMORY!!!!!!\n", FUNC); #endif /* H5F_DEBUG */ - } + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_free() */ /*------------------------------------------------------------------------- @@ -2490,24 +2498,24 @@ haddr_t H5FDrealloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size, hsize_t new_size) { - haddr_t ret_value=HADDR_UNDEF; + haddr_t ret_value = HADDR_UNDEF; FUNC_ENTER_API(H5FDrealloc, HADDR_UNDEF) H5TRACE6("a", "xMtiahh", file, type, dxpl_id, old_addr, old_size, new_size); /* Check args */ if(H5P_DEFAULT == dxpl_id) - dxpl_id= H5P_DATASET_XFER_DEFAULT; + dxpl_id = H5P_DATASET_XFER_DEFAULT; else - if(TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list") - if(HADDR_UNDEF==(ret_value=H5FD_realloc(file, type, dxpl_id, old_addr, old_size, new_size))) + if(HADDR_UNDEF == (ret_value = H5FD_realloc(file, type, dxpl_id, old_addr, old_size, new_size))) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file reallocation request failed") done: FUNC_LEAVE_API(ret_value) -} +} /* end H5FDrealloc() */ /*------------------------------------------------------------------------- @@ -2538,21 +2546,19 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsi FUNC_ENTER_NOAPI(H5FD_realloc, HADDR_UNDEF) - if(new_size==old_size) { + if(new_size == old_size) { /*nothing to do*/ - - } else if(0==old_size) { + } else if(0 == old_size) { /* allocate memory */ - assert(!H5F_addr_defined(old_addr)); - if(HADDR_UNDEF==(new_addr=H5FD_alloc(file, type, dxpl_id, new_size))) + HDassert(!H5F_addr_defined(old_addr)); + if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size))) HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed") } else if(0==new_size) { /* free memory */ - assert(H5F_addr_defined(old_addr)); + HDassert(H5F_addr_defined(old_addr)); if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed") new_addr = HADDR_UNDEF; - } else if(new_sizesizeof(_buf) && NULL==(buf=H5MM_malloc((size_t)old_size))) { + if(old_size > sizeof(_buf) && NULL == (buf = H5MM_malloc((size_t)old_size))) { (void)H5FD_free(file, type, dxpl_id, new_addr, new_size); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed") - } + } /* end if */ if(H5FD_read(file, type, dxpl_id, old_addr, (size_t)old_size, buf) < 0 || H5FD_write(file, type, dxpl_id, new_addr, (size_t)old_size, buf) < 0) { (void)H5FD_free(file, type, dxpl_id, new_addr, new_size); - if(buf!=_buf) + if(buf != _buf) H5MM_xfree(buf); HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block") - } + } /* end if */ - if(buf!=_buf) + if(buf != _buf) H5MM_xfree(buf); if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed") - } + } /* end else */ /* Set return value */ - ret_value=new_addr; + ret_value = new_addr; done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_realloc() */ /*------------------------------------------------------------------------- diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 7bbabb9..202b7d1 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -53,7 +53,6 @@ H5_DLL hid_t H5FD_register(const void *cls, size_t size); H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); H5_DLL herr_t H5FD_close(H5FD_t *file); -H5_DLL herr_t H5FD_free_freelist(H5FD_t *file); H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2); H5_DLL int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/); H5_DLL haddr_t H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); diff --git a/test/tattr.c b/test/tattr.c index 1e2807b..6e0142c 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -65,6 +65,8 @@ /* Dataset Information */ #define DSET1_NAME "Dataset1" #define DSET2_NAME "Dataset2" +#define DSET3_NAME "Dataset3" +#define NUM_DSETS 3 /* Group Information */ #define GROUP1_NAME "/Group1" @@ -2757,7 +2759,8 @@ static void test_attr_corder_create_compact(hid_t fcpl, hid_t fapl) { hid_t fid; /* HDF5 File ID */ - hid_t dataset; /* Dataset ID */ + hid_t dset1, dset2, dset3; /* Dataset IDs */ + hid_t my_dataset; /* Current dataset ID */ hid_t sid; /* Dataspace ID */ hid_t attr; /* Attribute ID */ hid_t dcpl; /* Dataset creation property list ID */ @@ -2767,6 +2770,7 @@ test_attr_corder_create_compact(hid_t fcpl, hid_t fapl) htri_t is_dense; /* Are attributes stored densely? */ hsize_t nattrs; /* Number of attributes on object */ char attrname[NAME_BUF_SIZE]; /* Name of attribute */ + unsigned curr_dset; /* Current dataset to work on */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ @@ -2785,29 +2789,274 @@ test_attr_corder_create_compact(hid_t fcpl, hid_t fapl) ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)); CHECK(ret, FAIL, "H5Pset_attr_creation_order"); + /* Query the attribute creation properties */ + ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); + CHECK(ret, FAIL, "H5Pget_attr_phase_change"); + /* Create dataspace for dataset & attributes */ sid = H5Screate(H5S_SCALAR); CHECK(sid, FAIL, "H5Screate"); - /* Create a dataset */ - dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); - CHECK(dataset, FAIL, "H5Dcreate"); + /* Create datasets */ + dset1 = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset1, FAIL, "H5Dcreate"); + dset2 = H5Dcreate(fid, DSET2_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset2, FAIL, "H5Dcreate"); + dset3 = H5Dcreate(fid, DSET3_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset3, FAIL, "H5Dcreate"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ - /* Check on dataset's attribute storage status */ - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + /* Check on dataset's attribute storage status */ + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Create several attributes, but keep storage in compact form */ + for(u = 0; u < max_compact; u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (u + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + } /* end for */ + } /* end for */ + + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Open datasets created */ + dset1 = H5Dopen(fid, DSET1_NAME); + CHECK(dset1, FAIL, "H5Dopen"); + dset2 = H5Dopen(fid, DSET2_NAME); + CHECK(dset2, FAIL, "H5Dopen"); + dset3 = H5Dopen(fid, DSET3_NAME); + CHECK(dset3, FAIL, "H5Dopen"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ + + /* Check on dataset's attribute storage status */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, max_compact, "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Loop through attributes, checking their creation order values */ + /* (the name index is used, but the creation order value is in the same order) */ + for(u = 0; u < max_compact; u++) { + H5A_info_t ainfo; /* Attribute information */ + + /* Retrieve information for attribute */ + sprintf(attrname, "attr %02u", u); + ret = H5Aget_info(my_dataset, attrname, &ainfo); + CHECK(ret, FAIL, "H5Aget_info"); + + /* Verify creation order of attribute */ + VERIFY(ainfo.corder_valid, TRUE, "H5Aget_info"); + VERIFY(ainfo.corder, u, "H5Aget_info"); + } /* end for */ + } /* end for */ + + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_corder_create_compact() */ + +/**************************************************************** +** +** test_attr_corder_create_dense(): Test basic H5A (attribute) code. +** Tests dense attribute storage on objects with attribute creation order info +** +****************************************************************/ +static void +test_attr_corder_create_dense(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* HDF5 File ID */ + hid_t dset1, dset2, dset3; /* Dataset IDs */ + hid_t my_dataset; /* Current dataset ID */ + hid_t sid; /* Dataspace ID */ + hid_t attr; /* Attribute ID */ + hid_t dcpl; /* Dataset creation property list ID */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + htri_t is_empty; /* Are there any attributes? */ + htri_t is_dense; /* Are attributes stored densely? */ + hsize_t nattrs; /* Number of attributes on object */ + hsize_t name_count; /* # of records in name index */ + hsize_t corder_count; /* # of records in creation order index */ + char attrname[NAME_BUF_SIZE]; /* Name of attribute */ + unsigned curr_dset; /* Current dataset to work on */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Dense Storage of Attributes with Creation Order Info\n")); + + /* Create file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create dataset creation property list */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + + /* Set attribute creation order tracking & indexing for object */ + ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)); + CHECK(ret, FAIL, "H5Pset_attr_creation_order"); /* Query the attribute creation properties */ ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); CHECK(ret, FAIL, "H5Pget_attr_phase_change"); - /* Create several attributes, but keep storage in compact form */ - for(u = 0; u < max_compact; u++) { - /* Create attribute */ - sprintf(attrname, "attr %02u", u); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + /* Create dataspace for dataset & attributes */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create datasets */ + dset1 = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset1, FAIL, "H5Dcreate"); + dset2 = H5Dcreate(fid, DSET2_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset2, FAIL, "H5Dcreate"); + dset3 = H5Dcreate(fid, DSET3_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset3, FAIL, "H5Dcreate"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ + + /* Check on dataset's attribute storage status */ + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Create several attributes, but keep storage in compact form */ + for(u = 0; u < max_compact; u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (u + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + } /* end for */ + + /* Create another attribute, to push into dense storage */ + sprintf(attrname, "attr %02u", max_compact); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); CHECK(attr, FAIL, "H5Acreate"); /* Write data into the attribute */ @@ -2819,23 +3068,32 @@ test_attr_corder_create_compact(hid_t fcpl, hid_t fapl) CHECK(ret, FAIL, "H5Aclose"); /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); + ret = H5O_num_attrs_test(my_dataset, &nattrs); CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (u + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); + VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); } /* end for */ + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + /* Close dataspace */ ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); - /* Close Dataset */ - ret = H5Dclose(dataset); - CHECK(ret, FAIL, "H5Dclose"); - /* Close property list */ ret = H5Pclose(dcpl); CHECK(ret, FAIL, "H5Pclose"); @@ -2849,54 +3107,83 @@ test_attr_corder_create_compact(hid_t fcpl, hid_t fapl) fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); CHECK(fid, FAIL, "H5Fopen"); - /* Open dataset created */ - dataset = H5Dopen(fid, DSET1_NAME); - CHECK(dataset, FAIL, "H5Dopen"); + /* Open datasets created */ + dset1 = H5Dopen(fid, DSET1_NAME); + CHECK(dset1, FAIL, "H5Dopen"); + dset2 = H5Dopen(fid, DSET2_NAME); + CHECK(dset2, FAIL, "H5Dopen"); + dset3 = H5Dopen(fid, DSET3_NAME); + CHECK(dset3, FAIL, "H5Dopen"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ - /* Check on dataset's attribute storage status */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, max_compact, "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + /* Check on dataset's attribute storage status */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); - /* Loop through attributes, checking their creation order values */ - /* (the name index is used, but the creation order value is in the same order) */ - for(u = 0; u < max_compact; u++) { - H5A_info_t ainfo; /* Attribute information */ + /* Loop through attributes, checking their creation order values */ + /* (the name index is used, but the creation order value is in the same order) */ + for(u = 0; u < (max_compact + 1); u++) { + H5A_info_t ainfo; /* Attribute information */ - /* Retrieve information for attribute */ - sprintf(attrname, "attr %02u", u); - ret = H5Aget_info(dataset, attrname, &ainfo); - CHECK(ret, FAIL, "H5Aget_info"); + /* Retrieve information for attribute */ + sprintf(attrname, "attr %02u", u); + ret = H5Aget_info(my_dataset, attrname, &ainfo); + CHECK(ret, FAIL, "H5Aget_info"); - /* Verify creation order of attribute */ - VERIFY(ainfo.corder_valid, TRUE, "H5Aget_info"); - VERIFY(ainfo.corder, u, "H5Aget_info"); + /* Verify creation order of attribute */ + VERIFY(ainfo.corder_valid, TRUE, "H5Aget_info"); + VERIFY(ainfo.corder, u, "H5Aget_info"); + } /* end for */ } /* end for */ - /* Close Dataset */ - ret = H5Dclose(dataset); + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); CHECK(ret, FAIL, "H5Dclose"); /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); -} /* test_attr_corder_create_compact() */ +} /* test_attr_corder_create_dense() */ /**************************************************************** ** -** test_attr_corder_create_dense(): Test basic H5A (attribute) code. -** Tests dense attribute storage on objects with attribute creation order info +** test_attr_corder_transition(): Test basic H5A (attribute) code. +** Tests attribute storage transitions on objects with attribute creation order info ** ****************************************************************/ static void -test_attr_corder_create_dense(hid_t fcpl, hid_t fapl) +test_attr_corder_transition(hid_t fcpl, hid_t fapl) { hid_t fid; /* HDF5 File ID */ - hid_t dataset; /* Dataset ID */ + hid_t dset1, dset2, dset3; /* Dataset IDs */ + hid_t my_dataset; /* Current dataset ID */ hid_t sid; /* Dataspace ID */ hid_t attr; /* Attribute ID */ hid_t dcpl; /* Dataset creation property list ID */ @@ -2908,11 +3195,12 @@ test_attr_corder_create_dense(hid_t fcpl, hid_t fapl) hsize_t name_count; /* # of records in name index */ hsize_t corder_count; /* # of records in creation order index */ char attrname[NAME_BUF_SIZE]; /* Name of attribute */ + unsigned curr_dset; /* Current dataset to work on */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ - MESSAGE(5, ("Testing Dense Storage of Attributes with Creation Order Info\n")); + MESSAGE(5, ("Testing Storage Transitions of Attributes with Creation Order Info\n")); /* Create file */ fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); @@ -2926,29 +3214,128 @@ test_attr_corder_create_dense(hid_t fcpl, hid_t fapl) ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)); CHECK(ret, FAIL, "H5Pset_attr_creation_order"); + /* Query the attribute creation properties */ + ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); + CHECK(ret, FAIL, "H5Pget_attr_phase_change"); + /* Create dataspace for dataset & attributes */ sid = H5Screate(H5S_SCALAR); CHECK(sid, FAIL, "H5Screate"); - /* Create a dataset */ - dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); - CHECK(dataset, FAIL, "H5Dcreate"); +/* XXX: Try to find a way to resize dataset's object header so that the object + * header can have one chunk, then retrieve "empty" file size and check + * that size after everything is deleted -QAK + */ + /* Create datasets */ + dset1 = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset1, FAIL, "H5Dcreate"); + dset2 = H5Dcreate(fid, DSET2_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset2, FAIL, "H5Dcreate"); + dset3 = H5Dcreate(fid, DSET3_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset3, FAIL, "H5Dcreate"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ - /* Check on dataset's attribute storage status */ - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + /* Check on dataset's attribute storage status */ + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + } /* end for */ - /* Query the attribute creation properties */ - ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); - CHECK(ret, FAIL, "H5Pget_attr_phase_change"); + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); - /* Create several attributes, but keep storage in compact form */ - for(u = 0; u < max_compact; u++) { - /* Create attribute */ - sprintf(attrname, "attr %02u", u); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + /* Close property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Open datasets created */ + dset1 = H5Dopen(fid, DSET1_NAME); + CHECK(dset1, FAIL, "H5Dopen"); + dset2 = H5Dopen(fid, DSET2_NAME); + CHECK(dset2, FAIL, "H5Dopen"); + dset3 = H5Dopen(fid, DSET3_NAME); + CHECK(dset3, FAIL, "H5Dopen"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ + + /* Create several attributes, but keep storage in compact form */ + for(u = 0; u < max_compact; u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (u + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + } /* end for */ + + /* Create another attribute, to push into dense storage */ + sprintf(attrname, "attr %02u", max_compact); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); CHECK(attr, FAIL, "H5Acreate"); /* Write data into the attribute */ @@ -2960,53 +3347,92 @@ test_attr_corder_create_dense(hid_t fcpl, hid_t fapl) CHECK(ret, FAIL, "H5Aclose"); /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); + ret = H5O_num_attrs_test(my_dataset, &nattrs); CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (u + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); + VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); - } /* end for */ + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); - /* Create another attribute, to push into dense storage */ - sprintf(attrname, "attr %02u", max_compact); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Acreate"); + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); - /* Write data into the attribute */ - ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); - CHECK(ret, FAIL, "H5Awrite"); + /* Delete several attributes from object, until attribute storage resumes compact form */ + for(u = max_compact; u >= min_dense; u--) { + sprintf(attrname, "attr %02u", u); + ret = H5Adelete(my_dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); - /* Close attribute */ - ret = H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, u, "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + } /* end for */ - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Delete another attribute, to push attribute storage into compact form */ + sprintf(attrname, "attr %02u", (min_dense - 1)); + ret = H5Adelete(my_dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); - /* Retrieve & verify # of records in the name & creation order indices */ - ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); - CHECK(ret, FAIL, "H5O_attr_dense_info_test"); - VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (min_dense - 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); - /* Close dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); + /* Re-add attributes to get back into dense form */ + for(u = (min_dense - 1); u < (max_compact + 1); u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); - /* Close Dataset */ - ret = H5Dclose(dataset); - CHECK(ret, FAIL, "H5Dclose"); + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); - /* Close property list */ - ret = H5Pclose(dcpl); - CHECK(ret, FAIL, "H5Pclose"); + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + } /* end for */ + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + } /* end for */ + + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); /* Close file */ ret = H5Fclose(fid); @@ -3017,54 +3443,152 @@ test_attr_corder_create_dense(hid_t fcpl, hid_t fapl) fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); CHECK(fid, FAIL, "H5Fopen"); - /* Open dataset created */ - dataset = H5Dopen(fid, DSET1_NAME); - CHECK(dataset, FAIL, "H5Dopen"); + /* Open datasets created */ + dset1 = H5Dopen(fid, DSET1_NAME); + CHECK(dset1, FAIL, "H5Dopen"); + dset2 = H5Dopen(fid, DSET2_NAME); + CHECK(dset2, FAIL, "H5Dopen"); + dset3 = H5Dopen(fid, DSET3_NAME); + CHECK(dset3, FAIL, "H5Dopen"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ - /* Check on dataset's attribute storage status */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Check on dataset's attribute storage status */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); - /* Loop through attributes, checking their creation order values */ - /* (the name index is used, but the creation order value is in the same order) */ - for(u = 0; u < (max_compact + 1); u++) { - H5A_info_t ainfo; /* Attribute information */ + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); - /* Retrieve information for attribute */ - sprintf(attrname, "attr %02u", u); - ret = H5Aget_info(dataset, attrname, &ainfo); - CHECK(ret, FAIL, "H5Aget_info"); + /* Delete several attributes from object, until attribute storage resumes compact form */ + for(u = max_compact; u >= min_dense; u--) { + sprintf(attrname, "attr %02u", u); + ret = H5Adelete(my_dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, u, "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + } /* end for */ + + /* Delete another attribute, to push attribute storage into compact form */ + sprintf(attrname, "attr %02u", (min_dense - 1)); + ret = H5Adelete(my_dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); - /* Verify creation order of attribute */ - VERIFY(ainfo.corder_valid, TRUE, "H5Aget_info"); - VERIFY(ainfo.corder, u, "H5Aget_info"); + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (min_dense - 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Re-add attributes to get back into dense form */ + for(u = (min_dense - 1); u < (max_compact + 1); u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + } /* end for */ + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + + /* Delete all attributes */ + for(u = max_compact; u > 0; u--) { + sprintf(attrname, "attr %02u", u); + ret = H5Adelete(my_dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); + } /* end for */ + sprintf(attrname, "attr %02u", 0); + ret = H5Adelete(my_dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); } /* end for */ - /* Close Dataset */ - ret = H5Dclose(dataset); + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); -} /* test_attr_corder_create_dense() */ +} /* test_attr_corder_transition() */ /**************************************************************** ** -** test_attr_corder_transition(): Test basic H5A (attribute) code. -** Tests attribute storage transitions on objects with attribute creation order info +** test_attr_corder_delete(): Test basic H5A (attribute) code. +** Tests deleting object w/dense attribute storage on objects with attribute creation order info ** ****************************************************************/ static void -test_attr_corder_transition(hid_t fcpl, hid_t fapl) +test_attr_corder_delete(hid_t fcpl, hid_t fapl) { hid_t fid; /* HDF5 File ID */ - hid_t dataset; /* Dataset ID */ + hid_t dset1, dset2, dset3; /* Dataset IDs */ + hid_t my_dataset; /* Current dataset ID */ hid_t sid; /* Dataspace ID */ hid_t attr; /* Attribute ID */ hid_t dcpl; /* Dataset creation property list ID */ @@ -3075,16 +3599,22 @@ test_attr_corder_transition(hid_t fcpl, hid_t fapl) hsize_t nattrs; /* Number of attributes on object */ hsize_t name_count; /* # of records in name index */ hsize_t corder_count; /* # of records in creation order index */ + hbool_t reopen_file; /* Whether to re-open the file before deleting group */ char attrname[NAME_BUF_SIZE]; /* Name of attribute */ +#ifdef LATER + h5_stat_size_t empty_size; /* Size of empty file */ + h5_stat_size_t file_size; /* Size of file after operating on it */ +#endif /* LATER */ + unsigned curr_dset; /* Current dataset to work on */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ - MESSAGE(5, ("Testing Storage Transitions of Attributes with Creation Order Info\n")); + MESSAGE(5, ("Testing Deleting Object w/Dense Attribute Storage and Creation Order Info\n")); - /* Create file */ - fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); - CHECK(fid, FAIL, "H5Fcreate"); + /* Create dataspace for dataset & attributes */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); /* Create dataset creation property list */ dcpl = H5Pcreate(H5P_DATASET_CREATE); @@ -3094,203 +3624,248 @@ test_attr_corder_transition(hid_t fcpl, hid_t fapl) ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)); CHECK(ret, FAIL, "H5Pset_attr_creation_order"); - /* Create dataspace for dataset & attributes */ - sid = H5Screate(H5S_SCALAR); - CHECK(sid, FAIL, "H5Screate"); - - /* Create a dataset */ - dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); - CHECK(dataset, FAIL, "H5Dcreate"); - - /* Check on dataset's attribute storage status */ - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); - /* Query the attribute creation properties */ ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); CHECK(ret, FAIL, "H5Pget_attr_phase_change"); - /* Close Dataset */ - ret = H5Dclose(dataset); - CHECK(ret, FAIL, "H5Dclose"); - /* Close property list */ - ret = H5Pclose(dcpl); - CHECK(ret, FAIL, "H5Pclose"); +/* XXX: Try to find a way to resize dataset's object header so that the object + * header can have one chunk, then retrieve "empty" file size and check + * that size after everything is deleted -QAK + */ +#ifdef LATER + /* Create empty file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); + /* Get the size of an empty file */ + empty_size = h5_get_file_size(FILENAME); + CHECK(empty_size, FAIL, "h5_get_file_size"); +#endif /* LATER */ - /* Re-open file */ - fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); - CHECK(fid, FAIL, "H5Fopen"); - - /* Open dataset created */ - dataset = H5Dopen(fid, DSET1_NAME); - CHECK(dataset, FAIL, "H5Dopen"); - - /* Create several attributes, but keep storage in compact form */ - for(u = 0; u < max_compact; u++) { - /* Create attribute */ - sprintf(attrname, "attr %02u", u); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Acreate"); - - /* Write data into the attribute */ - ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); - CHECK(ret, FAIL, "H5Awrite"); - /* Close attribute */ - ret = H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); + /* Loop to leave file open when deleting dataset, or to close & re-open file + * before deleting dataset */ + for(reopen_file = FALSE; reopen_file <= TRUE; reopen_file++) { + /* Create test file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fopen"); - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (u + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); - } /* end for */ + /* Create datasets */ + dset1 = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset1, FAIL, "H5Dcreate"); + dset2 = H5Dcreate(fid, DSET2_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset2, FAIL, "H5Dcreate"); + dset3 = H5Dcreate(fid, DSET3_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dset3, FAIL, "H5Dcreate"); + + /* Work on all the datasets */ + for(curr_dset = 0; curr_dset < NUM_DSETS; curr_dset++) { + switch(curr_dset) { + case 0: + my_dataset = dset1; + break; + + case 1: + my_dataset = dset2; + break; + + case 2: + my_dataset = dset3; + break; + + default: + HDassert(0 && "Too many datasets!"); + } /* end switch */ - /* Create another attribute, to push into dense storage */ - sprintf(attrname, "attr %02u", max_compact); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Acreate"); + /* Check on dataset's attribute storage status */ + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Create attributes, until attribute storage is in dense form */ + for(u = 0; u < max_compact * 2; u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(my_dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); - /* Write data into the attribute */ - ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); - CHECK(ret, FAIL, "H5Awrite"); + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); - /* Close attribute */ - ret = H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + } /* end for */ + + /* Verify state of object */ + ret = H5O_num_attrs_test(my_dataset, &nattrs); + CHECK(ret, FAIL, "H5O_num_attrs_test"); + VERIFY(nattrs, (max_compact * 2), "H5O_num_attrs_test"); + is_empty = H5O_is_attr_empty_test(my_dataset); + VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(my_dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Retrieve & verify # of records in the name & creation order indices */ + ret = H5O_attr_dense_info_test(my_dataset, &name_count, &corder_count); + CHECK(ret, FAIL, "H5O_attr_dense_info_test"); + VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + } /* end for */ - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Close Datasets */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); - /* Retrieve & verify # of records in the name & creation order indices */ - ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); - CHECK(ret, FAIL, "H5O_attr_dense_info_test"); - VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + /* Check for deleting datasets without re-opening file */ + if(!reopen_file) { + ret = H5Ldelete(fid, DSET1_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + ret = H5Ldelete(fid, DSET2_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + ret = H5Ldelete(fid, DSET3_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + } /* end if */ - /* Delete several attributes from object, until attribute storage resumes compact form */ - for(u = max_compact; u >= min_dense; u--) { - sprintf(attrname, "attr %02u", u); - ret = H5Adelete(dataset, attrname); - CHECK(ret, FAIL, "H5Adelete"); + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, u, "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Check for deleting dataset after re-opening file */ + if(reopen_file) { + /* Re-open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Delete the datasets */ + ret = H5Ldelete(fid, DSET1_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + ret = H5Ldelete(fid, DSET2_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + ret = H5Ldelete(fid, DSET3_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } /* end if */ - /* Retrieve & verify # of records in the name & creation order indices */ - ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); - CHECK(ret, FAIL, "H5O_attr_dense_info_test"); - VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); +#ifdef LATER + /* Get the size of the file now */ + file_size = h5_get_file_size(FILENAME); + CHECK(file_size, FAIL, "h5_get_file_size"); + VERIFY(file_size, empty_size, "h5_get_file_size"); +#endif /* LATER */ } /* end for */ - /* Delete another attribute, to push attribute storage into compact form */ - sprintf(attrname, "attr %02u", (min_dense - 1)); - ret = H5Adelete(dataset, attrname); - CHECK(ret, FAIL, "H5Adelete"); + /* Close property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (min_dense - 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + /* Close dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* test_attr_corder_delete() */ - /* Re-add attributes to get back into dense form */ - for(u = (min_dense - 1); u < (max_compact + 1); u++) { - /* Create attribute */ - sprintf(attrname, "attr %02u", u); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Acreate"); +#ifdef NOT_YET +/**************************************************************** +** +** test_attr_info_by_idx(): Test basic H5A (attribute) code. +** Tests querying attribute info by index +** +****************************************************************/ +static void +test_attr_info_by_idx(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* HDF5 File ID */ + hid_t dataset; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hid_t attr; /* Attribute ID */ + hid_t dcpl; /* Dataset creation property list ID */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + htri_t is_empty; /* Are there any attributes? */ + htri_t is_dense; /* Are attributes stored densely? */ + hsize_t nattrs; /* Number of attributes on object */ + hsize_t name_count; /* # of records in name index */ + hsize_t corder_count; /* # of records in creation order index */ + hbool_t use_index; /* Use index on creation order values */ + char attrname[NAME_BUF_SIZE]; /* Name of attribute */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ - /* Write data into the attribute */ - ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); - CHECK(ret, FAIL, "H5Awrite"); + /* Create dataspace for dataset & attributes */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); - /* Close attribute */ - ret = H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); - } /* end for */ + /* Loop over using index for creation order value */ + for(use_index = FALSE; use_index <= TRUE; use_index++) { + /* Output message about test being performed */ + if(use_index) + MESSAGE(5, ("Testing Querying Attribute Info By Index w/Creation Order Index\n")); + else + MESSAGE(5, ("Testing Querying Attribute Info By Index w/o Creation Order Index\n")); - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Create file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); - /* Retrieve & verify # of records in the name & creation order indices */ - ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); - CHECK(ret, FAIL, "H5O_attr_dense_info_test"); - VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + /* Create dataset creation property list */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); - /* Close Dataset */ - ret = H5Dclose(dataset); - CHECK(ret, FAIL, "H5Dclose"); + /* Set attribute creation order tracking & indexing for object */ + ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | (use_index ? H5P_CRT_ORDER_INDEXED : (unsigned)0))); + CHECK(ret, FAIL, "H5Pset_attr_creation_order"); - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + /* Create a dataset */ + dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dataset, FAIL, "H5Dcreate"); + /* Check on dataset's attribute storage status */ + is_empty = H5O_is_attr_empty_test(dataset); + VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test"); + is_dense = H5O_is_attr_dense_test(dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); - /* Re-open file */ - fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); - CHECK(fid, FAIL, "H5Fopen"); + /* Query the attribute creation properties */ + ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); + CHECK(ret, FAIL, "H5Pget_attr_phase_change"); - /* Open dataset created */ - dataset = H5Dopen(fid, DSET1_NAME); - CHECK(dataset, FAIL, "H5Dopen"); + /* Close property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Check on dataset's attribute storage status */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Create attributes, until attribute storage is in dense form */ + for(u = 0; u < max_compact * 2; u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); - /* Retrieve & verify # of records in the name & creation order indices */ - ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); - CHECK(ret, FAIL, "H5O_attr_dense_info_test"); - VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); - /* Delete several attributes from object, until attribute storage resumes compact form */ - for(u = max_compact; u >= min_dense; u--) { - sprintf(attrname, "attr %02u", u); - ret = H5Adelete(dataset, attrname); - CHECK(ret, FAIL, "H5Adelete"); + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + } /* end for */ /* Verify state of object */ ret = H5O_num_attrs_test(dataset, &nattrs); CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, u, "H5O_num_attrs_test"); + VERIFY(nattrs, (max_compact * 2), "H5O_num_attrs_test"); is_empty = H5O_is_attr_empty_test(dataset); VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); is_dense = H5O_is_attr_dense_test(dataset); @@ -3300,74 +3875,43 @@ test_attr_corder_transition(hid_t fcpl, hid_t fapl) ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); CHECK(ret, FAIL, "H5O_attr_dense_info_test"); VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); - } /* end for */ - - /* Delete another attribute, to push attribute storage into compact form */ - sprintf(attrname, "attr %02u", (min_dense - 1)); - ret = H5Adelete(dataset, attrname); - CHECK(ret, FAIL, "H5Adelete"); - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (min_dense - 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); - /* Re-add attributes to get back into dense form */ - for(u = (min_dense - 1); u < (max_compact + 1); u++) { - /* Create attribute */ - sprintf(attrname, "attr %02u", u); - attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Acreate"); + /* Check for deleting dataset without re-opening file */ + if(!reopen_file) { + ret = H5Ldelete(fid, DSET1_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + } /* end if */ - /* Write data into the attribute */ - ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); - CHECK(ret, FAIL, "H5Awrite"); + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); - /* Close attribute */ - ret = H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); - } /* end for */ + /* Check for deleting dataset after re-opening file */ + if(reopen_file) { + /* Re-open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); - /* Verify state of object */ - ret = H5O_num_attrs_test(dataset, &nattrs); - CHECK(ret, FAIL, "H5O_num_attrs_test"); - VERIFY(nattrs, (max_compact + 1), "H5O_num_attrs_test"); - is_empty = H5O_is_attr_empty_test(dataset); - VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test"); - is_dense = H5O_is_attr_dense_test(dataset); - VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + /* Delete the dataset */ + ret = H5Ldelete(fid, DSET1_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); - /* Retrieve & verify # of records in the name & creation order indices */ - ret = H5O_attr_dense_info_test(dataset, &name_count, &corder_count); - CHECK(ret, FAIL, "H5O_attr_dense_info_test"); - VERIFY(name_count, corder_count, "H5O_attr_dense_info_test"); + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } /* end if */ - /* Delete all attributes */ - for(u = max_compact; u > 0; u--) { - sprintf(attrname, "attr %02u", u); - ret = H5Adelete(dataset, attrname); - CHECK(ret, FAIL, "H5Adelete"); + /* Get the size of the file now */ + file_size = h5_get_file_size(FILENAME); + CHECK(file_size, FAIL, "h5_get_file_size"); + VERIFY(file_size, empty_size, "h5_get_file_size"); } /* end for */ - sprintf(attrname, "attr %02u", 0); - ret = H5Adelete(dataset, attrname); - CHECK(ret, FAIL, "H5Adelete"); - - /* Close Dataset */ - ret = H5Dclose(dataset); - CHECK(ret, FAIL, "H5Dclose"); - - /* Close dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); - - /* Close file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); -} /* test_attr_corder_transition() */ +} /* test_attr_corder_delete() */ +#endif /* NOT_YET */ /**************************************************************** ** @@ -4943,44 +5487,61 @@ test_attr(void) /* This next test uses its own file information */ test_attr_dtype_shared(my_fapl); /* Test using shared dataypes in attributes */ - } /* end for */ - /* Tests on "new format" attribute storage */ - /* Loop over using shared attributes */ - for(use_shared = FALSE; use_shared <= TRUE; use_shared++) { - hid_t my_fcpl; - - /* Set the FCPL for shared or not */ - if(use_shared) { - MESSAGE(7, ("testing with shared attributes\n")); - my_fcpl = fcpl2; + /* Tests on "new format" attribute storage */ + if(new_format == TRUE) { + /* Loop over using shared attributes */ + for(use_shared = FALSE; use_shared <= TRUE; use_shared++) { + hid_t my_fcpl; + + /* Set the FCPL for shared or not */ + if(use_shared) { + MESSAGE(7, ("testing with shared attributes\n")); + my_fcpl = fcpl2; + } /* end if */ + else { + MESSAGE(7, ("testing without shared attributes\n")); + my_fcpl = fcpl; + } /* end else */ + + /* General attribute tests */ + test_attr_dense_create(my_fcpl, my_fapl); /* Test dense attribute storage creation */ + test_attr_dense_open(my_fcpl, my_fapl); /* Test opening attributes in dense storage */ + test_attr_dense_delete(my_fcpl, my_fapl); /* Test deleting attributes in dense storage */ + test_attr_dense_rename(my_fcpl, my_fapl); /* Test renaming attributes in dense storage */ + test_attr_dense_unlink(my_fcpl, my_fapl); /* Test unlinking object with attributes in dense storage */ + test_attr_dense_limits(my_fcpl, my_fapl); /* Test dense attribute storage limits */ + + /* Attribute creation order tests */ + test_attr_corder_create_basic(my_fcpl, my_fapl);/* Test creating an object w/attribute creation order info */ +/* XXX: when creation order indexing is fully working, go back and add checks + * to these tests to make certain that the creation order values are + * correct. + */ + test_attr_corder_create_compact(my_fcpl, my_fapl); /* Test compact attribute storage on an object w/attribute creation order info */ + test_attr_corder_create_dense(my_fcpl, my_fapl);/* Test dense attribute storage on an object w/attribute creation order info */ + test_attr_corder_transition(my_fcpl, my_fapl); /* Test attribute storage transitions on an object w/attribute creation order info */ + test_attr_corder_delete(my_fcpl, my_fapl); /* Test deleting object using dense storage w/attribute creation order info */ + + /* New attribute API routine tests */ +#ifdef NOT_YET + test_attr_info_by_idx(my_fcpl, my_fapl); /* Test querying attribute info by index */ +#endif /* NOT_YET */ + + /* More complex tests with both "new format" and "shared" attributes */ + if(use_shared == TRUE) { + test_attr_shared_write(my_fcpl, my_fapl); /* Test writing to shared attributes in compact & dense storage */ + test_attr_shared_rename(my_fcpl, my_fapl); /* Test renaming shared attributes in compact & dense storage */ + test_attr_shared_delete(my_fcpl, my_fapl); /* Test deleting shared attributes in compact & dense storage */ + test_attr_shared_unlink(my_fcpl, my_fapl); /* Test unlinking object with shared attributes in compact & dense storage */ + } /* end if */ + } /* end for */ } /* end if */ else { - MESSAGE(7, ("testing without shared attributes\n")); - my_fcpl = fcpl; + /* New attribute API routine tests */ } /* end else */ - - /* General attribute tests */ - test_attr_dense_create(my_fcpl, fapl2); /* Test dense attribute storage creation */ - test_attr_dense_open(my_fcpl, fapl2); /* Test opening attributes in dense storage */ - test_attr_dense_delete(my_fcpl, fapl2); /* Test deleting attributes in dense storage */ - test_attr_dense_rename(my_fcpl, fapl2); /* Test renaming attributes in dense storage */ - test_attr_dense_unlink(my_fcpl, fapl2); /* Test unlinking object with attributes in dense storage */ - test_attr_dense_limits(my_fcpl, fapl2); /* Test dense attribute storage limits */ - - /* Attribute creation order tests */ - test_attr_corder_create_basic(my_fcpl, fapl2); /* Test creating an object w/attribute creation order info */ - test_attr_corder_create_compact(my_fcpl, fapl2); /* Test compact attribute storage on an object w/attribute creation order info */ - test_attr_corder_create_dense(my_fcpl, fapl2); /* Test dense attribute storage on an object w/attribute creation order info */ - test_attr_corder_transition(my_fcpl, fapl2); /* Test attribute storage transitions on an object w/attribute creation order info */ } /* end for */ - /* More complex tests with both "new format" and "shared" attributes */ - test_attr_shared_write(fcpl2, fapl2); /* Test writing to shared attributes in compact & dense storage */ - test_attr_shared_rename(fcpl2, fapl2); /* Test renaming shared attributes in compact & dense storage */ - test_attr_shared_delete(fcpl2, fapl2); /* Test deleting shared attributes in compact & dense storage */ - test_attr_shared_unlink(fcpl2, fapl2); /* Test unlinking object with shared attributes in compact & dense storage */ - /* Close FCPLs */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); -- cgit v0.12