From e9522de4e1ec02209673fb45378d1525cd723949 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 12 Dec 2006 15:28:48 -0500 Subject: [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) --- src/H5Abtree2.c | 20 ++++---- src/H5Adense.c | 124 ++++++++++++++++++++++++++++++++++----------- src/H5Apkg.h | 3 +- src/H5Oattribute.c | 24 +++++++-- src/H5Opkg.h | 2 +- src/H5Oprivate.h | 2 +- src/H5SM.c | 144 ++++++++++++++++++++++++++++++++++++++++++----------- src/H5SMprivate.h | 1 + 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*/ -- cgit v0.12