diff options
Diffstat (limited to 'src/H5SM.c')
-rwxr-xr-x | src/H5SM.c | 538 |
1 files changed, 271 insertions, 267 deletions
@@ -43,6 +43,7 @@ /******************/ /* Local Typedefs */ /******************/ + /* Udata struct for calls to H5SM_read_iter_op */ typedef struct H5SM_read_udata_t { H5F_t *file; /* File in which sharing is happening (in) */ @@ -70,7 +71,7 @@ static herr_t H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned *cache_flags_ptr); static herr_t H5SM_decr_ref(void *record, void *op_data, hbool_t *changed); static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, - H5SM_index_header_t *header, const H5O_shared_t * mesg, + H5SM_index_header_t *header, const H5O_shared_t * mesg, unsigned *cache_flags, void ** /*out*/ encoded_mesg); static herr_t H5SM_type_to_flag(unsigned type_id, unsigned *type_flag); static herr_t H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence, @@ -139,34 +140,34 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* File should not already have a SOHM table */ HDassert(f->shared->sohm_addr == HADDR_UNDEF); - /* Initialize master table */ - if(NULL == (table = H5FL_MALLOC(H5SM_master_table_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table") - /* Get information from fcpl */ if(H5P_get(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &num_indexes)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get number of indexes") if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, &index_type_flags)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM type flags") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM type flags") if(H5P_get(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &list_max)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM list maximum") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM list maximum") if(H5P_get(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &btree_min)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM btree minimum") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM btree minimum") if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, &minsizes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM message min sizes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM message min sizes") /* Verify that values are valid */ if(num_indexes > H5O_SHMESG_MAX_NINDEXES) - HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "number of indexes in property list is too large") + HGOTO_ERROR(H5E_SOHM, H5E_BADRANGE, FAIL, "number of indexes in property list is too large") /* Check that type flags weren't duplicated anywhere */ type_flags_used = 0; for(x = 0; x < num_indexes; ++x) { if(index_type_flags[x] & type_flags_used) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index") type_flags_used |= index_type_flags[x]; } /* end for */ + /* Initialize master table */ + if(NULL == (table = H5FL_MALLOC(H5SM_master_table_t))) + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table") + /* Set version and number of indexes in table and in superblock. * Right now we just use one byte to hold the number of indexes. */ @@ -183,7 +184,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* Allocate the SOHM indexes as an array. */ if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM indexes") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM indexes") /* Initialize all of the indexes, but don't allocate space for them to * hold messages until we actually need to write to them. @@ -206,13 +207,13 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d } /* end for */ /* Allocate space for the table on disk */ - table_size = (hsize_t) H5SM_TABLE_SIZE(f) + (hsize_t) (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); + table_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); if(HADDR_UNDEF == (table_addr = H5MF_alloc(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table") /* Cache the new table */ if(H5AC_set(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "can't add SOHM table to cache") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINS, FAIL, "can't add SOHM table to cache") /* Record the address of the master table in the file */ f->shared->sohm_addr = table_addr; @@ -235,7 +236,7 @@ done: if(table_addr != HADDR_UNDEF) H5MF_xfree(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_addr, (hsize_t)H5SM_TABLE_SIZE(f)); if(table != NULL) - H5FL_FREE(H5SM_master_table_t, table); + table = H5FL_FREE(H5SM_master_table_t, table); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -276,7 +277,7 @@ H5SM_type_to_flag(unsigned type_id, unsigned *type_flag) break; default: - HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unknown message type ID") + HGOTO_ERROR(H5E_SOHM, H5E_BADTYPE, FAIL, "unknown message type ID") } /* end switch */ done: @@ -311,7 +312,7 @@ H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id) /* 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") + HGOTO_ERROR(H5E_SOHM, 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. @@ -352,12 +353,12 @@ H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id) /* 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") + HGOTO_ERROR(H5E_SOHM, 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 = (H5SM_master_table_t *)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") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") } /* end if */ else /* No shared messages of any type */ @@ -373,7 +374,7 @@ H5SM_type_shared(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) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_type_shared() */ @@ -407,7 +408,7 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Look up index for message type */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -419,7 +420,7 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad 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_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_get_fheap_addr() */ @@ -440,36 +441,50 @@ done: static herr_t H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) { - haddr_t list_addr=HADDR_UNDEF; /* Address of SOHM list */ - haddr_t tree_addr=HADDR_UNDEF; /* Address of SOHM B-tree */ - H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ - H5HF_t *fheap = NULL; + H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5SM_create_index) + /* Sanity check */ HDassert(header); HDassert(header->index_addr == HADDR_UNDEF); HDassert(header->btree_min <= header->list_max + 1); /* In most cases, the index starts as a list */ if(header->list_max > 0) { - header->index_type = H5SM_LIST; + haddr_t list_addr = HADDR_UNDEF; /* Address of SOHM list */ + /* Create the list index */ if((list_addr = H5SM_create_list(f, header, dxpl_id)) == HADDR_UNDEF) HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "list creation failed for SOHM index") + /* Set the index type & address */ + header->index_type = H5SM_LIST; header->index_addr = list_addr; } /* end if */ /* index is a B-tree */ else { + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + haddr_t tree_addr = HADDR_UNDEF; /* Address of SOHM B-tree */ + + /* Create the v2 B-tree index */ + bt2_cparam.cls = H5SM_INDEX; + bt2_cparam.node_size = (size_t)H5SM_B2_NODE_SIZE; + bt2_cparam.rrec_size = (size_t)H5SM_SOHM_ENTRY_SIZE(f); + bt2_cparam.split_percent = H5SM_B2_SPLIT_PERCENT; + bt2_cparam.merge_percent = H5SM_B2_MERGE_PERCENT; + if(NULL == (bt2 = H5B2_create(f, dxpl_id, &bt2_cparam, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2, &tree_addr) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for SOHM index") + + /* Set the index type & address */ header->index_type = H5SM_BTREE; - - if(H5B2_create(f, dxpl_id, H5SM_INDEX, (size_t)H5SM_B2_NODE_SIZE, - (size_t)H5SM_SOHM_ENTRY_SIZE(f), H5SM_B2_SPLIT_PERCENT, - H5SM_B2_MERGE_PERCENT, &tree_addr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") - header->index_addr = tree_addr; } /* end else */ @@ -484,10 +499,10 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) fheap_cparam.id_len = 0; fheap_cparam.max_man_size = H5O_FHEAP_MAX_MAN_SIZE; if(NULL == (fheap = H5HF_create(f, dxpl_id, &fheap_cparam))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to create fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "unable to create fractal heap") if(H5HF_get_heap_addr(fheap, &(header->heap_addr)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address") #ifndef NDEBUG { @@ -495,15 +510,17 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) /* 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") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length") HDassert(fheap_id_len == H5O_FHEAP_ID_LEN); } #endif /* NDEBUG */ done: - /* Close the fractal heap if one has been created */ + /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_create_index */ @@ -529,30 +546,38 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, hbool_t delete_heap) +H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, + hbool_t delete_heap) { - hsize_t list_size; /* Size of list on disk */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5SM_delete_index) /* Determine whether index is a list or a B-tree. */ if(header->index_type == H5SM_LIST) { - /* Eject entry from cache */ - if(H5AC_expunge_entry(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache") - - /* Free the file space used */ - list_size = H5SM_LIST_SIZE(f, header->list_max); - if(H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, header->index_addr, list_size) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to free shared message list") + unsigned index_status = 0; /* Index list's status in the metadata cache */ + + /* Check the index list's status in the metadata cache */ + if(H5AC_get_entry_status(f, header->index_addr, &index_status) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to check metadata cache status for direct block") + + /* If the index list is in the cache, expunge it now */ + if(index_status & H5AC_ES__IN_CACHE) { + /* Sanity checks on index list */ + HDassert(!(index_status & H5AC_ES__IS_PINNED)); + HDassert(!(index_status & H5AC_ES__IS_PROTECTED)); + + /* Evict the index list from the metadata cache */ + if(H5AC_expunge_entry(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache") + } /* end if */ } /* end if */ else { HDassert(header->index_type == H5SM_BTREE); - /* Delete from the B-tree. */ - if(H5B2_delete(f, dxpl_id, H5SM_INDEX, header->index_addr, NULL, NULL) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree") + /* Delete the B-tree. */ + if(H5B2_delete(f, dxpl_id, header->index_addr, f, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree") /* Revert to list unless B-trees can have zero records */ if(header->btree_min > 0) @@ -609,9 +634,9 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) /* Allocate list in memory */ if((list = H5FL_MALLOC(H5SM_list_t)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") if((list->messages = (H5SM_sohm_t *)H5FL_ARR_MALLOC(H5SM_sohm_t, num_entries)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") /* Initialize messages in list */ HDmemset(list->messages, 0, sizeof(H5SM_sohm_t) * num_entries); @@ -624,11 +649,11 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) /* Allocate space for the list on disk */ size = H5SM_LIST_SIZE(f, num_entries); if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_SOHM_INDEX, dxpl_id, size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") /* Put the list into the cache */ if(H5AC_set(f, dxpl_id, H5AC_SOHM_LIST, addr, list, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache") /* Set return value */ ret_value = addr; @@ -638,7 +663,7 @@ done: if(list != NULL) { if(list->messages != NULL) H5FL_ARR_FREE(H5SM_sohm_t, list->messages); - H5FL_FREE(H5SM_list_t, list); + (void)H5FL_FREE(H5SM_list_t, list); } /* end if */ if(addr != HADDR_UNDEF) H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, addr, size); @@ -675,11 +700,13 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, { H5SM_list_t *list; /* Pointer to the existing message list */ H5SM_mesg_key_t key; /* Key for inserting records in v2 B-tree */ + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t tree_addr; /* New v2 B-tree's address */ size_t num_messages; /* Number of messages being tracked */ size_t x; void * encoding_buf = NULL; - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5SM_convert_list_to_btree) @@ -690,10 +717,17 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, list = *_list; /* Create the new v2 B-tree for tracking the messages */ - if(H5B2_create(f, dxpl_id, H5SM_INDEX, (size_t)H5SM_B2_NODE_SIZE, - (size_t)H5SM_SOHM_ENTRY_SIZE(f), H5SM_B2_SPLIT_PERCENT, - H5SM_B2_MERGE_PERCENT, &tree_addr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") + bt2_cparam.cls = H5SM_INDEX; + bt2_cparam.node_size = (size_t)H5SM_B2_NODE_SIZE; + bt2_cparam.rrec_size = (size_t)H5SM_SOHM_ENTRY_SIZE(f); + bt2_cparam.split_percent = H5SM_B2_SPLIT_PERCENT; + bt2_cparam.merge_percent = H5SM_B2_MERGE_PERCENT; + if(NULL == (bt2 = H5B2_create(f, dxpl_id, &bt2_cparam, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2, &tree_addr) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for SOHM index") /* Set up key values that all messages will use. Since these messages * are in the heap, they have a heap ID and no encoding or type_id. @@ -717,8 +751,8 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, key.encoding = encoding_buf; /* Insert the message into the B-tree */ - if(H5B2_insert(f, dxpl_id, H5SM_INDEX, tree_addr, &key) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") + if(H5B2_insert(bt2, dxpl_id, &key) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") /* Free buffer from H5SM_read_mesg */ if(encoding_buf) @@ -727,8 +761,8 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, } /* end for */ /* Unprotect list in cache and release heap */ - if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") + if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") *_list = list = NULL; /* Delete the old list index (but not its heap, which the new index is @@ -744,7 +778,9 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, header->num_messages = num_messages; done: - /* Free the buffer, if it hasn't already been freed (because of error) */ + /* Release resources */ + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") if(encoding_buf) encoding_buf = H5MM_xfree(encoding_buf); @@ -793,13 +829,13 @@ H5SM_convert_btree_to_list(H5F_t * f, H5SM_index_header_t * header, hid_t dxpl_i /* Delete the B-tree and have messages copy themselves to the * list as they're deleted */ - if(H5B2_delete(f, dxpl_id, H5SM_INDEX, btree_addr, H5SM_btree_convert_to_list_op, list) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree") + if(H5B2_delete(f, dxpl_id, btree_addr, f, H5SM_bt2_convert_to_list_op, list) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree") done: /* Release the SOHM list from the cache */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_convert_btree_to_list() */ @@ -904,7 +940,7 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table, /* If the message isn't big enough, don't bother sharing it */ if(0 == (mesg_size = H5O_msg_raw_size(f, type_id, TRUE, mesg))) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get OH message size") + HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, FAIL, "unable to get OH message size") if(mesg_size < my_table->indexes[index_num].min_mesg_size) HGOTO_DONE(FALSE) @@ -915,7 +951,7 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table, done: /* Release the master SOHM table, if we protected it */ if(my_table && my_table != table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, my_table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_can_share() */ @@ -997,7 +1033,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id, /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* "complex" sharing checks */ if((tri_ret = H5SM_can_share(f, dxpl_id, table, &index_num, type_id, mesg)) < 0) @@ -1034,7 +1070,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id, done: /* Release the master SOHM table */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_try_share() */ @@ -1078,7 +1114,7 @@ H5SM_incr_ref(void *record, void *_op_data, hbool_t *changed) /* Put the message in the heap and record its new heap ID */ if(H5HF_insert(op_data->key->fheap, op_data->dxpl_id, op_data->key->encoding_size, op_data->key->encoding, &message->u.heap_loc.fheap_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") message->location = H5SM_IN_HEAP; message->u.heap_loc.ref_count = 2; @@ -1134,6 +1170,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t shared; /* Shared H5O message */ hbool_t found = FALSE; /* Was the message in the index? */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ size_t buf_size; /* Size of the encoded message */ void * encoding_buf = NULL; /* Buffer for encoded message */ size_t empty_pos = UFAIL; /* Empty entry in list */ @@ -1148,15 +1185,15 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Encode the message to be written */ if((buf_size = H5O_msg_raw_size(f, type_id, TRUE, mesg)) == 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADSIZE, FAIL, "can't find message size") + HGOTO_ERROR(H5E_SOHM, H5E_BADSIZE, FAIL, "can't find message size") if(NULL == (encoding_buf = H5MM_malloc(buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate buffer for encoding") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't allocate buffer for encoding") if(H5O_msg_encode(f, type_id, TRUE, (unsigned char *)encoding_buf, mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "can't encode message to be shared") + HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, FAIL, "can't encode message to be shared") /* Open the fractal heap for this index */ if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up a key for the message to be written */ key.dxpl_id = dxpl_id; @@ -1176,7 +1213,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* The index is a list; get it from the cache */ if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, NULL, header, H5AC_WRITE))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") /* See if the message is already in the index and get its location. * Also record the first empty list position we find in case we need it @@ -1190,7 +1227,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, if(list->messages[list_pos].location == H5SM_IN_OH) { /* Put the message in the heap and record its new heap ID */ if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") list->messages[list_pos].location = H5SM_IN_HEAP; list->messages[list_pos].u.heap_loc.fheap_id = shared.u.heap_id; @@ -1213,6 +1250,11 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, HDassert(header->index_type == H5SM_BTREE); + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + + /* Set up callback info */ op_data.key = &key; op_data.dxpl_id = dxpl_id; @@ -1221,10 +1263,12 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, * return a heap ID, since a message with a reference count greater * than 1 is always shared in the heap. */ - if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_incr_ref, &op_data) >= 0) { + if(H5B2_modify(bt2, dxpl_id, &key, H5SM_incr_ref, &op_data) >= 0) { shared.u.heap_id = op_data.fheap_id; found = TRUE; } /* end if */ + else + H5E_clear_stack(NULL); /*ignore error*/ } /* end else */ if(found) @@ -1299,8 +1343,14 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, else { HDassert(header->index_type == H5SM_BTREE); - if(H5B2_insert(f, dxpl_id, H5SM_INDEX, header->index_addr, &key) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") + /* Open the index v2 B-tree, if it isn't already */ + if(NULL == bt2) { + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + } /* end if */ + + if(H5B2_insert(bt2, dxpl_id, &key) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") } /* end else */ ++(header->num_messages); @@ -1313,16 +1363,18 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Update the original message's shared component */ 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_SOHM, H5E_BADMESG, FAIL, "unable to set sharing information") done: - /* Release the fractal heap if we opened it */ + /* Release the fractal heap & v2 B-tree if we opened them */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") /* If we got a list out of the cache, release it (it is always dirty after writing a message) */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") if(encoding_buf) encoding_buf = H5MM_xfree(encoding_buf); @@ -1371,7 +1423,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index and try to delete from it */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -1386,7 +1438,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) /* Release the master SOHM table */ if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") table = NULL; /* If buf was allocated, delete the message it holds. This message may @@ -1394,17 +1446,17 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) * master table needs to be unprotected when we do this. */ if(mesg_buf) { - if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, type_id, (const unsigned char *)mesg_buf))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode shared message.") + if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, open_oh, type_id, (const unsigned char *)mesg_buf))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTDECODE, FAIL, "can't decode shared message.") if(H5O_msg_delete(f, dxpl_id, open_oh, type_id, native_mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't delete shared message.") + HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "can't delete shared message.") } /* end if */ done: /* Release the master SOHM table (should only happen on error) */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") /* Release any native message we decoded */ if(native_mesg) @@ -1580,10 +1632,9 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5SM_sohm_t message; /* Deleted message returned from index */ H5SM_sohm_t *message_ptr; /* Pointer to deleted message returned from index */ H5HF_t *fheap = NULL; /* Fractal heap that contains the message */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ size_t buf_size; /* Size of the encoded message (out) */ void *encoding_buf = NULL; /* The encoded message (out) */ - H5O_loc_t oloc; /* Object location for message in object header */ - H5O_t *oh = NULL; /* Object header for message in object header */ unsigned type_id; /* Message type to operate on */ herr_t ret_value = SUCCEED; @@ -1601,7 +1652,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Open the heap for this type of message. */ if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get the message size and encoded message for the message to be deleted, * either from its OH or from the heap. @@ -1620,7 +1671,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Get the encoded message */ if(H5SM_read_mesg(f, &key.message, fheap, open_oh, dxpl_id, &buf_size, &encoding_buf) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up key for message to be deleted. */ key.file = f; @@ -1652,9 +1703,14 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Index is a B-tree */ HDassert(header->index_type == H5SM_BTREE); + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + /* If this returns failure, it means that the message wasn't found. - * If it succeeds, a copy of the modified message will be returned. */ - if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_decr_ref, &message) <0) + * If it succeeds, a copy of the modified message will be returned. + */ + if(H5B2_modify(bt2, dxpl_id, &key, H5SM_decr_ref, &message) <0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") /* Point to the message */ @@ -1676,8 +1732,14 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, if(header->index_type == H5SM_LIST) message_ptr->location = H5SM_NO_LOC; else { - if(H5B2_remove(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, NULL, NULL) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTREMOVE, FAIL, "unable to delete message") + /* Open the index v2 B-tree, if it isn't already */ + if(NULL == bt2) { + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + } /* end if */ + + if(H5B2_remove(bt2, dxpl_id, &key, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "unable to delete message from index") } /* end else */ /* Remove the message from the heap if it was stored in the heap*/ @@ -1693,13 +1755,13 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, if(header->num_messages == 0) { /* Unprotect cache and release heap */ - if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") + if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") list = NULL; HDassert(fheap); if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") fheap = NULL; /* Delete the index and its heap */ @@ -1716,22 +1778,15 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, } /* end if */ done: - /* Unprotect & close the object header if we opened one */ - if(oh && oh != open_oh) { - if(H5AC_unprotect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") - - if(H5O_close(&oloc) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object header") - } /* end if */ - /* Release the SOHM list */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") - /* Release the fractal heap if we opened it */ + /* Release the fractal heap & v2 B-tree if we opened them */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") /* Free the message encoding, if we're not returning it in encoded_mesg * or if there's been an error. @@ -1762,6 +1817,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) H5F_file_t *shared = f->shared; /* Shared file info (convenience variable) */ H5O_shmesg_table_t sohm_table; /* SOHM message from superblock extension */ H5SM_master_table_t *table = NULL; /* SOHM master table */ + htri_t status; /* Status for message existing */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5SM_get_info, FAIL) @@ -1771,27 +1827,20 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) HDassert(f && shared); HDassert(fc_plist); - /* Read in shared message information, if it exists */ - if(NULL == H5O_msg_read(ext_loc, H5O_SHMESG_ID, &sohm_table, dxpl_id)) { - /* Reset error from "failed" message read */ - H5E_clear_stack(NULL); - - /* No SOHM info in file */ - shared->sohm_addr = HADDR_UNDEF; - shared->sohm_nindexes = 0; - shared->sohm_vers = 0; - - /* Shared object header messages are disabled */ - if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") - } /* end if */ - else { + /* Check for the extension having a 'shared message info' message */ + if((status = H5O_msg_exists(ext_loc, H5O_SHMESG_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to read object header") + if(status) { unsigned index_flags[H5O_SHMESG_MAX_NINDEXES]; /* Message flags for each index */ unsigned minsizes[H5O_SHMESG_MAX_NINDEXES]; /* Minimum message size for each index */ unsigned sohm_l2b; /* SOHM list-to-btree cutoff */ unsigned sohm_b2l; /* SOHM btree-to-list cutoff */ unsigned u; /* Local index variable */ + /* Retrieve the 'shared message info' structure */ + if(NULL == H5O_msg_read(ext_loc, H5O_SHMESG_ID, &sohm_table, dxpl_id)) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "shared message info message not present") + /* Portably initialize the arrays */ HDmemset(index_flags, 0, sizeof(index_flags)); HDmemset(minsizes, 0, sizeof(minsizes)); @@ -1805,7 +1854,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Read the rest of the SOHM table information from the cache */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Get index conversion limits */ sohm_l2b = table->indexes[0].list_max; @@ -1830,107 +1879,37 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Set values in the property list */ if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") if(H5P_set(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, index_flags) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set type flags for indexes") if(H5P_set(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, minsizes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set type flags for indexes") if(H5P_set(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &sohm_l2b) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") if(H5P_set(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &sohm_b2l) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") + } /* end if */ + else { + /* No SOHM info in file */ + shared->sohm_addr = HADDR_UNDEF; + shared->sohm_nindexes = 0; + shared->sohm_vers = 0; + + /* Shared object header messages are disabled */ + if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") } /* end else */ done: /* Release the master SOHM table if we took it out of the cache */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_get_info() */ /*------------------------------------------------------------------------- - * Function: H5SM_message_encode - * - * Purpose: Serialize a H5SM_sohm_t struct into a buffer RAW. - * - * Return: Non-negative on success - * Negative on failure - * - * Programmer: James Laird - * Monday, November 6, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5SM_message_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord) -{ - const H5SM_sohm_t *message = (const H5SM_sohm_t *)_nrecord; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_encode) - - *raw++ = message->location; - UINT32ENCODE(raw, message->hash); - - if(message->location == H5SM_IN_HEAP) { - UINT32ENCODE(raw, message->u.heap_loc.ref_count); - UINT64ENCODE(raw, message->u.heap_loc.fheap_id); - } /* end if */ - else { - HDassert(message->location == H5SM_IN_OH); - - *raw++ = 0; /* reserved (possible flags byte) */ - *raw++ = message->msg_type_id; - UINT16ENCODE(raw, message->u.mesg_loc.index); - H5F_addr_encode(f, &raw, message->u.mesg_loc.oh_addr); - } /* end else */ - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_message_encode */ - - -/*------------------------------------------------------------------------- - * Function: H5SM_message_decode - * - * Purpose: Read an encoded SOHM message from RAW into an H5SM_sohm_t struct. - * - * Return: Non-negative on success - * Negative on failure - * - * Programmer: James Laird - * Monday, November 6, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5SM_message_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord) -{ - H5SM_sohm_t *message = (H5SM_sohm_t *)_nrecord; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_decode) - - message->location = *raw++; - UINT32DECODE(raw, message->hash); - - if(message->location == H5SM_IN_HEAP) { - UINT32DECODE(raw, message->u.heap_loc.ref_count); - UINT64DECODE(raw, message->u.heap_loc.fheap_id); - } /* end if */ - else { - HDassert(message->location == H5SM_IN_OH); - - raw++; /* reserved */ - message->msg_type_id = *raw++; - UINT16DECODE(raw, message->u.mesg_loc.index); - H5F_addr_decode(f, &raw, &message->u.mesg_loc.oh_addr); - } /* end else */ - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_message_decode */ - - -/*------------------------------------------------------------------------- * Function: H5SM_reconstitute * * Purpose: Reconstitute a shared object header message structure from @@ -2010,8 +1989,9 @@ H5SM_get_refcount_bt2_cb(const void *_record, void *_op_data) herr_t H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *sh_mesg, hsize_t *ref_count) -{ +{ H5HF_t *fheap = NULL; /* Fractal heap that contains shared messages */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ H5SM_master_table_t *table = NULL; /* SOHM master table */ H5SM_list_t *list = NULL; /* SOHM index list for message type (if in list form) */ H5SM_index_header_t *header=NULL; /* Index header for message type */ @@ -2031,7 +2011,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index and find the message in it */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -2040,7 +2020,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Open the heap for this message type */ if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up a SOHM message to correspond to the shared message passed in */ key.message.location = H5SM_IN_HEAP; @@ -2049,7 +2029,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Get the encoded message */ if(H5SM_read_mesg(f, &key.message, fheap, NULL, dxpl_id, &buf_size, &encoding_buf) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up key for message to locate */ key.file = f; @@ -2075,11 +2055,19 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, message = list->messages[list_pos]; } /* end if */ else { + htri_t msg_exists; /* Whether the message exists in the v2 B-tree */ + /* Index is a B-tree */ HDassert(header->index_type == H5SM_BTREE); + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + /* Look up the message in the v2 B-tree */ - if(H5B2_find(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_get_refcount_bt2_cb, &message) < 0) + if((msg_exists = H5B2_find(bt2, dxpl_id, &key, H5SM_get_refcount_bt2_cb, &message)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "error finding message in index") + if(!msg_exists) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") } /* end else */ @@ -2090,11 +2078,13 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, done: /* Release resources */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") 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_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") if(encoding_buf) encoding_buf = H5MM_xfree(encoding_buf); @@ -2142,7 +2132,7 @@ H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence, /* Check if the message is dirty & flush it to the object header if so */ if(mesg->dirty) if(H5O_msg_flush(udata->file, oh, mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message") + HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message") /* Get the message's encoded size */ udata->buf_size = mesg->raw_size; @@ -2150,7 +2140,7 @@ H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence, /* Allocate buffer to return the message in */ if(NULL == (udata->encoding_buf = H5MM_malloc(udata->buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") /* Copy the encoded message into the buffer to return */ HDmemcpy(udata->encoding_buf, mesg->raw, udata->buf_size); @@ -2188,7 +2178,7 @@ H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata) /* Allocate a buffer to hold the message */ if(NULL == (udata->encoding_buf = H5MM_malloc(obj_len))) - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "memory allocation failed") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the message from the heap */ HDmemcpy(udata->encoding_buf, obj, obj_len); @@ -2247,18 +2237,18 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, /* Reset object location for operation */ if(H5O_loc_reset(&oloc) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize location") + HGOTO_ERROR(H5E_SOHM, H5E_CANTRESET, FAIL, "unable to initialize location") if(NULL == open_oh || mesg->u.mesg_loc.oh_addr != H5O_OH_GET_ADDR(open_oh)) { /* Open the object in the file */ oloc.file = f; oloc.addr = mesg->u.mesg_loc.oh_addr; if(H5O_open(&oloc) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to open object header") + HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "unable to open object header") /* Load the object header from the cache */ - if(NULL == (oh = H5AC_protect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header") + if(NULL == (oh = (H5O_t *)H5AC_protect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load object header") } /* end if */ else oh = open_oh; @@ -2267,14 +2257,14 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, op.op_type = H5O_MESG_OP_LIB; op.u.lib_op = H5SM_read_iter_op; if((ret_value = H5O_msg_iterate_real(f, oh, type, &op, &udata, dxpl_id)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages") + HGOTO_ERROR(H5E_SOHM, H5E_BADITER, FAIL, "unable to iterate over object header messages") } /* end if */ else { HDassert(mesg->location == H5SM_IN_HEAP); /* Copy the message from the heap */ if(H5HF_op(fheap, dxpl_id, &(mesg->u.heap_loc.fheap_id), H5SM_read_mesg_fh_cb, &udata) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "can't read message from fractal heap.") + HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "can't read message from fractal heap.") } /* end else */ HDassert(udata.encoding_buf); HDassert(udata.buf_size); @@ -2287,10 +2277,9 @@ done: /* Close the object header if we opened one and had an error */ if(oh && oh != open_oh) { if(H5AC_unprotect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") - + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release object header") if(H5O_close(&oloc) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object header") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "unable to close object header") } /* end if */ /* Release the encoding buffer on error */ @@ -2347,13 +2336,13 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr, /* Check arguments. Version must be 0, the only version implemented so far */ if(table_vers > HDF5_SHAREDHEADER_VERSION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown shared message table version") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "unknown shared message table version") if(num_indexes == 0 || num_indexes > H5O_SHMESG_MAX_NINDEXES) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") HDfprintf(stream, "%*sShared Message Master Table...\n", indent, ""); for(x = 0; x < num_indexes; ++x) { @@ -2381,7 +2370,7 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr, done: 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") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_table_debug() */ @@ -2422,9 +2411,9 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr, /* Check arguments. Version must be 0, the only version implemented so far */ if(table_vers > H5SM_LIST_VERSION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown shared message list version") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "unknown shared message list version") if(num_messages == 0 || num_messages > H5O_SHMESG_MAX_LIST_SIZE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") /* Create a temporary header using the arguments. The cache needs this to load the list. */ HDmemset(&header, 0, sizeof(H5SM_index_header_t)); @@ -2434,7 +2423,7 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr, /* Get the list from the cache */ if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, list_addr, NULL, &header, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") HDfprintf(stream, "%*sShared Message List Index...\n", indent, ""); for(x = 0; x < num_messages; ++x) { @@ -2466,7 +2455,7 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr, done: if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, list_addr, list, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_list_debug() */ @@ -2477,7 +2466,7 @@ done: * * Purpose: Loop through the master SOHM table (if there is one) to: * 1. collect storage used for header - * 1. collect storage used for B-tree and List + * 1. collect storage used for B-tree and List * (include btree storage used by huge objects in fractal heap) * 2. collect fractal heap storage * @@ -2489,10 +2478,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) +H5SM_ih_size(H5F_t *f, hid_t dxpl_id, hsize_t *hdr_size, H5_ih_info_t *ih_info) { H5SM_master_table_t *table = NULL; /* SOHM master table */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2501,40 +2491,52 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) /* Sanity check */ HDassert(f); HDassert(H5F_addr_defined(f->shared->sohm_addr)); - HDassert(finfo); + HDassert(hdr_size); + HDassert(ih_info); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Get SOHM header size */ - finfo->sohm.hdr_size = (hsize_t) H5SM_TABLE_SIZE(f) + - (hsize_t)(table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); + *hdr_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); /* Loop over all the indices for shared messages */ for(u = 0; u < table->num_indexes; u++) { /* Get index storage size (for either B-tree or list) */ if(table->indexes[u].index_type == H5SM_BTREE) { - if(H5F_addr_defined(table->indexes[u].index_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5SM_INDEX, table->indexes[u].index_addr, &(finfo->sohm.msgs_info.index_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + if(H5F_addr_defined(table->indexes[u].index_addr)) { + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, table->indexes[u].index_addr, f))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + + if(H5B2_size(bt2, dxpl_id, &(ih_info->index_size)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + + /* Close the v2 B-tree */ + if(H5B2_close(bt2, dxpl_id) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") + bt2 = NULL; + } /* end if */ } /* end if */ - else if(table->indexes[u].index_type == H5SM_LIST) - finfo->sohm.msgs_info.index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max); + else { + HDassert(table->indexes[u].index_type == H5SM_LIST); + ih_info->index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max); + } /* end else */ /* Check for heap for this index */ if(H5F_addr_defined(table->indexes[u].heap_addr)) { /* Open the fractal heap for this index */ if(NULL == (fheap = H5HF_open(f, dxpl_id, table->indexes[u].heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get heap storage size */ - if(H5HF_size(fheap, dxpl_id, &(finfo->sohm.msgs_info.heap_size)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") + if(H5HF_size(fheap, dxpl_id, &(ih_info->heap_size)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") - /* Release the fractal heap */ + /* Close the fractal heap */ if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") fheap = NULL; } /* end if */ } /* end for */ @@ -2542,9 +2544,11 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") 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_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_ih_size() */ |