diff options
Diffstat (limited to 'src/H5Gstab.c')
-rw-r--r-- | src/H5Gstab.c | 623 |
1 files changed, 476 insertions, 147 deletions
diff --git a/src/H5Gstab.c b/src/H5Gstab.c index b63e1cd..926ff7f 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -26,87 +26,170 @@ #include "H5Fpkg.h" /* File access */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ +#include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ +/* Private typedefs */ +/* User data for finding a name in the link messages */ +typedef struct { + /* downward */ + H5F_t *f; /* Pointer to file for insertion */ + const char *name; /* Name to search for */ + + /* upward */ + H5G_entry_t *ent; /* Entry to update when match found */ +} H5G_stab_ud1_t; + +/* User data for finding object info from B-tree */ +typedef struct { + /* downward */ + H5O_loc_t *grp_oloc; /* Object location of group */ + hid_t dxpl_id; /* DXPL during operation */ + haddr_t heap_addr; /* Local heap address for group */ + + /* upward */ + H5G_stat_t *statbuf; /* Caller's statbuf */ +} H5G_stab_fnd_ud1_t; + +/* User data for finding link information from B-tree */ +typedef struct { + /* downward */ + H5F_t *file; /* Pointer to file for query */ + hid_t dxpl_id; /* DXPL during operation */ + const char *name; /* Name to search for */ + haddr_t heap_addr; /* Local heap address for group */ + + /* upward */ + H5O_link_t *lnk; /* Caller's link location */ +} H5G_stab_fnd_ud2_t; + +/* User data for finding object location from B-tree */ +typedef struct { + /* downward */ + H5F_t *file; /* Pointer to file for query */ + size_t size; /* Buffer size for link value */ + haddr_t heap_addr; /* Local heap address for group */ + hid_t dxpl_id; /* DXPL during operation */ + + /* upward */ + char *buf; /* Buffer to fill with link value */ +} H5G_stab_fnd_ud3_t; + /* Private prototypes */ /*------------------------------------------------------------------------- - * Function: H5G_stab_create + * Function: H5G_stab_create_components * - * Purpose: Creates a new empty symbol table (object header, name heap, + * Purpose: Creates the components for a new, empty, symbol table (name heap * and B-tree). The caller can specify an initial size for the - * name heap. The object header of the group is opened for - * write access. + * name heap. * * In order for the B-tree to operate correctly, the first * item in the heap is the empty string, and must appear at * heap offset zero. * - * Errors: - * * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 1 1997 - * - * Modifications: + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Nov 7 2005 * *------------------------------------------------------------------------- */ herr_t -H5G_stab_create(H5F_t *f, hid_t dxpl_id, size_t init, H5G_entry_t *self/*out*/) +H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id) { - size_t name; /*offset of "" name */ - H5O_stab_t stab; /*symbol table message */ - herr_t ret_value=SUCCEED; /* Return value */ + size_t name_offset; /* Offset of "" name */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_stab_create, FAIL) + FUNC_ENTER_NOAPI(H5G_stab_create_components, FAIL) /* * Check arguments. */ HDassert(f); - HDassert(self); - init = MAX(init, H5HL_SIZEOF_FREE(f) + 2); + HDassert(stab); + HDassert(size_hint > 0); + + /* Create the B-tree */ + if(H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab->btree_addr)/*out*/) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree") /* Create symbol table private heap */ - if (H5HL_create(f, dxpl_id, init, &(stab.heap_addr)/*out*/)<0) + if(H5HL_create(f, dxpl_id, size_hint, &(stab->heap_addr)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap") - name = H5HL_insert(f, dxpl_id, stab.heap_addr, 1, ""); - if ((size_t)(-1)==name) + name_offset = H5HL_insert(f, dxpl_id, stab->heap_addr, 1, ""); + if((size_t)(-1) == name_offset) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap") /* * B-tree's won't work if the first name isn't at the beginning * of the heap. */ - assert(0 == name); + HDassert(0 == name_offset); - /* Create the B-tree */ - if (H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab.btree_addr)/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_create_components() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_stab_create + * + * Purpose: Creates a new empty symbol table (object header, name heap, + * and B-tree). The caller can specify an initial size for the + * name heap. The object header of the group is opened for + * write access. + * + * In order for the B-tree to operate correctly, the first + * item in the heap is the empty string, and must appear at + * heap offset zero. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 1 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_stab_create(H5O_loc_t *grp_oloc, H5O_stab_t *stab, hid_t dxpl_id) +{ + H5O_ginfo_t ginfo; /* Group info message */ + size_t heap_hint; /* Local heap size hint */ + size_t size_hint; /* Local heap size hint */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_stab_create, FAIL) /* - * Create symbol table object header. It has a zero link count - * since nothing refers to it yet. The link count will be - * incremented if the object is added to the group directed graph. + * Check arguments. */ - if (H5O_create(f, dxpl_id, 4 + 2 * H5F_SIZEOF_ADDR(f), self/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header") + HDassert(grp_oloc); + HDassert(stab); + + /* Get the group info */ + if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") + + /* Adjust the size hint, if necessary */ + if(ginfo.lheap_size_hint == 0) + heap_hint = ginfo.est_num_entries * (ginfo.est_name_len + 1); + else + heap_hint = ginfo.lheap_size_hint; + size_hint = MAX(heap_hint, H5HL_SIZEOF_FREE(grp_oloc->file) + 2); + + if(H5G_stab_create_components(grp_oloc->file, stab, size_hint, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create symbol table components") /* * Insert the symbol table message into the object header and the symbol * table entry. */ - if (H5O_modify(self, H5O_STAB_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, &stab, dxpl_id)<0) { - H5O_close(self); + if(H5O_modify(grp_oloc, H5O_STAB_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, stab, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") - } - self->cache.stab.btree_addr = stab.btree_addr; - self->cache.stab.heap_addr = stab.heap_addr; - self->type = H5G_CACHED_STAB; done: FUNC_LEAVE_NOAPI(ret_value) @@ -114,62 +197,47 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_stab_find - * - * Purpose: Finds a symbol named NAME in the symbol table whose - * description is stored in GRP_ENT in file F and returns its - * symbol table entry through OBJ_ENT (which is optional). + * Function: H5G_stab_insert_real * - * Errors: + * Purpose: Insert a new symbol into a table. + * The name of the new symbol is NAME and its symbol + * table entry is OBJ_LNK. * * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 1 1997 - * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002 - * Added `id to name' support. - * Added a deep copy of the symbol table entry + * Programmer: Quincey Koziol + * koziol@uiuc.edu + * Nov 7 2005 * *------------------------------------------------------------------------- */ herr_t -H5G_stab_find(H5G_entry_t *grp_ent, const char *name, - H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id) +H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, + H5O_link_t *obj_lnk, hid_t dxpl_id) { - H5G_bt_ud1_t udata; /*data to pass through B-tree */ - H5O_stab_t stab; /*symbol table message */ - herr_t ret_value=SUCCEED; /* Return value */ + H5G_bt_ud1_t udata; /* Data to pass through B-tree */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_stab_find, FAIL) + FUNC_ENTER_NOAPI(H5G_stab_insert_real, FAIL) - /* Check arguments */ - assert(grp_ent); - assert(grp_ent->file); - assert(obj_ent); - assert(name && *name); + /* check arguments */ + HDassert(f); + HDassert(stab); + HDassert(name && *name); + HDassert(obj_lnk); - /* set up the udata */ - if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message") + /* Initialize data to pass through B-tree */ udata.common.name = name; - udata.common.heap_addr = stab.heap_addr; - udata.ent = obj_ent; - - /* search the B-tree */ - if (H5B_find(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found") + udata.common.heap_addr = stab->heap_addr; + udata.lnk = obj_lnk; - /* Set the name for the symbol entry OBJ_ENT */ - if (H5G_ent_set_name( grp_ent, obj_ent, name ) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name") + /* Insert into symbol table */ + if(H5B_insert(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_stab_find() */ +} /* end H5G_stab_insert_real() */ /*------------------------------------------------------------------------- @@ -188,46 +256,29 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent, - hbool_t inc_link, hid_t dxpl_id) +H5G_stab_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, + hid_t dxpl_id) { - H5O_stab_t stab; /*symbol table message */ - H5G_bt_ud1_t udata; /*data to pass through B-tree */ - herr_t ret_value=SUCCEED; /* Return value */ + H5O_stab_t stab; /* Symbol table message */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_stab_insert, FAIL) /* check arguments */ - assert(grp_ent && grp_ent->file); - assert(name && *name); - assert(obj_ent && obj_ent->file); - if (grp_ent->file->shared != obj_ent->file->shared) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed") - - /* Set the name for the symbol entry OBJ_ENT */ - if (H5G_ent_set_name( grp_ent, obj_ent, name ) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name") + HDassert(grp_oloc && grp_oloc->file); + HDassert(name && *name); + HDassert(obj_lnk); - /* initialize data to pass through B-tree */ - if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + /* Retrieve symbol table message */ + if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") - udata.common.name = name; - udata.common.heap_addr = stab.heap_addr; - udata.ent = obj_ent; - - /* insert */ - if (H5B_insert(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") - - /* Increment link count on object, if appropriate */ - if(inc_link) - if (H5O_link(obj_ent, 1, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count") + if(H5G_stab_insert_real(grp_oloc->file, &stab, name, obj_lnk, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5B_ITER_ERROR, "unable to insert the name") done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_insert() */ /*------------------------------------------------------------------------- @@ -240,36 +291,37 @@ done: * Programmer: Robb Matzke * Thursday, September 17, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t -H5G_stab_remove(H5G_entry_t *grp_ent, const char *name, hid_t dxpl_id) +H5G_stab_remove(H5O_loc_t *loc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id) { H5O_stab_t stab; /*symbol table message */ H5G_bt_ud2_t udata; /*data to pass through B-tree */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_stab_remove, FAIL) - assert(grp_ent && grp_ent->file); - assert(name && *name); + HDassert(loc && loc->file); + HDassert(name && *name); - /* initialize data to pass through B-tree */ - if (NULL==H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + /* Read in symbol table message */ + if(NULL == H5O_read(loc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + + /* Initialize data to pass through B-tree */ udata.common.name = name; udata.common.heap_addr = stab.heap_addr; udata.adj_link = TRUE; + udata.obj_type = obj_type; - /* remove */ - if (H5B_remove(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry") + /* Remove from symbol table */ + if(H5B_remove(loc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry") done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5G_stab_remove() */ /*------------------------------------------------------------------------- @@ -318,47 +370,324 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_stab_copy_tmp + * Function: H5G_stab_iterate + * + * Purpose: Iterate over the objects in a group * - * Purpose: copy a group symbol table and memeber objects from SRC file to DST file. + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, October 3, 2005 * - * Return: Non-negative on success - * Negative on failure. + *------------------------------------------------------------------------- + */ +herr_t +H5G_stab_iterate(H5O_loc_t *oloc, hid_t gid, int skip, int *last_obj, + H5G_iterate_t op, void *op_data, hid_t dxpl_id) +{ + H5G_bt_it_ud1_t udata; /* User data to pass to B-tree callback */ + H5O_stab_t stab; /* Info about symbol table */ + herr_t ret_value; + + FUNC_ENTER_NOAPI(H5G_stab_iterate, FAIL) + + /* Sanity check */ + HDassert(oloc); + HDassert(H5I_GROUP == H5I_get_type(gid)); + HDassert(last_obj); + HDassert(op); + + /* Get the B-tree info */ + if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + + /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ + udata.group_id = gid; + udata.skip = skip; + udata.heap_addr = stab.heap_addr; + udata.op = op; + udata.op_data = op_data; + udata.final_ent = last_obj; + + /* Iterate over the group members */ + if((ret_value = H5B_iterate(oloc->file, H5AC_dxpl_id, H5B_SNODE, + H5G_node_iterate, stab.btree_addr, &udata))<0) + HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_iterate() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_stab_count * - * Programmer: Peter Cao - * September 10, 2005 + * Purpose: Count the # of objects in a group * - * Note: This routine should be replaced with proper call to "real" - * stab creation routine after the "big group revision" checkin - * occurs. -QAK + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, September 6, 2005 * *------------------------------------------------------------------------- */ herr_t -H5G_stab_copy_tmp(H5F_t *f_dst, H5O_stab_t *stab_dst, hid_t dxpl_id) +H5G_stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id) +{ + H5O_stab_t stab; /* Info about symbol table */ + herr_t ret_value; + + FUNC_ENTER_NOAPI(H5G_stab_count, FAIL) + + /* Sanity check */ + HDassert(oloc); + HDassert(num_objs); + + /* Reset the number of objects in the group */ + *num_objs = 0; + + /* Get the B-tree info */ + if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + + /* Iterate over the group members */ + if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, num_objs)) < 0) + HERROR(H5E_SYM, H5E_CANTINIT, "iteration operator failed"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_count() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_stab_get_name_by_idx + * + * Purpose: Returns the name of objects in the group by giving index. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Raymond Lu + * Nov 20, 2002 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, + size_t size, hid_t dxpl_id) +{ + H5O_stab_t stab; /* Info about local heap & B-tree */ + H5G_bt_it_ud2_t udata; /* Iteration information */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_stab_get_name_by_idx, FAIL) + + /* Sanity check */ + HDassert(oloc); + + /* Get the B-tree & local heap info */ + if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + + /* Set iteration information */ + udata.idx = idx; + udata.num_objs = 0; + udata.heap_addr = stab.heap_addr; + udata.name = NULL; + + /* Iterate over the group members */ + if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_name, stab.btree_addr, &udata))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed") + + /* If we don't know the name now, we almost certainly went out of bounds */ + if(udata.name==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") + + /* Get the length of the name */ + ret_value = (ssize_t)HDstrlen(udata.name); + + /* Copy the name into the user's buffer, if given */ + if(name) { + HDstrncpy(name, udata.name, MIN((size_t)(ret_value+1),size)); + if((size_t)ret_value >= size) + name[size-1]='\0'; + } /* end if */ + +done: + /* Free the duplicated name */ + if(udata.name!=NULL) + H5MM_xfree(udata.name); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_get_name_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_get_objtype_by_idx + * + * Purpose: Private function for H5Gget_objtype_by_idx. + * Returns the type of objects in the group by giving index. + * + * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3) + * + * Failure: UNKNOWN + * + * Programmer: Raymond Lu + * Nov 20, 2002 + * + *------------------------------------------------------------------------- + */ +H5G_obj_t +H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) +{ + H5O_stab_t stab; /* Info about local heap & B-tree */ + H5G_bt_it_ud3_t udata; /* User data for B-tree callback */ + H5G_obj_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_stab_get_type_by_idx, H5G_UNKNOWN) + + /* Sanity check */ + HDassert(oloc); + + /* Get the B-tree & local heap info */ + if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to determine local heap address") + + /* Set iteration information */ + udata.idx = idx; + udata.num_objs = 0; + udata.type = H5G_UNKNOWN; + + /* Iterate over the group members */ + if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_type, stab.btree_addr, &udata) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed") + + /* If we don't know the type now, we almost certainly went out of bounds */ + if(udata.type == H5G_UNKNOWN) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound") + + /* Set the return value */ + ret_value = udata.type; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_get_type_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_stab_lookup_cb + * + * Purpose: B-tree 'find' callback to retrieve location for an object + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Sep 20, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) { - size_t size_init, name_offset; - herr_t ret_value = SUCCEED; /* Return value */ + H5G_stab_fnd_ud2_t *udata = (H5G_stab_fnd_ud2_t *)_udata; /* 'User data' passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_stab_lookup_cb) + + /* Set link info */ + if(udata->lnk) { + /* Set (default) common info for link */ + udata->lnk->cset = H5T_CSET_ASCII; + udata->lnk->ctime = 0; + udata->lnk->name = H5MM_xstrdup(udata->name); + + /* Object is a symbolic link */ + if(H5G_CACHED_SLINK == ent->type) { + const char *s; /* Pointer to link value */ + const H5HL_t *heap; /* Pointer to local heap for group */ + + /* Lock the local heap */ + if(NULL == (heap = H5HL_protect(udata->file, udata->dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") - FUNC_ENTER_NOAPI(H5G_stab_copy_tmp, FAIL) + s = H5HL_offset_into(udata->file, heap, ent->cache.slink.lval_offset); - HDassert(f_dst); - HDassert(stab_dst); + /* Copy the link value */ + udata->lnk->u.soft.name = H5MM_xstrdup(s); - /* create B-tree private heap */ - size_init = MAX(H5G_SIZE_HINT, H5HL_SIZEOF_FREE(f_dst) + 2); - if (H5HL_create(f_dst, dxpl_id, size_init, &(stab_dst->heap_addr))<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap") + /* Release the local heap */ + if(H5HL_unprotect(udata->file, udata->dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") - name_offset = H5HL_insert(f_dst, dxpl_id, stab_dst->heap_addr, 1, ""); - if ((size_t)(-1)==name_offset) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap") - assert(0 == name_offset); - - /* create the B-tree */ - if (H5B_create(f_dst, dxpl_id, H5B_SNODE, NULL, &(stab_dst->btree_addr)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree") + /* Set link type */ + udata->lnk->type = H5G_LINK_SOFT; + } /* end if */ + else { + /* Set address of object */ + udata->lnk->u.hard.addr = ent->header; + + /* Set link type */ + udata->lnk->type = H5G_LINK_HARD; + } /* end else */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_lookup_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_stab_lookup + * + * Purpose: Look up an object relative to a group, using symbol table + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 20 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, + hid_t dxpl_id) +{ + H5G_bt_ud3_t bt_udata; /* Data to pass through B-tree */ + H5G_stab_fnd_ud2_t udata; /* 'User data' to give to callback */ + H5O_stab_t stab; /* Symbol table message */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_stab_lookup, FAIL) + + /* check arguments */ + HDassert(grp_oloc && grp_oloc->file); + HDassert(name && *name); + HDassert(lnk); + + /* Set up user data to pass to 'find' operation callback */ + udata.file = grp_oloc->file; + udata.dxpl_id = dxpl_id; + udata.name = name; + udata.lnk = lnk; + + /* Set up the user data for actual B-tree find operation */ + if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message") + bt_udata.common.name = name; + bt_udata.common.heap_addr = stab.heap_addr; + bt_udata.op = H5G_stab_lookup_cb; + bt_udata.op_data = &udata; + + /* Finish up user data to pass to 'find' operation callback */ + udata.heap_addr = stab.heap_addr; + + /* Search the B-tree */ + if(H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_stab_copy_tmp() */ +} /* end H5G_stab_lookup() */ + |