summaryrefslogtreecommitdiffstats
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
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)
-rw-r--r--src/H5Abtree2.c20
-rw-r--r--src/H5Adense.c124
-rw-r--r--src/H5Apkg.h3
-rw-r--r--src/H5Oattribute.c24
-rw-r--r--src/H5Opkg.h2
-rw-r--r--src/H5Oprivate.h2
-rwxr-xr-xsrc/H5SM.c144
-rwxr-xr-xsrc/H5SMprivate.h1
8 files changed, 244 insertions, 76 deletions
diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c
index 47cbaae..dc2478e 100644
--- a/src/H5Abtree2.c
+++ b/src/H5Abtree2.c
@@ -148,10 +148,9 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
udata->cmp = HDstrcmp(udata->name, attr->name);
/* Check for correct attribute & callback to make */
- if(udata->cmp == 0 && udata->found_op) {
+ if(udata->cmp == 0 && udata->found_op)
if((udata->found_op)(attr, udata->found_op_data) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPERATE, FAIL, "attribute found callback failed")
- } /* end if */
done:
/* Release the space allocated for the attrbute */
@@ -250,6 +249,7 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec)
HGOTO_DONE(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 */
herr_t status; /* Status from fractal heap 'op' routine */
/* Sanity check */
@@ -267,14 +267,14 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec)
fh_udata.cmp = 0;
/* Check for attribute in shared storage */
- if(bt2_rec->flags) {
-HDfprintf(stderr, "%s: Shared dense storage for attributes not supported yet!\n", "H5A_dense_btree2_name_compare");
-HDassert(0 && "Shared dense storage for attributes not supported yet!");
- } /* end if */
+ if(bt2_rec->flags)
+ fheap = bt2_udata->shared_fheap;
+ else
+ fheap = bt2_udata->fheap;
+ HDassert(fheap);
/* Check if the user's link and the B-tree's link have the same name */
- status = H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, bt2_rec->id,
- H5A_dense_fh_name_cmp, &fh_udata);
+ 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 */
@@ -308,8 +308,8 @@ H5A_dense_btree2_name_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_n
/* Encode the record's fields */
UINT32ENCODE(raw, nrecord->hash)
- HDmemcpy(raw, nrecord->id, (size_t)H5A_DENSE_FHEAP_ID_LEN);
*raw++ = nrecord->flags;
+ HDmemcpy(raw, nrecord->id, (size_t)H5A_DENSE_FHEAP_ID_LEN);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5A_dense_btree2_name_encode() */
@@ -337,8 +337,8 @@ H5A_dense_btree2_name_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_n
/* Decode the record's fields */
UINT32DECODE(raw, nrecord->hash)
- HDmemcpy(nrecord->id, raw, (size_t)H5A_DENSE_FHEAP_ID_LEN);
nrecord->flags = *raw++;
+ HDmemcpy(nrecord->id, raw, (size_t)H5A_DENSE_FHEAP_ID_LEN);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5A_dense_btree2_name_decode() */
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;
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 11dd43d..a3b0e70 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -96,6 +96,7 @@ typedef struct H5A_bt2_ud_common_t {
H5F_t *f; /* Pointer to file that fractal heap is in */
hid_t dxpl_id; /* DXPL for operation */
H5HF_t *fheap; /* Fractal heap handle */
+ H5HF_t *shared_fheap; /* Fractal heap handle for shared messages */
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 */
@@ -111,7 +112,7 @@ typedef struct H5A_bt2_ud_common_t {
typedef struct H5A_bt2_ud_ins_t {
/* downward */
H5A_bt2_ud_common_t common; /* Common info for B-tree user data (must be first) */
- uint8_t id[H5A_DENSE_FHEAP_ID_LEN]; /* Heap ID of attribute to insert */
+ const uint8_t *id; /* Heap ID of attribute to insert */
} H5A_bt2_ud_ins_t;
/* Data structure to hold table of attributes for an object */
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 7d5e496..17d6dcd 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -161,7 +161,9 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
unsigned UNUSED sequence, unsigned *oh_flags_ptr, void *_udata/*in,out*/)
{
H5O_iter_cvt_t *udata = (H5O_iter_cvt_t *)_udata; /* Operator user data */
- herr_t ret_value = H5_ITER_CONT; /* Return value */
+ H5A_t shared_attr; /* Copy of shared attribute */
+ H5A_t *attr; /* Pointer to attribute to insert */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_to_dense_cb)
@@ -169,11 +171,23 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
HDassert(oh);
HDassert(mesg);
+ /* Check for shared attribute */
+ if(mesg->flags & H5O_MSG_FLAG_SHARED) {
+ /* Read the shared attribute in */
+ if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, mesg->native, H5O_MSG_ATTR, &shared_attr))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute")
+
+ /* Point attribute to insert at shared attribute read in */
+ attr = &shared_attr;
+ } /* end if */
+ else
+ attr = mesg->native;
+
/* Insert attribute into dense storage */
- if(H5A_dense_insert(udata->f, udata->dxpl_id, oh, mesg->flags, mesg->native) < 0)
+ if(H5A_dense_insert(udata->f, udata->dxpl_id, oh, mesg->flags, attr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage")
- /* Convert message into a null message */
+ /* Convert message into a null message in the header */
if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, TRUE, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to convert into null message")
@@ -181,6 +195,10 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
*oh_flags_ptr |= H5AC__DIRTIED_FLAG;
done:
+ /* Release copy of shared attribute */
+ if(attr == &shared_attr)
+ H5O_attr_reset(&shared_attr);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_to_dense_cb() */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index e0c7292..a87c3ba 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -217,7 +217,7 @@ struct H5O_t {
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 */
- /* Message management (stored, indirectly) */
+ /* Message management (stored, in chunks) */
size_t nmesgs; /*number of messages */
size_t alloc_nmesgs; /*number of message slots */
H5O_mesg_t *mesg; /*array of messages */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 3c95953..5e84ff6 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -47,7 +47,7 @@ typedef struct H5O_t H5O_t;
/* JAMES: should these be in H5SM_private? or renamed? */
/* JAMES: causes errors encoding/decoding if this is wrong. Can't be constant. */
-#define H5SM_FHEAP_ID_LEN 6
+#define H5SM_FHEAP_ID_LEN 7
/* JAMES: not great? */
typedef uint64_t H5SM_fheap_id_t;
diff --git a/src/H5SM.c b/src/H5SM.c
index 2654483..0e7ba0e 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -40,7 +40,7 @@
#define H5SM_FHEAP_MAN_WIDTH 4
#define H5SM_FHEAP_MAN_START_BLOCK_SIZE 1024
#define H5SM_FHEAP_MAN_MAX_DIRECT_SIZE (64 * 1024)
-#define H5SM_FHEAP_MAN_MAX_INDEX 20
+#define H5SM_FHEAP_MAN_MAX_INDEX 32
#define H5SM_FHEAP_MAN_START_ROOT_ROWS 1
#define H5SM_FHEAP_CHECKSUM_DBLOCKS TRUE
#define H5SM_FHEAP_MAX_MAN_SIZE (4 * 1024)
@@ -62,6 +62,7 @@ static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id,
H5SM_index_header_t *header, unsigned type_id, const H5O_shared_t * mesg,
unsigned *cache_flags);
static hsize_t H5SM_find_in_list(H5F_t *f, H5SM_list_t *list, const H5SM_mesg_key_t *key);
+static herr_t H5SM_type_to_flag(unsigned type_id, unsigned *type_flag);
static ssize_t H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id);
@@ -217,13 +218,9 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5SM_get_index
- *
- * Purpose: Get the index number for a given message type.
+ * Function: H5SM_type_to_flag
*
- * Returns the number of the index in the supplied table
- * that holds messages of type type_id, or negative if
- * there is no index for this message type.
+ * Purpose: Get the shared message flag for a given message type.
*
* Return: Non-negative on success/Negative on failure
*
@@ -232,36 +229,67 @@ done:
*
*-------------------------------------------------------------------------
*/
-static ssize_t
-H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id)
+static herr_t
+H5SM_type_to_flag(unsigned type_id, unsigned *type_flag)
{
- ssize_t x;
- unsigned type_flag;
- ssize_t ret_value = FAIL;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5SM_get_index)
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_type_to_flag)
/* Translate the H5O type_id into an H5SM type flag */
- switch(type_id)
- {
+ switch(type_id) {
case H5O_SDSPACE_ID:
- type_flag = H5O_MESG_SDSPACE_FLAG;
+ *type_flag = H5O_MESG_SDSPACE_FLAG;
break;
case H5O_DTYPE_ID:
- type_flag = H5O_MESG_DTYPE_FLAG;
+ *type_flag = H5O_MESG_DTYPE_FLAG;
break;
case H5O_FILL_NEW_ID:
- type_flag = H5O_MESG_FILL_FLAG;
+ *type_flag = H5O_MESG_FILL_FLAG;
break;
case H5O_PLINE_ID:
- type_flag = H5O_MESG_PLINE_FLAG;
+ *type_flag = H5O_MESG_PLINE_FLAG;
break;
case H5O_ATTR_ID:
- type_flag = H5O_MESG_ATTR_FLAG;
+ *type_flag = H5O_MESG_ATTR_FLAG;
break;
default:
HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unknown message type ID")
- }
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_type_to_flag() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_get_index
+ *
+ * Purpose: Get the index number for a given message type.
+ *
+ * Returns the number of the index in the supplied table
+ * that holds messages of type type_id, or negative if
+ * there is no index for this message type.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Tuesday, October 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static ssize_t
+H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id)
+{
+ ssize_t x;
+ unsigned type_flag;
+ ssize_t ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_get_index)
+
+ /* Translate the H5O type_id into an H5SM type flag */
+ if(H5SM_type_to_flag(type_id, &type_flag) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't map message type to flag")
/* Search the indexes until we find one that matches this flag or we've
* searched them all.
@@ -284,6 +312,57 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5SM_type_shared
+ *
+ * Purpose: Check if a given message type is shared in a file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 12, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id)
+{
+ H5SM_master_table_t *table = NULL; /* Shared object master table */
+ unsigned type_flag; /* Flag corresponding to message type */
+ size_t u; /* Local index variable */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_type_shared)
+
+ /* Translate the H5O type_id into an H5SM type flag */
+ if(H5SM_type_to_flag(type_id, &type_flag) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't map message type to flag")
+
+ /* Look up the master SOHM table */
+ if(H5F_addr_defined(f->shared->sohm_addr)) {
+ if(NULL == (table = H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ } /* end if */
+ else
+ /* No shared messages of any type */
+ HGOTO_DONE(FALSE)
+
+ /* Search the indexes until we find one that matches this flag or we've
+ * searched them all.
+ */
+ for(u = 0; u < table->num_indexes; u++)
+ if(table->indexes[u].mesg_types & type_flag)
+ HGOTO_DONE(TRUE)
+
+done:
+ /* Release the master SOHM table */
+ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_type_shared() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5SM_get_fheap_addr
*
* Purpose: Gets the address of the fractal heap used to store
@@ -299,14 +378,14 @@ done:
haddr_t
H5SM_get_fheap_addr(H5F_t *f, unsigned type_id, hid_t dxpl_id)
{
- H5SM_master_table_t *table = NULL;
- ssize_t index_num; /* Which index */
+ H5SM_master_table_t *table = NULL; /* Shared object master table */
+ ssize_t index_num; /* Which index */
haddr_t ret_value;
FUNC_ENTER_NOAPI(H5SM_get_fheap_addr, FAIL)
/* Look up the master SOHM table */
- if(NULL == (table = H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (table = H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, HADDR_UNDEF, "unable to load SOHM master table")
/* JAMES! */
@@ -317,8 +396,8 @@ H5SM_get_fheap_addr(H5F_t *f, unsigned type_id, hid_t dxpl_id)
done:
/* Release the master SOHM table */
- if (table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, HADDR_UNDEF, "unable to close SOHM master table")
+ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, HADDR_UNDEF, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_get_fheap_addr() */
@@ -343,7 +422,9 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
haddr_t tree_addr=HADDR_UNDEF; /* Address of SOHM B-tree */
H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */
H5HF_t *fheap = NULL;
+#ifndef NDEBUG
size_t fheap_id_len; /* Size of a fractal heap ID */
+#endif /* NDEBUG */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5SM_create_index, FAIL)
@@ -393,8 +474,12 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
if(H5HF_get_heap_addr(fheap, &(header->heap_addr )) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address")
+#ifndef NDEBUG
+ /* Sanity check ID length */
if(H5HF_get_id_len(fheap, &fheap_id_len) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length")
+ HDassert(fheap_id_len == H5SM_FHEAP_ID_LEN);
+#endif /* NDEBUG */
done:
/* Close the fractal heap if one has been created */
@@ -773,7 +858,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header,
/* Change the original message passed in to reflect that it's now shared */
if(H5O_msg_set_share(type_id, &shared, mesg) < 0)
- HGOTO_ERROR (H5E_OHDR, H5E_BADMESG, FAIL, "unable to set sharing information")
+ HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to set sharing information")
done:
/* Release the fractal heap if we opened it */
@@ -1000,7 +1085,6 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, uns
/* Remember the btree address for this index; we'll overwrite the
* address in the index header
*/
- haddr_t btree_addr = header->index_addr;
H5SM_index_header_t temp_header;
/* The protect callback expects a header corresponding to the list
@@ -1100,8 +1184,8 @@ H5SM_get_info(H5F_t *f, unsigned *index_flags, unsigned *minsizes,
done:
/* Release the master SOHM table if we took it out of the cache */
- if (table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_get_info() */
diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h
index 1c90e80..2308167 100755
--- a/src/H5SMprivate.h
+++ b/src/H5SMprivate.h
@@ -48,6 +48,7 @@ H5_DLL htri_t H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id,
H5_DLL herr_t H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *mesg);
H5_DLL herr_t H5SM_get_info(H5F_t *f, unsigned *index_flags, unsigned *minsizes,
unsigned *list_to_btree, unsigned *btree_to_list, hid_t dxpl_id);
+H5_DLL htri_t H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id);
H5_DLL haddr_t H5SM_get_fheap_addr(H5F_t *f, unsigned type_id, hid_t dxpl_id);
#endif /*_H5SMprivate_H*/