From d47a0604451a975d3389ff510b6cad6507ea7200 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 6 Feb 2007 21:18:17 -0500 Subject: [svn-r13250] Description: Add support for inserting attributes into creation order index. Also, update support for dense link & attribute storage in h5debug. Tested on: FreeBSD/32 6.2 (duty) Mac OS X/32 10.4.8 (amazon) --- src/H5Abtree2.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++---- src/H5Adense.c | 35 +++++--- src/H5Apkg.h | 16 +++- src/H5B2dbg.c | 18 +++- src/H5B2private.h | 1 + src/H5Fpkg.h | 4 +- src/H5Gbtree2.c | 7 +- src/H5O.c | 2 + src/H5Ocache.c | 3 + src/H5Ocopy.c | 2 + src/H5Odbg.c | 3 + src/H5Opkg.h | 15 ++-- src/H5Oshmesg.c | 1 - src/H5Otest.c | 65 ++++++++++++++ test/stab.c | 8 +- test/tattr.c | 169 ++++++++++++++++++++++++++++++++++++ tools/misc/h5debug.c | 53 +++++++++++- 17 files changed, 589 insertions(+), 52 deletions(-) diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c index 14d7bb9..25abd92 100644 --- a/src/H5Abtree2.c +++ b/src/H5Abtree2.c @@ -77,6 +77,17 @@ typedef struct H5A_fh_ud_cmp_t { /* v2 B-tree function callbacks */ +/* v2 B-tree driver callbacks for 'creation order' index */ +static herr_t H5A_dense_btree2_corder_store(void *native, const void *udata); +static herr_t H5A_dense_btree2_corder_retrieve(void *udata, const void *native); +static herr_t H5A_dense_btree2_corder_compare(const void *rec1, const void *rec2); +static herr_t H5A_dense_btree2_corder_encode(const H5F_t *f, uint8_t *raw, + const void *native); +static herr_t H5A_dense_btree2_corder_decode(const H5F_t *f, const uint8_t *raw, + void *native); +static herr_t H5A_dense_btree2_corder_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *_udata); + /* v2 B-tree driver callbacks for 'name' index */ static herr_t H5A_dense_btree2_name_store(void *native, const void *udata); static herr_t H5A_dense_btree2_name_retrieve(void *udata, const void *native); @@ -95,7 +106,7 @@ static herr_t H5A_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_da /*********************/ /* Package Variables */ /*********************/ -/* v2 B-tree class for indexing 'name' field of links */ +/* v2 B-tree class for indexing 'name' field of attributes */ const H5B2_class_t H5A_BT2_NAME[1]={{ /* B-tree class information */ H5B2_ATTR_DENSE_NAME_ID, /* Type of B-tree */ sizeof(H5A_dense_bt2_name_rec_t), /* Size of native record */ @@ -107,6 +118,18 @@ const H5B2_class_t H5A_BT2_NAME[1]={{ /* B-tree class information */ H5A_dense_btree2_name_debug /* Record debugging callback */ }}; +/* v2 B-tree class for indexing 'creation order' field of attributes */ +const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */ + H5B2_ATTR_DENSE_CORDER_ID, /* Type of B-tree */ + sizeof(H5A_dense_bt2_corder_rec_t),/* Size of native record */ + H5A_dense_btree2_corder_store, /* Record storage callback */ + H5A_dense_btree2_corder_retrieve, /* Record retrieval callback */ + H5A_dense_btree2_corder_compare, /* Record comparison callback */ + H5A_dense_btree2_corder_encode, /* Record encoding callback */ + H5A_dense_btree2_corder_decode, /* Record decoding callback */ + H5A_dense_btree2_corder_debug /* Record debugging callback */ +}}; + /*****************************/ /* Library Private Variables */ @@ -142,7 +165,7 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata) FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fh_name_cmp) - /* Decode link information */ + /* Decode attribute information */ if(NULL == (attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode attribute") @@ -155,6 +178,9 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata) if(udata->record->flags & H5O_MSG_FLAG_SHARED) H5SM_reconstitute(&(attr->sh_loc), udata->record->id); + /* Set the creation order index for the attribute */ + attr->crt_idx = udata->record->corder; + /* Make callback */ if((udata->found_op)(attr, udata->found_op_data) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPERATE, FAIL, "attribute found callback failed") @@ -191,9 +217,10 @@ H5A_dense_btree2_name_store(void *_nrecord, const void *_udata) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_store) /* Copy user information info native record */ - nrecord->hash = udata->common.name_hash; - nrecord->flags = udata->common.flags; nrecord->id = udata->id; + nrecord->flags = udata->common.flags; + nrecord->corder = udata->common.corder; + nrecord->hash = udata->common.name_hash; FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A_dense_btree2_name_store() */ @@ -252,9 +279,9 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec) /* Check hash value */ if(bt2_udata->name_hash < bt2_rec->hash) - HGOTO_DONE(-1) + ret_value = (-1); else if(bt2_udata->name_hash > bt2_rec->hash) - HGOTO_DONE(1) + ret_value = 1; else { H5A_fh_ud_cmp_t fh_udata; /* User data for fractal heap 'op' callback */ H5HF_t *fheap; /* Fractal heap handle to use for finding object */ @@ -282,15 +309,14 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec) fheap = bt2_udata->fheap; HDassert(fheap); - /* Check if the user's link and the B-tree's link have the same name */ + /* Check if the user's attribute and the B-tree's attribute have the same name */ status = H5HF_op(fheap, bt2_udata->dxpl_id, &bt2_rec->id, H5A_dense_fh_name_cmp, &fh_udata); HDassert(status >= 0); /* Callback will set comparison value */ - HGOTO_DONE(fh_udata.cmp) + ret_value = fh_udata.cmp; } /* end else */ -done: FUNC_LEAVE_NOAPI(ret_value) } /* H5A_dense_btree2_name_compare() */ @@ -316,9 +342,10 @@ H5A_dense_btree2_name_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_n FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_encode) /* Encode the record's fields */ - UINT32ENCODE(raw, nrecord->hash) - *raw++ = nrecord->flags; UINT64ENCODE(raw, nrecord->id); + *raw++ = nrecord->flags; + UINT32ENCODE(raw, nrecord->corder) + UINT32ENCODE(raw, nrecord->hash) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A_dense_btree2_name_encode() */ @@ -345,9 +372,10 @@ H5A_dense_btree2_name_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_n FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_decode) /* Decode the record's fields */ - UINT32DECODE(raw, nrecord->hash) - nrecord->flags = *raw++; UINT64DECODE(raw, nrecord->id); + nrecord->flags = *raw++; + UINT32DECODE(raw, nrecord->corder) + UINT32DECODE(raw, nrecord->hash) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A_dense_btree2_name_decode() */ @@ -374,9 +402,190 @@ H5A_dense_btree2_name_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dx FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_debug) - HDfprintf(stream, "%*s%-*s {%lx, %Hx, %02x}", indent, "", fwidth, "Record:", - nrecord->hash, nrecord->id, nrecord->flags); + HDfprintf(stream, "%*s%-*s {%016Hx, %02x, %u, %08lx}\n", indent, "", fwidth, + "Record:", + (hsize_t)nrecord->id, (unsigned)nrecord->flags, (unsigned)nrecord->corder, (unsigned long)nrecord->hash); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A_dense_btree2_name_debug() */ + +/*------------------------------------------------------------------------- + * Function: H5A_dense_btree2_corder_store + * + * Purpose: Store user information into native record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, February 6, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_btree2_corder_store(void *_nrecord, const void *_udata) +{ + const H5A_bt2_ud_ins_t *udata = (const H5A_bt2_ud_ins_t *)_udata; + H5A_dense_bt2_corder_rec_t *nrecord = (H5A_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_store) + + /* Copy user information info native record */ + nrecord->id = udata->id; + nrecord->flags = udata->common.flags; + nrecord->corder = udata->common.corder; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5A_dense_btree2_corder_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_dense_btree2_corder_retrieve + * + * Purpose: Retrieve native information from record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, February 6, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_btree2_corder_retrieve(void *udata, const void *nrecord) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_retrieve) + + *(H5A_dense_bt2_corder_rec_t *)udata = *(const H5A_dense_bt2_corder_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5A_dense_btree2_corder_retrieve() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_dense_btree2_corder_compare + * + * Purpose: Compare two native information records, according to some key + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Quincey Koziol + * Tuesday, February 6, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_btree2_corder_compare(const void *_bt2_udata, const void *_bt2_rec) +{ + const H5A_bt2_ud_common_t *bt2_udata = (const H5A_bt2_ud_common_t *)_bt2_udata; + const H5A_dense_bt2_corder_rec_t *bt2_rec = (const H5A_dense_bt2_corder_rec_t *)_bt2_rec; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_compare) + + /* Sanity check */ + HDassert(bt2_udata); + HDassert(bt2_rec); + + /* Check creation order value */ + if(bt2_udata->corder < bt2_rec->corder) + ret_value = -1; + else if(bt2_udata->corder > bt2_rec->corder) + ret_value = 1; + else + ret_value = 0; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_dense_btree2_corder_compare() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_dense_btree2_corder_encode + * + * Purpose: Encode native information into raw form for storing on disk + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, February 6, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord) +{ + const H5A_dense_bt2_corder_rec_t *nrecord = (const H5A_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_encode) + + /* Encode the record's fields */ + UINT64ENCODE(raw, nrecord->id); + *raw++ = nrecord->flags; + UINT32ENCODE(raw, nrecord->corder) + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5A_dense_btree2_corder_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_dense_btree2_corder_decode + * + * Purpose: Decode raw disk form of record into native form + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, February 6, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_btree2_corder_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord) +{ + H5A_dense_bt2_corder_rec_t *nrecord = (H5A_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_decode) + + /* Decode the record's fields */ + UINT64DECODE(raw, nrecord->id); + nrecord->flags = *raw++; + UINT32DECODE(raw, nrecord->corder) + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5A_dense_btree2_corder_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_dense_btree2_corder_debug + * + * Purpose: Debug native form of record + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, February 6, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_btree2_corder_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_nrecord, const void UNUSED *_udata) +{ + const H5A_dense_bt2_corder_rec_t *nrecord = (const H5A_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_debug) + + HDfprintf(stream, "%*s%-*s {%016Hx, %02x, %u}\n", indent, "", fwidth, + "Record:", + (hsize_t)nrecord->id, (unsigned)nrecord->flags, (unsigned)nrecord->corder); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5A_dense_btree2_corder_debug() */ + diff --git a/src/H5Adense.c b/src/H5Adense.c index f227730..a0de2fb 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -216,6 +216,7 @@ HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len); /* Create the name index v2 B-tree */ bt2_rrec_size = 4 + /* Name's hash value */ + 4 + /* Creation order index */ 1 + /* Message flags */ H5O_FHEAP_ID_LEN; /* Fractal heap ID */ if(H5B2_create(f, dxpl_id, H5A_BT2_NAME, @@ -227,23 +228,21 @@ HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len); HDfprintf(stderr, "%s: oh->name_bt2_addr = %a\n", FUNC, oh->name_bt2_addr); #endif /* QAK */ -/* XXX: fix me */ -#ifdef NOT_YET /* Check if we should create a creation order index v2 B-tree */ - if(linfo->index_corder) { + if(oh->flags & H5P_CRT_ORDER_INDEXED) { /* Create the creation order index v2 B-tree */ - bt2_rrec_size = 8 + /* Creation order value */ + bt2_rrec_size = 4 + /* Creation order index */ + 1 + /* Message flags */ H5O_FHEAP_ID_LEN; /* Fractal heap ID */ if(H5B2_create(f, dxpl_id, H5A_BT2_CORDER, (size_t)H5A_CORDER_BT2_NODE_SIZE, bt2_rrec_size, H5A_CORDER_BT2_SPLIT_PERC, H5A_CORDER_BT2_MERGE_PERC, - &(linfo->corder_bt2_addr)) < 0) + &(oh->corder_bt2_addr)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index") #ifdef QAK -HDfprintf(stderr, "%s: linfo->corder_bt2_addr = %a\n", FUNC, linfo->corder_bt2_addr); +HDfprintf(stderr, "%s: oh->corder_bt2_addr = %a\n", FUNC, oh->corder_bt2_addr); #endif /* QAK */ } /* end if */ -#endif /* NOT_YET */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -350,7 +349,7 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) udata.name = name; udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0); udata.flags = 0; - udata.corder = -1; /* XXX: None yet */ + udata.corder = 0; udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */ udata.found_op_data = &ret_value; @@ -484,7 +483,7 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr) udata.common.name = attr->name; udata.common.name_hash = H5_checksum_lookup3(attr->name, HDstrlen(attr->name), 0); udata.common.flags = mesg_flags; - udata.common.corder = -1; /* XXX: None yet */ + udata.common.corder = attr->crt_idx; udata.common.found_op = NULL; udata.common.found_op_data = NULL; /* udata.id already set */ @@ -493,6 +492,14 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr) if(H5B2_insert(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") + /* Check if we should create a creation order index v2 B-tree record */ + if(oh->flags & H5P_CRT_ORDER_INDEXED) { + /* Insert the record into the creation order index v2 B-tree */ + HDassert(H5F_addr_defined(oh->corder_bt2_addr)); + if(H5B2_insert(f, dxpl_id, H5A_BT2_CORDER, oh->corder_bt2_addr, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") + } /* end if */ + done: /* Release resources */ if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0) @@ -656,7 +663,7 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr) udata.name = attr->name; udata.name_hash = H5_checksum_lookup3(attr->name, HDstrlen(attr->name), 0); udata.flags = 0; - udata.corder = -1; /* XXX: None yet */ + udata.corder = 0; udata.found_op = NULL; udata.found_op_data = NULL; @@ -790,7 +797,7 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_name, udata.name = old_name; udata.name_hash = H5_checksum_lookup3(old_name, HDstrlen(old_name), 0); udata.flags = 0; - udata.corder = -1; /* XXX: None yet */ + udata.corder = 0; udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */ udata.found_op_data = &attr_copy; @@ -1168,7 +1175,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) udata.name = name; udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0); udata.flags = 0; - udata.corder = -1; /* XXX: None yet */ + udata.corder = 0; udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */ udata.found_op_data = &attr_copy; @@ -1253,7 +1260,7 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) udata.name = name; udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0); udata.flags = 0; - udata.corder = -1; /* XXX: None yet */ + udata.corder = 0; udata.found_op = NULL; /* v2 B-tree comparison callback */ udata.found_op_data = NULL; @@ -1402,7 +1409,7 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh) udata.name = NULL; udata.name_hash = 0; udata.flags = 0; - udata.corder = -1; /* XXX: None yet */ + udata.corder = 0; udata.found_op = NULL; /* v2 B-tree comparison callback */ udata.found_op_data = NULL; diff --git a/src/H5Apkg.h b/src/H5Apkg.h index eb2b11f..10aa0ad 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -81,10 +81,19 @@ struct H5A_t { /* (Keep 'id' field first so generic record handling in callbacks works) */ typedef struct H5A_dense_bt2_name_rec_t { H5O_fheap_id_t id; /* Heap ID for attribute */ - uint8_t flags; /* Message flags for attribute */ + uint8_t flags; /* Object header message flags for attribute */ + H5O_msg_crt_idx_t corder; /* 'creation order' field value */ uint32_t hash; /* Hash of 'name' field value */ } H5A_dense_bt2_name_rec_t; +/* Typedef for native 'creation order' field index records in the v2 B-tree */ +/* (Keep 'id' field first so generic record handling in callbacks works) */ +typedef struct H5A_dense_bt2_corder_rec_t { + H5O_fheap_id_t id; /* Heap ID for attribute */ + uint8_t flags; /* Object header message flags for attribute */ + H5O_msg_crt_idx_t corder; /* 'creation order' field value */ +} H5A_dense_bt2_corder_rec_t; + /* * Common data exchange structure for dense attribute storage. This structure * is passed through the v2 B-tree layer to the methods for the objects @@ -99,7 +108,7 @@ typedef struct H5A_bt2_ud_common_t { const char *name; /* Name of attribute to compare */ uint32_t name_hash; /* Hash of name of attribute to compare */ uint8_t flags; /* Flags for attribute storage location */ - int64_t corder; /* Creation order value of attribute to compare */ + H5O_msg_crt_idx_t corder; /* Creation order value of attribute to compare */ H5B2_found_t found_op; /* Callback when correct attribute is found */ void *found_op_data; /* Callback data when correct attribute is found */ } H5A_bt2_ud_common_t; @@ -149,6 +158,9 @@ H5FL_BLK_EXTERN(attr_buf); /* The v2 B-tree class for indexing 'name' field on attributes */ H5_DLLVAR const H5B2_class_t H5A_BT2_NAME[1]; +/* The v2 B-tree class for indexing 'creation order' field on attributes */ +H5_DLLVAR const H5B2_class_t H5A_BT2_CORDER[1]; + /******************************/ /* Package Private Prototypes */ diff --git a/src/H5B2dbg.c b/src/H5B2dbg.c index 27db285..d2a392e 100644 --- a/src/H5B2dbg.c +++ b/src/H5B2dbg.c @@ -130,8 +130,12 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" : (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" : (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" : + (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" : + (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" : (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" : - "Unknown!"))))))); + (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" : + (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" : + "Unknown!"))))))))))); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of node:", shared->node_size); @@ -252,8 +256,12 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" : (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" : (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" : + (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" : + (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" : (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" : - "Unknown!"))))))); + (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" : + (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" : + "Unknown!"))))))))))); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of node:", shared->node_size); @@ -374,8 +382,12 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" : (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" : (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" : + (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" : + (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" : (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" : - "Unknown!"))))))); + (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" : + (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" : + "Unknown!"))))))))))); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of node:", shared->node_size); diff --git a/src/H5B2private.h b/src/H5B2private.h index a0e9c3b..35ddfb0 100644 --- a/src/H5B2private.h +++ b/src/H5B2private.h @@ -52,6 +52,7 @@ typedef enum H5B2_subid_t { H5B2_GRP_DENSE_CORDER_ID, /* B-tree is for indexing 'creation order' field for "dense" link storage in groups */ H5B2_SOHM_INDEX_ID, /* B-tree is an index for shared object header messages */ H5B2_ATTR_DENSE_NAME_ID, /* B-tree is for indexing 'name' field for "dense" attribute storage on objects */ + H5B2_ATTR_DENSE_CORDER_ID, /* B-tree is for indexing 'creation order' field for "dense" attribute storage on objects */ H5B2_NUM_BTREE_ID /* Number of B-tree IDs (must be last) */ } H5B2_subid_t; diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index d1457df..83a5071 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -92,8 +92,8 @@ ( 2 /* indexed B-tree internal k */ \ + H5F_SIZEOF_ADDR(f) /* base address */ \ + H5F_SIZEOF_ADDR(f) /* free space address */ \ -/* + H5F_SIZEOF_ADDR(f) /* shared message table address */ \ -/* JAMES + 2 /* shared message version and number of indexes */ \ +/* + H5F_SIZEOF_ADDR(f) */ /* shared message table address */ \ +/* JAMES + 2 */ /* shared message version and number of indexes */ \ + H5F_SIZEOF_ADDR(f) /* EOF address */ \ + H5F_SIZEOF_ADDR(f) /* driver block address */ \ + H5G_SIZEOF_ENTRY(f) /* root group ptr */ \ diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index ed909c3..d8958fb 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -275,9 +275,9 @@ for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++) #endif /* QAK */ /* Check hash value */ if(bt2_udata->name_hash < bt2_rec->hash) - HGOTO_DONE(-1) + ret_value = (-1); else if(bt2_udata->name_hash > bt2_rec->hash) - HGOTO_DONE(1) + ret_value = 1; else { H5G_fh_ud_cmp_t fh_udata; /* User data for fractal heap 'op' callback */ herr_t status; /* Status from fractal heap 'op' routine */ @@ -302,10 +302,9 @@ for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++) HDassert(status >= 0); /* Callback will set comparison value */ - HGOTO_DONE(fh_udata.cmp) + ret_value = fh_udata.cmp; } /* end else */ -done: FUNC_LEAVE_NOAPI(ret_value) } /* H5G_dense_btree2_name_compare() */ diff --git a/src/H5O.c b/src/H5O.c index acba9dd..075f6a3 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -697,6 +697,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, /* Set starting values for attribute info */ oh->attr_fheap_addr = HADDR_UNDEF; oh->name_bt2_addr = HADDR_UNDEF; + oh->corder_bt2_addr = HADDR_UNDEF; } /* end if */ else { /* Reset unused time fields */ @@ -705,6 +706,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, /* Reset unused attribute fields */ oh->attr_fheap_addr = HADDR_UNDEF; oh->name_bt2_addr = HADDR_UNDEF; + oh->corder_bt2_addr = HADDR_UNDEF; } /* end else */ /* Compute total size of initial object header */ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 878faf8..f804468 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -304,6 +304,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, H5F_DECODE_LENGTH(f, p, oh->nattrs); H5F_addr_decode(f, &p, &(oh->attr_fheap_addr)); H5F_addr_decode(f, &p, &(oh->name_bt2_addr)); + H5F_addr_decode(f, &p, &(oh->corder_bt2_addr)); UINT16DECODE(p, oh->max_attr_crt_idx); } /* end if */ else { @@ -316,6 +317,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, oh->nattrs = 0; oh->attr_fheap_addr = HADDR_UNDEF; oh->name_bt2_addr = HADDR_UNDEF; + oh->corder_bt2_addr = HADDR_UNDEF; oh->max_attr_crt_idx = 0; } /* end else */ @@ -642,6 +644,7 @@ H5O_assert(oh); H5F_ENCODE_LENGTH(f, p, oh->nattrs); H5F_addr_encode(f, &p, oh->attr_fheap_addr); H5F_addr_encode(f, &p, oh->name_bt2_addr); + H5F_addr_encode(f, &p, oh->corder_bt2_addr); UINT16ENCODE(p, oh->max_attr_crt_idx); /* Chunk size */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 1592278..b703895 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -354,6 +354,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, oh_dst->nattrs = 0; oh_dst->attr_fheap_addr = HADDR_UNDEF; oh_dst->name_bt2_addr = HADDR_UNDEF; + oh_dst->corder_bt2_addr = HADDR_UNDEF; } /* end if */ else { oh_dst->nattrs = oh_src->nattrs; @@ -364,6 +365,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HDassert(!H5F_addr_defined(oh_src->name_bt2_addr)); oh_dst->attr_fheap_addr = HADDR_UNDEF; oh_dst->name_bt2_addr = HADDR_UNDEF; + oh_dst->corder_bt2_addr = HADDR_UNDEF; } /* end else */ } /* end else */ diff --git a/src/H5Odbg.c b/src/H5Odbg.c index 90c9376..50575da 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -320,6 +320,9 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Attribute name index address:", oh->name_bt2_addr); + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, + "Attribute creation order index address:", + oh->corder_bt2_addr); } /* end if */ HDfprintf(stream, "%*s%-*s %Zu (%Zu)\n", indent, "", fwidth, diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 3b39640..f7a2a08 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -98,14 +98,15 @@ 4 + /*modification time */ \ 4 + /*change time */ \ 4 + /*birth time */ \ - 2 + /*max compact attributes */ \ + 2 + /*max compact attributes */ \ 2 + /*min dense attributes */ \ - (O)->sizeof_size + /*# of attributes */ \ - (O)->sizeof_addr + /*addr of attribute heap */ \ - (O)->sizeof_addr + /*addr of attribute name index */ \ - 2 + /*max attr. creation index */ \ + (O)->sizeof_size + /*# of attributes */ \ + (O)->sizeof_addr + /*addr of attribute heap */ \ + (O)->sizeof_addr + /*addr of attribute name index */ \ + (O)->sizeof_addr + /*addr of attribute creation order index */ \ + 2 + /*max attr. creation index */ \ 4 + /*chunk data size */ \ - H5O_SIZEOF_CHKSUM) /*checksum size */ \ + H5O_SIZEOF_CHKSUM) /*checksum size */ \ ) /* @@ -245,6 +246,7 @@ struct H5O_t { hsize_t nattrs; /* Number of attributes in the group */ haddr_t attr_fheap_addr; /* Address of fractal heap for storing "dense" attributes */ haddr_t name_bt2_addr; /* Address of v2 B-tree for indexing names of attributes */ + haddr_t corder_bt2_addr; /* Address of v2 B-tree for indexing creation order of attributes */ H5O_msg_crt_idx_t max_attr_crt_idx; /* Maximum attribute creation index used */ /* Message management (stored, encoded in chunks) */ @@ -497,6 +499,7 @@ H5_DLL herr_t H5O_dest(H5F_t *f, H5O_t *oh); H5_DLL htri_t H5O_is_attr_empty_test(hid_t oid); H5_DLL htri_t H5O_is_attr_dense_test(hid_t oid); H5_DLL herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs); +H5_DLL herr_t H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count); #endif /* H5O_TESTING */ /* Object header debugging routines */ diff --git a/src/H5Oshmesg.c b/src/H5Oshmesg.c index 1a39af2..3a02302 100644 --- a/src/H5Oshmesg.c +++ b/src/H5Oshmesg.c @@ -251,4 +251,3 @@ H5O_shmesg_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_shmesg_debug() */ - diff --git a/src/H5Otest.c b/src/H5Otest.c index b1b0751..e442374 100644 --- a/src/H5Otest.c +++ b/src/H5Otest.c @@ -258,3 +258,68 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5O_num_attrs_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5O_attr_dense_info_test + PURPOSE + Retrieve information about the state of the "dense" storage for attributes + USAGE + herr_t H5O_attr_dense_info_test(oid, name_count, corder_count) + hid_t oid; IN: Object to check + hsize_t *name_count; OUT: Number of attributes in name index + hsize_t *corder_count; OUT: Number of attributes in creation order index + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Currently, just retrieves the number of attributes in each index and returns + them. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count) +{ + H5O_t *oh = NULL; /* Object header */ + H5O_loc_t *oloc; /* Pointer to object's location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_attr_dense_info_test, FAIL) + + /* Get object location for object */ + if(NULL == (oloc = H5O_get_loc(oid))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + + /* Get the object header */ + if(NULL == (oh = H5AC_protect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + + /* Check for 'dense' attribute storage file addresses being defined */ + if(!H5F_addr_defined(oh->attr_fheap_addr)) + HGOTO_DONE(FAIL) + if(!H5F_addr_defined(oh->name_bt2_addr)) + HGOTO_DONE(FAIL) + + /* Retrieve # of records in name index */ + if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, name_count) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") + + /* Check if there is a creation order index */ + if(H5F_addr_defined(oh->corder_bt2_addr)) { + /* Retrieve # of records in creation order index */ + if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_CORDER, oh->corder_bt2_addr, corder_count) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index") + } /* end if */ + else + *corder_count = 0; + +done: + if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_attr_dense_info_test() */ + diff --git a/test/stab.c b/test/stab.c index 47dbbfe..48e2bb9 100644 --- a/test/stab.c +++ b/test/stab.c @@ -426,9 +426,9 @@ lifecycle(hid_t fapl) /* Check that the object header is only one chunk and the space has been allocated correctly */ if(H5Gget_objinfo(gid, ".", FALSE, &obj_stat) < 0) TEST_ERROR #ifdef H5_HAVE_LARGE_HSIZET - if(obj_stat.ohdr.size != 250) TEST_ERROR + if(obj_stat.ohdr.size != 258) TEST_ERROR #else /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.size != 230) TEST_ERROR + if(obj_stat.ohdr.size != 238) TEST_ERROR #endif /* H5_HAVE_LARGE_HSIZET */ if(obj_stat.ohdr.free != 0) TEST_ERROR if(obj_stat.ohdr.nmesgs != 6) TEST_ERROR @@ -452,9 +452,9 @@ lifecycle(hid_t fapl) /* Check that the object header is still one chunk and the space has been allocated correctly */ if(H5Gget_objinfo(gid, ".", FALSE, &obj_stat) < 0) TEST_ERROR #ifdef H5_HAVE_LARGE_HSIZET - if(obj_stat.ohdr.size != 250) TEST_ERROR + if(obj_stat.ohdr.size != 258) TEST_ERROR #else /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.size != 230) TEST_ERROR + if(obj_stat.ohdr.size != 238) TEST_ERROR #endif /* H5_HAVE_LARGE_HSIZET */ if(obj_stat.ohdr.free != 120) TEST_ERROR if(obj_stat.ohdr.nmesgs != 3) TEST_ERROR diff --git a/test/tattr.c b/test/tattr.c index c877c37..ff04026 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -2887,6 +2887,174 @@ test_attr_corder_create_compact(hid_t fcpl, hid_t fapl) /**************************************************************** ** +** 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 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 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"); + + /* 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"); + + /* 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"); + + /* 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"); + + /* 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"); + + /* 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"); + + /* Verify creation order of attribute */ + VERIFY(ainfo.corder_valid, TRUE, "H5Aget_info"); + VERIFY(ainfo.corder, u, "H5Aget_info"); + } /* end for */ + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_corder_create_dense() */ + +/**************************************************************** +** ** test_attr_shared_write(): Test basic H5A (attribute) code. ** Tests writing mix of shared & un-shared attributes in "compact" & "dense" storage ** @@ -4487,6 +4655,7 @@ test_attr(void) /* 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 */ } /* end for */ /* More complex tests with both "new format" and "shared" attributes */ diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c index e9d80a6..061f5f1 100644 --- a/tools/misc/h5debug.c +++ b/tools/misc/h5debug.c @@ -24,22 +24,25 @@ * *------------------------------------------------------------------------- */ +#define H5A_PACKAGE /*suppress error about including H5Apkg */ #define H5B2_PACKAGE /*suppress error about including H5B2pkg */ #define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ #define H5FS_PACKAGE /*suppress error about including H5FSpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ #define H5HF_PACKAGE /*suppress error about including H5HFpkg */ #define H5O_PACKAGE /*suppress error about including H5Opkg */ #define H5SM_PACKAGE /*suppress error about including H5SMpkg */ #include "H5private.h" /* Generic Functions */ +#include "H5Apkg.h" /* Attributes */ #include "H5Bprivate.h" /* B-trees */ #include "H5B2pkg.h" /* v2 B-trees */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FSpkg.h" /* File free space */ -#include "H5Gprivate.h" /* Groups */ +#include "H5Gpkg.h" /* Groups */ #include "H5HFpkg.h" /* Fractal heaps */ #include "H5HGprivate.h" /* Global Heaps */ #include "H5HLprivate.h" /* Local Heaps */ @@ -234,10 +237,26 @@ main(int argc, char *argv[]) status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_DIR); break; + case H5B2_GRP_DENSE_NAME_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5G_BT2_NAME); + break; + + case H5B2_GRP_DENSE_CORDER_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5G_BT2_CORDER); + break; + case H5B2_SOHM_INDEX_ID: status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5SM_INDEX); break; + case H5B2_ATTR_DENSE_NAME_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5A_BT2_NAME); + break; + + case H5B2_ATTR_DENSE_CORDER_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5A_BT2_CORDER); + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); @@ -281,10 +300,26 @@ main(int argc, char *argv[]) status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_DIR, extra, (unsigned)extra2, (unsigned)extra3); break; + case H5B2_GRP_DENSE_NAME_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5G_BT2_NAME, extra, (unsigned)extra2, (unsigned)extra3); + break; + + case H5B2_GRP_DENSE_CORDER_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5G_BT2_CORDER, extra, (unsigned)extra2, (unsigned)extra3); + break; + case H5B2_SOHM_INDEX_ID: status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5SM_INDEX, extra, (unsigned)extra2, (unsigned)extra3); break; + case H5B2_ATTR_DENSE_NAME_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5A_BT2_NAME, extra, (unsigned)extra2, (unsigned)extra3); + break; + + case H5B2_ATTR_DENSE_CORDER_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5A_BT2_CORDER, extra, (unsigned)extra2, (unsigned)extra3); + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); @@ -327,10 +362,26 @@ main(int argc, char *argv[]) status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_DIR, extra, (unsigned)extra2); break; + case H5B2_GRP_DENSE_NAME_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5G_BT2_NAME, extra, (unsigned)extra2); + break; + + case H5B2_GRP_DENSE_CORDER_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5G_BT2_CORDER, extra, (unsigned)extra2); + break; + case H5B2_SOHM_INDEX_ID: status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5SM_INDEX, extra, (unsigned)extra2); break; + case H5B2_ATTR_DENSE_NAME_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5A_BT2_NAME, extra, (unsigned)extra2); + break; + + case H5B2_ATTR_DENSE_CORDER_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5A_BT2_CORDER, extra, (unsigned)extra2); + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); -- cgit v0.12