summaryrefslogtreecommitdiffstats
path: root/src/H5Adense.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-12-12 20:28:48 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-12-12 20:28:48 (GMT)
commite9522de4e1ec02209673fb45378d1525cd723949 (patch)
tree181a6d2310d48598eda000bd18853c83e922f258 /src/H5Adense.c
parent6bf1f234f273937911e61e54d5218c0664048f05 (diff)
downloadhdf5-e9522de4e1ec02209673fb45378d1525cd723949.zip
hdf5-e9522de4e1ec02209673fb45378d1525cd723949.tar.gz
hdf5-e9522de4e1ec02209673fb45378d1525cd723949.tar.bz2
[svn-r13056] Description:
Add H5SM_type_shared() internal routine to determine if a particular type of header message is sharable in a file. Correct off-by-one error in computing B-tree record size for densely stored attributes' name index. Further progress toward supporting shared attributes in dense storage. Tested on: Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2)
Diffstat (limited to 'src/H5Adense.c')
-rw-r--r--src/H5Adense.c124
1 files changed, 94 insertions, 30 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 8dea1b7..e2a3d76 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -40,6 +40,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
+#include "H5SMprivate.h" /* Shared object header messages */
/****************/
@@ -65,8 +66,8 @@
#define H5A_CORDER_BT2_MERGE_PERC 40
#define H5A_CORDER_BT2_SPLIT_PERC 100
-/* Size of stack buffer for serialized attribute */
-#define H5A_ATTR_BUF_SIZE 128
+/* Size of stack buffer for serialized messages */
+#define H5A_MESG_BUF_SIZE 128
/******************/
@@ -457,6 +458,7 @@ HDfprintf(stderr, "%s: oh->attr_fheap_addr = %a\n", FUNC, oh->attr_fheap_addr);
if(H5HF_get_id_len(fheap, &fheap_id_len) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length")
HDassert(fheap_id_len == H5A_DENSE_FHEAP_ID_LEN);
+ HDassert(fheap_id_len == H5SM_FHEAP_ID_LEN); /* Need to be interchangable -QAK */
#ifdef QAK
HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len);
#endif /* QAK */
@@ -467,6 +469,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 */
+ 1 + /* Message flags */
fheap_id_len; /* Fractal heap ID */
if(H5B2_create(f, dxpl_id, H5A_BT2_NAME,
(size_t)H5A_NAME_BT2_NODE_SIZE, bt2_rrec_size,
@@ -574,6 +577,7 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
udata.f = f;
udata.dxpl_id = dxpl_id;
udata.fheap = fheap;
+ udata.shared_fheap = NULL;
udata.name = name;
udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
udata.flags = 0;
@@ -612,10 +616,13 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags,
const H5A_t *attr)
{
H5A_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
- H5HF_t *fheap = NULL; /* Fractal heap handle */
- size_t attr_size; /* Size of serialized attribute in the heap */
- uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
- void *attr_ptr = NULL; /* Pointer to serialized attribute */
+ H5HF_t *fheap = NULL; /* Fractal heap handle for attributes */
+ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ uint8_t id[H5A_DENSE_FHEAP_ID_LEN]; /* Heap ID of attribute to insert */
+ H5O_shared_t sh_mesg; /* Shared object header message */
+ uint8_t attr_buf[H5A_MESG_BUF_SIZE]; /* Buffer for serializing message */
+ void *attr_ptr = NULL; /* Pointer to serialized message */
+ htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_insert, FAIL)
@@ -627,48 +634,79 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags,
HDassert(oh);
HDassert(attr);
- /* Check for inserting shared attribute */
- if(mesg_flags & H5O_MSG_FLAG_SHARED) {
-/* XXX: fix me */
-HDfprintf(stderr, "%s: inserting shared attributes in dense storage not supported yet!\n", FUNC);
-HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "inserting shared attributes in dense storage not supported yet")
- } /* end if */
+ /* 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")
- /* Find out the size of buffer needed for serialized attribute */
- if((attr_size = H5O_msg_raw_size(f, H5O_ATTR_ID, attr)) == 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get attribute size")
+ /* Get handle for shared object heap, if attributes are sharable */
+ if(attr_sharable) {
+ haddr_t shared_fheap_addr; /* Address of fractal heap to use */
- /* Allocate space for serialized attribute, if necessary */
- if(attr_size > sizeof(attr_buf)) {
- if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
- else
- attr_ptr = attr_buf;
+ /* Retrieve the address of the shared object's fractal heap */
+ if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared object heap address")
- /* Create serialized form of attribute */
- if(H5O_msg_encode(f, H5O_ATTR_ID, attr_ptr, attr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute")
+ /* 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 */
/* Open the fractal heap */
if(NULL == (fheap = H5HF_open(f, dxpl_id, oh->attr_fheap_addr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
- /* Insert the serialized attribute into the fractal heap */
- if(H5HF_insert(fheap, dxpl_id, attr_size, attr_ptr, udata.id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert attribute into fractal heap")
+ /* Check for inserting shared attribute */
+ if(mesg_flags & H5O_MSG_FLAG_SHARED) {
+ /* Sanity check */
+ HDassert(attr_sharable);
+
+ /* Get the shared information for the attribute */
+ HDmemset(&sh_mesg, 0, sizeof(sh_mesg));
+ if(H5O_attr_get_share(attr, &sh_mesg) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared message")
+
+ /* Use heap ID for shared message heap */
+ udata.id = (const uint8_t *)&sh_mesg.u.heap_id;
+ } /* end if */
+ else {
+ size_t attr_size; /* Size of serialized attribute in the heap */
+
+ /* Find out the size of buffer needed for serialized message */
+ if((attr_size = H5O_msg_raw_size(f, H5O_ATTR_ID, attr)) == 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get message size")
+
+ /* Allocate space for serialized message, if necessary */
+ if(attr_size > sizeof(attr_buf)) {
+ if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+ else
+ attr_ptr = attr_buf;
+
+ /* Create serialized form of attribute or shared message */
+ if(H5O_msg_encode(f, H5O_ATTR_ID, attr_ptr, attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute")
+
+ /* Insert the serialized attribute into the fractal heap */
+ if(H5HF_insert(fheap, dxpl_id, attr_size, attr_ptr, id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert attribute into fractal heap")
+
+ /* Use heap ID for attribute heap */
+ udata.id = id;
+ } /* end else */
/* Create the callback information for v2 B-tree record insertion */
udata.common.f = f;
udata.common.dxpl_id = dxpl_id;
udata.common.fheap = fheap;
+ udata.common.shared_fheap = shared_fheap;
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.found_op = NULL;
udata.common.found_op_data = NULL;
- /* udata.id already set in H5HF_insert() call */
+ /* udata.id already set */
/* Insert attribute into 'name' tracking v2 B-tree */
if(H5B2_insert(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata) < 0)
@@ -676,6 +714,8 @@ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "inserting shared attributes in den
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")
if(attr_ptr && attr_ptr != attr_buf)
@@ -769,10 +809,12 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
{
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5A_bt2_od_wrt_t op_data; /* "Op data" for v2 B-tree modify */
+ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5HF_t *fheap = NULL; /* Fractal heap handle */
size_t attr_size; /* Size of serialized attribute in the heap */
- uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
+ uint8_t attr_buf[H5A_MESG_BUF_SIZE]; /* Buffer for serializing attribute */
void *attr_ptr = NULL; /* Pointer to serialized attribute */
+ htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_write, FAIL)
@@ -784,6 +826,23 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
HDassert(oh);
HDassert(attr);
+ /* 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 object 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 object's fractal heap */
+ if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared object heap address")
+
+ /* 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 */
+
/* Find out the size of buffer needed for serialized attribute */
if((attr_size = H5O_msg_raw_size(f, H5O_ATTR_ID, attr)) == 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get attribute size")
@@ -808,6 +867,7 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
udata.f = f;
udata.dxpl_id = dxpl_id;
udata.fheap = fheap;
+ udata.shared_fheap = shared_fheap;
udata.name = attr->name;
udata.name_hash = H5_checksum_lookup3(attr->name, HDstrlen(attr->name), 0);
udata.flags = 0;
@@ -827,6 +887,8 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
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")
if(attr_ptr && attr_ptr != attr_buf)
@@ -1151,6 +1213,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
udata.f = f;
udata.dxpl_id = dxpl_id;
udata.fheap = fheap;
+ udata.shared_fheap = NULL;
udata.name = name;
udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
udata.flags = 0;
@@ -1209,6 +1272,7 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
udata.f = f;
udata.dxpl_id = dxpl_id;
udata.fheap = fheap;
+ udata.shared_fheap = NULL;
udata.name = name;
udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
udata.flags = 0;