mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-25 17:00:45 +08:00
[svn-r13267] Description:
Add more support for creation order index operations to attributes: get deletions & compact<->dense storage transitions working. Tested on: FreeBSD/32 6.2 (duty) Mac OS X/32 10.4.8 (amazon)
This commit is contained in:
parent
d45c7c031f
commit
e4d94d7943
134
src/H5Adense.c
134
src/H5Adense.c
@ -722,6 +722,9 @@ H5A_dense_copy_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
|
||||
if(NULL == (udata->attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, FAIL, "can't decode attribute")
|
||||
|
||||
/* Set the creation order index for the attribute */
|
||||
udata->attr->crt_idx = udata->record->corder;
|
||||
|
||||
/* Check whether we should "reconstitute" the shared message info */
|
||||
if(udata->record->flags & H5O_MSG_FLAG_SHARED)
|
||||
H5SM_reconstitute(&(udata->attr->sh_loc), udata->record->id);
|
||||
@ -1082,31 +1085,43 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5A_dense_remove_bt2_cb(const void *_record, void *_bt2_udata)
|
||||
H5A_dense_remove_bt2_cb(const void *_record, void *_udata)
|
||||
{
|
||||
const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record;
|
||||
H5A_bt2_ud_common_t *bt2_udata = (H5A_bt2_ud_common_t *)_bt2_udata; /* User data for callback */
|
||||
H5A_bt2_ud_rm_t *udata = (H5A_bt2_ud_rm_t *)_udata; /* User data for callback */
|
||||
H5A_t *attr = *(H5A_t **)udata->common.found_op_data; /* Pointer to attribute to remove */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_remove_bt2_cb)
|
||||
|
||||
/* Check for inserting shared attribute */
|
||||
/* Check for removing shared attribute */
|
||||
if(record->flags & H5O_MSG_FLAG_SHARED) {
|
||||
/* Decrement the reference count on the shared attribute message */
|
||||
if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &((*(H5A_t **)bt2_udata->found_op_data)->sh_loc)) < 0)
|
||||
if(H5SM_try_delete(udata->common.f, udata->common.dxpl_id, H5O_ATTR_ID, &(attr->sh_loc)) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Perform the deletion action on the attribute */
|
||||
/* (takes care of shared & committed datatype/dataspace components) */
|
||||
if(H5O_attr_delete(bt2_udata->f, bt2_udata->dxpl_id, *(H5A_t **)bt2_udata->found_op_data) < 0)
|
||||
if(H5O_attr_delete(udata->common.f, udata->common.dxpl_id, attr) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
|
||||
|
||||
/* Remove record from fractal heap */
|
||||
if(H5HF_remove(bt2_udata->fheap, bt2_udata->dxpl_id, &record->id) < 0)
|
||||
if(H5HF_remove(udata->common.fheap, udata->common.dxpl_id, &record->id) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from fractal heap")
|
||||
} /* end else */
|
||||
|
||||
/* Check for removing the link from the creation order index */
|
||||
if(H5F_addr_defined(udata->corder_bt2_addr)) {
|
||||
/* Set up the user data for the v2 B-tree 'record remove' callback */
|
||||
udata->common.corder = attr->crt_idx;
|
||||
|
||||
/* Remove the record from the name index v2 B-tree */
|
||||
if(H5B2_remove(udata->common.f, udata->common.dxpl_id, H5A_BT2_CORDER, udata->corder_bt2_addr,
|
||||
udata, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5A_dense_remove_bt2_cb() */
|
||||
@ -1128,7 +1143,7 @@ done:
|
||||
herr_t
|
||||
H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
|
||||
{
|
||||
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree record removal */
|
||||
H5A_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */
|
||||
H5HF_t *fheap = NULL; /* Fractal heap handle */
|
||||
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
|
||||
H5A_t *attr_copy = NULL; /* Copy of attribute to remove */
|
||||
@ -1169,16 +1184,15 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
|
||||
} /* end if */
|
||||
|
||||
/* Set up the user data for the v2 B-tree 'record remove' callback */
|
||||
udata.f = f;
|
||||
udata.dxpl_id = dxpl_id;
|
||||
udata.fheap = fheap;
|
||||
udata.shared_fheap = shared_fheap;
|
||||
udata.name = name;
|
||||
udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
|
||||
udata.flags = 0;
|
||||
udata.corder = 0;
|
||||
udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */
|
||||
udata.found_op_data = &attr_copy;
|
||||
udata.common.f = f;
|
||||
udata.common.dxpl_id = dxpl_id;
|
||||
udata.common.fheap = fheap;
|
||||
udata.common.shared_fheap = shared_fheap;
|
||||
udata.common.name = name;
|
||||
udata.common.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
|
||||
udata.common.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */
|
||||
udata.common.found_op_data = &attr_copy;
|
||||
udata.corder_bt2_addr = oh->corder_bt2_addr;
|
||||
|
||||
/* Remove the record from the name index v2 B-tree */
|
||||
if(H5B2_remove(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, H5A_dense_remove_bt2_cb, &udata) < 0)
|
||||
@ -1302,37 +1316,38 @@ H5A_dense_delete_bt2_cb(const void *_record, void *_bt2_udata)
|
||||
{
|
||||
const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
|
||||
H5A_bt2_ud_common_t *bt2_udata = (H5A_bt2_ud_common_t *)_bt2_udata; /* User data for callback */
|
||||
H5HF_t *fheap; /* Fractal heap handle for attribute storage */
|
||||
H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */
|
||||
H5A_t *attr = NULL; /* Attribute being removed */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_delete_bt2_cb)
|
||||
|
||||
/* Check for shared attribute */
|
||||
if(record->flags & H5O_MSG_FLAG_SHARED)
|
||||
fheap = bt2_udata->shared_fheap;
|
||||
else
|
||||
fheap = bt2_udata->fheap;
|
||||
|
||||
/* Prepare user data for callback */
|
||||
/* down */
|
||||
fh_udata.f = bt2_udata->f;
|
||||
fh_udata.dxpl_id = bt2_udata->dxpl_id;
|
||||
fh_udata.record = record;
|
||||
/* up */
|
||||
fh_udata.attr = NULL;
|
||||
|
||||
/* Call fractal heap 'op' routine, to copy the attribute information */
|
||||
if(H5HF_op(fheap, bt2_udata->dxpl_id, &record->id, H5A_dense_copy_fh_cb, &fh_udata) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "heap op callback failed")
|
||||
|
||||
/* Check for shared attribute */
|
||||
if(record->flags & H5O_MSG_FLAG_SHARED) {
|
||||
H5O_shared_t sh_mesg; /* Temporary shared message info */
|
||||
|
||||
/* "reconstitute" the shared message info for the attribute */
|
||||
H5SM_reconstitute(&sh_mesg, record->id);
|
||||
|
||||
/* Decrement the reference count on the shared attribute message */
|
||||
if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &(fh_udata.attr->sh_loc)) < 0)
|
||||
if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &sh_mesg) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute")
|
||||
} /* end if */
|
||||
else {
|
||||
H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */
|
||||
|
||||
/* Prepare user data for callback */
|
||||
/* down */
|
||||
fh_udata.f = bt2_udata->f;
|
||||
fh_udata.dxpl_id = bt2_udata->dxpl_id;
|
||||
fh_udata.record = record;
|
||||
/* up */
|
||||
fh_udata.attr = NULL;
|
||||
|
||||
/* Call fractal heap 'op' routine, to copy the attribute information */
|
||||
if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, &record->id, H5A_dense_copy_fh_cb, &fh_udata) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "heap op callback failed")
|
||||
attr = fh_udata.attr;
|
||||
|
||||
/* Perform the deletion action on the attribute */
|
||||
/* (takes care of shared/committed datatype & dataspace components) */
|
||||
if(H5O_attr_delete(bt2_udata->f, bt2_udata->dxpl_id, fh_udata.attr) < 0)
|
||||
@ -1341,8 +1356,8 @@ H5A_dense_delete_bt2_cb(const void *_record, void *_bt2_udata)
|
||||
|
||||
done:
|
||||
/* Release resources */
|
||||
if(fh_udata.attr)
|
||||
H5O_msg_free_real(H5O_MSG_ATTR, fh_udata.attr);
|
||||
if(attr)
|
||||
H5O_msg_free_real(H5O_MSG_ATTR, attr);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5A_dense_delete_bt2_cb() */
|
||||
@ -1366,8 +1381,6 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
||||
{
|
||||
H5A_bt2_ud_common_t udata; /* v2 B-tree user data for deleting attributes */
|
||||
H5HF_t *fheap = NULL; /* Fractal heap handle */
|
||||
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
|
||||
htri_t attr_sharable; /* Flag indicating attributes are sharable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5A_dense_delete, FAIL)
|
||||
@ -1382,31 +1395,11 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
||||
if(NULL == (fheap = H5HF_open(f, dxpl_id, oh->attr_fheap_addr)))
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
|
||||
|
||||
/* Check if attributes are shared in this file */
|
||||
if((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID, dxpl_id)) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
|
||||
|
||||
/* Get handle for shared message heap, if attributes are sharable */
|
||||
if(attr_sharable) {
|
||||
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
|
||||
|
||||
/* Retrieve the address of the shared message's fractal heap */
|
||||
if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address")
|
||||
|
||||
/* Check if there are any shared messages currently */
|
||||
if(H5F_addr_defined(shared_fheap_addr)) {
|
||||
/* Open the fractal heap for shared header messages */
|
||||
if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr)))
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Create the "udata" information for v2 B-tree 'delete' */
|
||||
udata.f = f;
|
||||
udata.dxpl_id = dxpl_id;
|
||||
udata.fheap = fheap;
|
||||
udata.shared_fheap = shared_fheap;
|
||||
udata.shared_fheap = NULL;
|
||||
udata.name = NULL;
|
||||
udata.name_hash = 0;
|
||||
udata.flags = 0;
|
||||
@ -1420,15 +1413,18 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
||||
oh->name_bt2_addr = HADDR_UNDEF;
|
||||
|
||||
/* Release resources */
|
||||
if(shared_fheap) {
|
||||
if(H5HF_close(shared_fheap, dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
|
||||
shared_fheap = NULL;
|
||||
} /* end if */
|
||||
if(H5HF_close(fheap, dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
|
||||
fheap = NULL;
|
||||
|
||||
/* Check if we should delete the creation order index v2 B-tree */
|
||||
if(H5F_addr_defined(oh->corder_bt2_addr)) {
|
||||
/* Delete the creation order index, without adjusting the ref. count on the attributes */
|
||||
if(H5B2_delete(f, dxpl_id, H5A_BT2_CORDER, oh->corder_bt2_addr, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index")
|
||||
oh->corder_bt2_addr = HADDR_UNDEF;
|
||||
} /* end if */
|
||||
|
||||
/* Delete fractal heap */
|
||||
if(H5HF_delete(f, dxpl_id, oh->attr_fheap_addr) < 0)
|
||||
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete fractal heap")
|
||||
@ -1436,8 +1432,6 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
||||
|
||||
done:
|
||||
/* Release resources */
|
||||
if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0)
|
||||
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
|
||||
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
|
||||
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
|
||||
|
||||
|
10
src/H5Apkg.h
10
src/H5Apkg.h
@ -124,6 +124,16 @@ typedef struct H5A_bt2_ud_ins_t {
|
||||
H5O_fheap_id_t id; /* Heap ID of attribute to insert */
|
||||
} H5A_bt2_ud_ins_t;
|
||||
|
||||
/*
|
||||
* Data exchange structure for dense attribute storage. This structure is
|
||||
* passed through the v2 B-tree layer when removing attributes.
|
||||
*/
|
||||
typedef struct H5A_bt2_ud_rm_t {
|
||||
/* downward */
|
||||
H5A_bt2_ud_common_t common; /* Common info for B-tree user data (must be first) */
|
||||
haddr_t corder_bt2_addr; /* v2 B-tree address of creation order index */
|
||||
} H5A_bt2_ud_rm_t;
|
||||
|
||||
/* Data structure to hold table of attributes for an object */
|
||||
typedef struct {
|
||||
size_t nattrs; /* # of attributes in table */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
@ -9,8 +8,8 @@
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* Generated automatically by bin/make_err -- do not edit */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
@ -9,8 +8,8 @@
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* Generated automatically by bin/make_err -- do not edit */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
@ -9,8 +8,8 @@
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* Generated automatically by bin/make_err -- do not edit */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
@ -9,8 +8,8 @@
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* Generated automatically by bin/make_err -- do not edit */
|
||||
|
@ -120,7 +120,6 @@ typedef struct {
|
||||
/* downward */
|
||||
H5G_bt2_ud_common_t common; /* Common info for B-tree user data (must be first) */
|
||||
hbool_t rem_from_fheap; /* Whether to remove the link from the fractal heap */
|
||||
hbool_t rem_from_corder_index; /* Whether to remove the link from the creation order index */
|
||||
haddr_t corder_bt2_addr; /* Address of v2 B-tree indexing creation order */
|
||||
H5RS_str_t *grp_full_path_r; /* Full path of group where link is removed */
|
||||
hbool_t replace_names; /* Whether to replace the names of open objects */
|
||||
@ -134,7 +133,6 @@ typedef struct {
|
||||
/* downward */
|
||||
H5F_t *f; /* Pointer to file that fractal heap is in */
|
||||
hid_t dxpl_id; /* DXPL for operation */
|
||||
hbool_t rem_from_corder_index; /* Whether to remove the link from the creation order index */
|
||||
haddr_t corder_bt2_addr; /* Address of v2 B-tree indexing creation order */
|
||||
H5RS_str_t *grp_full_path_r; /* Full path of group where link is removed */
|
||||
hbool_t replace_names; /* Whether to replace the names of open objects */
|
||||
@ -1347,7 +1345,7 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
|
||||
|
||||
/* Check for removing the link from the creation order index */
|
||||
if(udata->rem_from_corder_index) {
|
||||
if(H5F_addr_defined(udata->corder_bt2_addr)) {
|
||||
H5G_bt2_ud_common_t bt2_udata; /* Info for B-tree callbacks */
|
||||
|
||||
/* Set up the user data for the v2 B-tree 'record remove' callback */
|
||||
@ -1355,7 +1353,6 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
|
||||
bt2_udata.corder = lnk->corder;
|
||||
|
||||
/* Remove the record from the name index v2 B-tree */
|
||||
HDassert(H5F_addr_defined(udata->corder_bt2_addr));
|
||||
if(H5B2_remove(udata->f, udata->dxpl_id, H5G_BT2_CORDER, udata->corder_bt2_addr,
|
||||
&bt2_udata, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from creation order index v2 B-tree")
|
||||
@ -1406,7 +1403,6 @@ H5G_dense_remove_bt2_cb(const void *_record, void *_bt2_udata)
|
||||
/* Set up the user data for fractal heap 'op' callback */
|
||||
fh_udata.f = bt2_udata->common.f;
|
||||
fh_udata.dxpl_id = bt2_udata->common.dxpl_id;
|
||||
fh_udata.rem_from_corder_index = bt2_udata->rem_from_corder_index;
|
||||
fh_udata.corder_bt2_addr = bt2_udata->corder_bt2_addr;
|
||||
fh_udata.grp_full_path_r = bt2_udata->grp_full_path_r;
|
||||
fh_udata.replace_names = bt2_udata->replace_names;
|
||||
@ -1469,7 +1465,6 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
|
||||
udata.common.found_op = NULL;
|
||||
udata.common.found_op_data = NULL;
|
||||
udata.rem_from_fheap = TRUE;
|
||||
udata.rem_from_corder_index = H5F_addr_defined(linfo->corder_bt2_addr);
|
||||
udata.corder_bt2_addr = linfo->corder_bt2_addr;
|
||||
udata.grp_full_path_r = grp_full_path_r;
|
||||
udata.replace_names = TRUE;
|
||||
@ -1569,7 +1564,7 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTOPERATE, FAIL, "link removal callback failed")
|
||||
HDassert(fh_udata.lnk);
|
||||
|
||||
/* Check for removing the link from the creation order index */
|
||||
/* Check for removing the link from the "other" index (creation order, when name used and vice versa) */
|
||||
if(H5F_addr_defined(bt2_udata->other_bt2_addr)) {
|
||||
H5G_bt2_ud_common_t other_bt2_udata; /* Info for B-tree callbacks */
|
||||
const H5B2_class_t *other_bt2_class; /* Class of "other" v2 B-tree */
|
||||
@ -1778,7 +1773,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link)
|
||||
udata.common.found_op = NULL;
|
||||
udata.common.found_op_data = NULL;
|
||||
udata.rem_from_fheap = FALSE; /* handled in "bulk" below by deleting entire heap */
|
||||
udata.rem_from_corder_index = FALSE;
|
||||
udata.corder_bt2_addr = linfo->corder_bt2_addr;
|
||||
udata.grp_full_path_r = NULL;
|
||||
udata.replace_names = FALSE;
|
||||
|
||||
@ -1803,7 +1798,10 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link)
|
||||
HDassert(H5F_addr_defined(linfo->corder_bt2_addr));
|
||||
if(H5B2_delete(f, dxpl_id, H5G_BT2_CORDER, linfo->corder_bt2_addr, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index")
|
||||
linfo->corder_bt2_addr = HADDR_UNDEF;
|
||||
} /* end if */
|
||||
else
|
||||
HDassert(!H5F_addr_defined(linfo->corder_bt2_addr));
|
||||
|
||||
/* Delete the fractal heap */
|
||||
if(H5HF_delete(f, dxpl_id, linfo->link_fheap_addr) < 0)
|
||||
|
316
test/tattr.c
316
test/tattr.c
@ -3054,6 +3054,321 @@ test_attr_corder_create_dense(hid_t fcpl, hid_t fapl)
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
} /* test_attr_corder_create_dense() */
|
||||
|
||||
/****************************************************************
|
||||
**
|
||||
** 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_transition(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 */
|
||||
char attrname[NAME_BUF_SIZE]; /* Name of attribute */
|
||||
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"));
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* Close file */
|
||||
ret = H5Fclose(fid);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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 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");
|
||||
|
||||
/* 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(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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
} /* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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(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");
|
||||
|
||||
/* 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 Dataset */
|
||||
ret = H5Dclose(dataset);
|
||||
CHECK(ret, FAIL, "H5Dclose");
|
||||
|
||||
/* Close file */
|
||||
ret = H5Fclose(fid);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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");
|
||||
} /* 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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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(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");
|
||||
|
||||
/* 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");
|
||||
|
||||
/* Delete all attributes */
|
||||
for(u = max_compact; u > 0; u--) {
|
||||
sprintf(attrname, "attr %02u", u);
|
||||
ret = H5Adelete(dataset, attrname);
|
||||
CHECK(ret, FAIL, "H5Adelete");
|
||||
} /* 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_shared_write(): Test basic H5A (attribute) code.
|
||||
@ -4657,6 +4972,7 @@ test_attr(void)
|
||||
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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user