summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5Abtree2.c239
-rw-r--r--src/H5Adense.c35
-rw-r--r--src/H5Apkg.h16
-rw-r--r--src/H5B2dbg.c18
-rw-r--r--src/H5B2private.h1
-rw-r--r--src/H5Fpkg.h4
-rw-r--r--src/H5Gbtree2.c7
-rw-r--r--src/H5O.c2
-rw-r--r--src/H5Ocache.c3
-rw-r--r--src/H5Ocopy.c2
-rw-r--r--src/H5Odbg.c3
-rw-r--r--src/H5Opkg.h15
-rw-r--r--src/H5Oshmesg.c1
-rw-r--r--src/H5Otest.c65
14 files changed, 364 insertions, 47 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() */
+