diff options
-rw-r--r-- | release_docs/RELEASE.txt | 3 | ||||
-rw-r--r-- | src/H5A.c | 18 | ||||
-rw-r--r-- | src/H5HG.c | 2 | ||||
-rw-r--r-- | src/H5HGprivate.h | 2 | ||||
-rw-r--r-- | src/H5O.c | 500 | ||||
-rw-r--r-- | src/H5Oattr.c | 296 | ||||
-rw-r--r-- | src/H5Obogus.c | 1 | ||||
-rw-r--r-- | src/H5Ocont.c | 1 | ||||
-rw-r--r-- | src/H5Odtype.c | 1 | ||||
-rw-r--r-- | src/H5Oefl.c | 1 | ||||
-rw-r--r-- | src/H5Ofill.c | 2 | ||||
-rw-r--r-- | src/H5Olayout.c | 1 | ||||
-rw-r--r-- | src/H5Omtime.c | 2 | ||||
-rw-r--r-- | src/H5Oname.c | 1 | ||||
-rw-r--r-- | src/H5Onull.c | 1 | ||||
-rw-r--r-- | src/H5Opkg.h | 8 | ||||
-rw-r--r-- | src/H5Opline.c | 1 | ||||
-rw-r--r-- | src/H5Oprivate.h | 3 | ||||
-rw-r--r-- | src/H5Osdspace.c | 1 | ||||
-rw-r--r-- | src/H5Oshared.c | 302 | ||||
-rw-r--r-- | src/H5Ostab.c | 1 | ||||
-rw-r--r-- | src/H5Tcommit.c | 66 | ||||
-rw-r--r-- | src/H5Tprivate.h | 2 |
23 files changed, 922 insertions, 294 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 30dfc9b..67f5957 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -76,6 +76,9 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - Correctly create reference to shared datatype in attribute, instead + of making a copy of the shared datatype in the attribute. + QAK - 2003/10/01 - Revert changes which caused files >2GB to fail when created with MPI-I/O file driver on certain platforms. QAK - 2003/09/16 - Allow compound datatypes to grow in size. SLU - 2003/09/10 @@ -250,8 +250,22 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, if (H5G_ent_copy(&(attr->ent),ent,H5G_COPY_DEEP)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") - /* Compute the internal sizes */ - attr->dt_size=H5O_raw_size(H5O_DTYPE_ID,attr->ent.file,type); + /* Compute the size of pieces on disk */ + if(H5T_committed(attr->dt)) { + H5O_shared_t sh_mesg; + + /* Reset shared message information */ + HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); + + /* Get shared message information for datatype */ + if (H5O_get_share(H5O_DTYPE_ID,attr->ent.file, type, &sh_mesg/*out*/)<0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") + + /* Compute shared message size for datatype */ + attr->dt_size=H5O_raw_size(H5O_SHARED_ID,attr->ent.file,&sh_mesg); + } /* end if */ + else + attr->dt_size=H5O_raw_size(H5O_DTYPE_ID,attr->ent.file,type); assert(attr->dt_size>0); attr->ds_size=H5O_raw_size(H5O_SDSPACE_ID,attr->ent.file,&(space->extent.u.simple)); assert(attr->ds_size>0); @@ -891,7 +891,7 @@ done: *------------------------------------------------------------------------- */ int -H5HG_link (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, int adjust) +H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust) { H5HG_heap_t *heap = NULL; int ret_value; /* Return value */ diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index 8e589e1..56589f9 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -43,7 +43,7 @@ typedef struct H5HG_heap_t H5HG_heap_t; H5_DLL herr_t H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/); H5_DLL void *H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object); -H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, int adjust); +H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust); H5_DLL herr_t H5HG_remove(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj); /* Debugging functions */ @@ -49,15 +49,12 @@ static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header); static herr_t H5O_reset_real(const H5O_class_t *type, void *native); -static void * H5O_free_real(const H5O_class_t *type, void *mesg); static void * H5O_copy_real(const H5O_class_t *type, const void *mesg, void *dst); static int H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type, hid_t dxpl_id); static htri_t H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t dxpl_id); -static void * H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, - int sequence, void *mesg, hid_t dxpl_id); #ifdef NOT_YET static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg, H5HG_t *hobj/*out*/); @@ -76,6 +73,12 @@ static unsigned H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, static unsigned H5O_alloc_extend_chunk(H5O_t *oh, unsigned chunkno, size_t size); static unsigned H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size); static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh); +static herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg); +static unsigned H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, + const H5O_class_t *orig_type, const void *orig_mesg, H5O_shared_t *sh_mesg, + const H5O_class_t **new_type, const void **new_mesg, hid_t dxpl_id); +static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type, + const void *mesg, unsigned flags); /* Metadata cache callbacks */ static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1, @@ -119,7 +122,7 @@ static const H5O_class_t *const message_type_g[] = { H5O_ATTR, /*0x000C Attribute list */ H5O_NAME, /*0x000D Object name */ H5O_MTIME, /*0x000E Object modification date and time */ - NULL, /*0x000F Shared header message */ + H5O_SHARED, /*0x000F Shared header message */ H5O_CONT, /*0x0010 Object header continuation */ H5O_STAB, /*0x0011 Symbol table */ H5O_MTIME_NEW, /*0x0012 New Object modification date and time */ @@ -582,7 +585,8 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* decode next object header continuation message */ for (chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) { if (H5O_CONT_ID == oh->mesg[curmesg].type->id) { - H5O_cont_t *cont = NULL; + H5O_cont_t *cont; + cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw, NULL); oh->mesg[curmesg].native = cont; chunk_addr = cont->addr; @@ -1003,8 +1007,7 @@ H5O_free (hid_t type_id, void *mesg) assert(type); /* Call the "real" free routine */ - if((ret_value=H5O_free_real(type, mesg))==NULL) - HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to free object header"); + ret_value=H5O_free_real(type, mesg); done: FUNC_LEAVE_NOAPI(ret_value); @@ -1028,7 +1031,7 @@ done: * *------------------------------------------------------------------------- */ -static void * +void * H5O_free_real(const H5O_class_t *type, void *mesg) { void * ret_value=NULL; /* Return value */ @@ -1156,7 +1159,7 @@ done: *------------------------------------------------------------------------- */ int -H5O_link(H5G_entry_t *ent, int adjust, hid_t dxpl_id) +H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id) { H5O_t *oh = NULL; hbool_t deleted=FALSE; /* Whether the object was deleted as a result of this action */ @@ -1505,7 +1508,7 @@ done: * actually destroys the object in the cache. *------------------------------------------------------------------------- */ -static void * +void * H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id) { H5O_t *oh = NULL; @@ -1548,28 +1551,9 @@ H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mes * message in the global heap or some other object header. */ H5O_shared_t *shared; - void *tmp_buf, *tmp_mesg; shared = (H5O_shared_t *)(oh->mesg[idx].native); - if (shared->in_gh) { - if (NULL==(tmp_buf = H5HG_read (ent->file, dxpl_id, &(shared->u.gh), NULL))) - HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to read shared message from global heap"); - tmp_mesg = (type->decode)(ent->file, dxpl_id, tmp_buf, shared); - tmp_buf = H5MM_xfree (tmp_buf); - if (!tmp_mesg) - HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to decode object header shared message"); - if (mesg) { - HDmemcpy (mesg, tmp_mesg, type->native_size); - H5MM_xfree (tmp_mesg); - } else { - ret_value = tmp_mesg; - } - } else { - ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id); - if (type->set_share && - (type->set_share)(ent->file, ret_value, shared)<0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information"); - } + ret_value=H5O_shared_read(ent->file,dxpl_id,shared,type,mesg); } else { /* * The message is not shared, but rather exists in the object @@ -1590,7 +1574,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_find_in_ohdr + * Function: H5O_find_in_ohdr * * Purpose: Find a message in the object header without consulting * a symbol table entry. @@ -1622,6 +1606,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p, /* Check args */ assert(f); + assert(oh); assert(type_p); /* Scan through the messages looking for the right one */ @@ -1789,7 +1774,6 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite, int sequence; unsigned idx; /* Index of message to modify */ H5O_mesg_t *idx_msg; /* Pointer to message to modify */ - size_t size=0; H5O_shared_t sh_mesg; int ret_value; @@ -1815,64 +1799,24 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite, continue; if (++sequence == overwrite) break; - } + } /* end for */ /* Was the right message found? */ - if (overwrite >= 0 && - (idx >= oh->nmesgs || sequence != overwrite)) { - + if (overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) { /* But can we insert a new one with this sequence number? */ - if (overwrite == sequence + 1) { + if (overwrite == sequence + 1) overwrite = -1; - } else { + else HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found"); - } - } + } /* end if */ + + /* Check for creating new message */ if (overwrite < 0) { - /* Allocate space for the new message */ - if (flags & H5O_FLAG_SHARED) { - HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); - - if (NULL==type->get_share) - HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable"); - if ((type->get_share)(ent->file, mesg, &sh_mesg/*out*/)<0) { - /* - * If the message isn't shared then turn off the shared bit - * and treat it as an unshared message. - */ - H5E_clear (NULL); - flags &= ~H5O_FLAG_SHARED; - } else if (sh_mesg.in_gh) { - /* - * The shared message is stored in the global heap. - * Increment the reference count on the global heap message. - */ - if (H5HG_link (ent->file, dxpl_id, &(sh_mesg.u.gh), 1)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); - size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg); - } else { - /* - * The shared message is stored in some other object header. - * The other object header must be in the same file as the - * new object header. Increment the reference count on that - * object header. - */ - if (sh_mesg.u.ent.file->shared != ent->file->shared) - HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed"); - if (H5O_link (&(sh_mesg.u.ent), 1, dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); - size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg); - } - } - /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */ - if (0== (flags & H5O_FLAG_SHARED)) { - size = (type->raw_size) (ent->file, mesg); - if (size>=H5O_MAX_SIZE) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)"); - } - idx = H5O_alloc(ent->file, oh, type, size); - if (idx == UFAIL) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message"); + /* Create a new message */ + if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id))==UFAIL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message"); + + /* Set the correct sequence number for the message created */ sequence++; } else if (oh->mesg[idx].flags & H5O_FLAG_CONSTANT) { @@ -1881,30 +1825,14 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite, HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message"); } - /* Set pointer to the correct message */ - idx_msg=&oh->mesg[idx]; - - /* Copy the native value into the object header */ - if (flags & H5O_FLAG_SHARED) { - if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t)); - } else { - if (idx_msg->native) - H5O_reset_real(idx_msg->type, idx_msg->native); - idx_msg->native = (type->copy) (mesg, idx_msg->native); - if (NULL == idx_msg->native) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header"); - } + /* Write the information to the message */ + if(H5O_write_mesg(oh,idx,type,mesg,flags)<0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message"); /* Update the modification time message if any */ if(update_time) H5O_touch_oh(ent->file, oh, FALSE); - idx_msg->flags = flags; - idx_msg->dirty = TRUE; - oh->cache_info.dirty = TRUE; - /* Set return value */ ret_value = sequence; @@ -2007,13 +1935,6 @@ done: * Purpose: Simplified version of H5O_modify, used when creating a new * object header message (usually during object creation) * - * Modifies an existing message or creates a new message. - * The cache fields in that symbol table entry ENT are *not* - * updated, you must do that separately because they often - * depend on multiple object header messages. Besides, we - * don't know which messages will be constant and which will - * not. - * * Return: Success: The sequence number of the message that * was created. * @@ -2064,13 +1985,6 @@ done: * Purpose: Simplified version of H5O_modify, used when creating a new * object header message (usually during object creation) * - * Modifies an existing message or creates a new message. - * The cache fields in that symbol table entry ENT are *not* - * updated, you must do that separately because they often - * depend on multiple object header messages. Besides, we - * don't know which messages will be constant and which will - * not. - * * Return: Success: The sequence number of the message that * was created. * @@ -2089,8 +2003,6 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type, unsigned flags, const void *mesg) { unsigned idx; /* Index of message to modify */ - H5O_mesg_t *idx_msg; /* Pointer to message to modify */ - size_t size=0; H5O_shared_t sh_mesg; int ret_value = FAIL; @@ -2103,76 +2015,143 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type, assert(0==(flags & ~H5O_FLAG_BITS)); assert(mesg); - /* Allocate space for the new message */ - if (flags & H5O_FLAG_SHARED) { - HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); + /* Create a new message */ + if((idx=H5O_new_mesg(f,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id))==UFAIL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message"); + + /* Write the information to the message */ + if(H5O_write_mesg(oh,idx,type,mesg,flags)<0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message"); + + /* Set return value */ + ret_value = idx; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_append_real () */ + + +/*------------------------------------------------------------------------- + * Function: H5O_new_mesg + * + * Purpose: Create a new message in an object header + * + * Return: Success: Index of message + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, September 3, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static unsigned +H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type, + const void *orig_mesg, H5O_shared_t *sh_mesg, const H5O_class_t **new_type, + const void **new_mesg, hid_t dxpl_id) +{ + size_t size; /* Size of space allocated for object header */ + unsigned ret_value=UFAIL; /* Return value */ + + FUNC_ENTER_NOINIT(H5O_new_mesg); - if (NULL==type->get_share) - HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable"); - if ((type->get_share)(f, mesg, &sh_mesg/*out*/)<0) { + /* check args */ + assert(f); + assert(oh); + assert(flags); + assert(orig_type); + assert(orig_mesg); + assert(sh_mesg); + assert(new_mesg); + assert(new_type); + + /* Check for shared message */ + if (*flags & H5O_FLAG_SHARED) { + HDmemset(sh_mesg,0,sizeof(H5O_shared_t)); + + if (NULL==orig_type->get_share) + HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable"); + if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/)<0) { /* * If the message isn't shared then turn off the shared bit * and treat it as an unshared message. */ H5E_clear (NULL); - flags &= ~H5O_FLAG_SHARED; - } else if (sh_mesg.in_gh) { - /* - * The shared message is stored in the global heap. - * Increment the reference count on the global heap message. - */ - if (H5HG_link (f, dxpl_id, &(sh_mesg.u.gh), 1)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); - size = (H5O_SHARED->raw_size)(f, &sh_mesg); + *flags &= ~H5O_FLAG_SHARED; } else { - /* - * The shared message is stored in some other object header. - * The other object header must be in the same file as the - * new object header. Increment the reference count on that - * object header. - */ - if (sh_mesg.u.ent.file->shared != f->shared) - HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed"); - if (H5O_link (&(sh_mesg.u.ent), 1, dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); - size = (H5O_SHARED->raw_size)(f, &sh_mesg); - } - } - /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */ - if (0== (flags & H5O_FLAG_SHARED)) { - size = (type->raw_size) (f, mesg); - if (size>=H5O_MAX_SIZE) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)"); - } - if ((idx = H5O_alloc(f, oh, type, size)) == UFAIL) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message"); - + /* Change type & message to use shared information */ + *new_type=H5O_SHARED; + *new_mesg=sh_mesg; + } /* end else */ + } /* end if */ + else { + *new_type=orig_type; + *new_mesg=orig_mesg; + } /* end else */ + + /* Compute the size needed to store the message on disk */ + if ((size = ((*new_type)->raw_size) (f, *new_mesg)) >=H5O_MAX_SIZE) + HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large (16k max)"); + + /* Allocate space in the object headed for the message */ + if ((ret_value = H5O_alloc(f, oh, orig_type, size)) == UFAIL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message"); + + /* Increment any links in message */ + if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg))<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_new_mesg() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_write_mesg + * + * Purpose: Write message to object header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, September 3, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type, + const void *mesg, unsigned flags) +{ + H5O_mesg_t *idx_msg; /* Pointer to message to modify */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOINIT(H5O_write_mesg); + + /* check args */ + assert(oh); + assert(type); + assert(mesg); + /* Set pointer to the correct message */ idx_msg=&oh->mesg[idx]; - /* Copy the native value into the object header */ - if (flags & H5O_FLAG_SHARED) { - if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t)); - } else { - if (idx_msg->native) - H5O_reset_real(idx_msg->type, idx_msg->native); - idx_msg->native = (type->copy) (mesg, idx_msg->native); - if (NULL == idx_msg->native) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header"); - } - + /* Reset existing native information */ + H5O_reset_real(type, idx_msg->native); + + /* Copy the native value for the message */ + if (NULL == (idx_msg->native = (type->copy) (mesg, idx_msg->native))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header"); + idx_msg->flags = flags; idx_msg->dirty = TRUE; oh->cache_info.dirty = TRUE; - /* Set return value */ - ret_value = idx; - done: FUNC_LEAVE_NOAPI(ret_value); -} /* end H5O_append_real () */ +} /* end H5O_write_mesg() */ /*------------------------------------------------------------------------- @@ -2478,10 +2457,10 @@ done: static herr_t H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t dxpl_id) { - H5O_t *oh = NULL; + H5O_t *oh = NULL; + H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ int seq, nfailed = 0; - unsigned u; - H5O_shared_t *sh_mesg = NULL; + unsigned u; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOINIT(H5O_remove_real); @@ -2499,40 +2478,32 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t d if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header"); - for (u = seq = 0; u < oh->nmesgs; u++) { - if (type->id != oh->mesg[u].type->id) + for (u = seq = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) { + if (type->id != curr_msg->type->id) continue; if (seq++ == sequence || H5O_ALL == sequence) { + /* * Keep track of how many times we failed trying to remove constant * messages. */ - if (oh->mesg[u].flags & H5O_FLAG_CONSTANT) { + if (curr_msg->flags & H5O_FLAG_CONSTANT) { nfailed++; continue; - } + } /* end if */ - if (oh->mesg[u].flags & H5O_FLAG_SHARED) { - if (NULL==oh->mesg[u].native) { - sh_mesg = (H5O_SHARED->decode)(ent->file, dxpl_id, oh->mesg[u].raw, - NULL); - if (NULL==(oh->mesg[u].native = sh_mesg)) - HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode shared message info"); - } - if (sh_mesg->in_gh) { - if (H5HG_link (ent->file, dxpl_id, &(sh_mesg->u.gh), -1)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to decrement link count on shared message"); - } else { - if (H5O_link (&(sh_mesg->u.ent), -1, dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to decrement link count on shared message"); - } - } + /* Free any space referred to in the file from this message */ + if(H5O_delete_mesg(ent->file,dxpl_id,curr_msg)<0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message"); /* change message type to nil and zero it */ - oh->mesg[u].type = H5O_NULL; - HDmemset(oh->mesg[u].raw, 0, oh->mesg[u].raw_size); - oh->mesg[u].native = H5O_free_real(type, oh->mesg[u].native); - oh->mesg[u].dirty = TRUE; + curr_msg->type = H5O_NULL; + HDmemset(curr_msg->raw, 0, curr_msg->raw_size); + if(curr_msg->flags & H5O_FLAG_SHARED) + curr_msg->native = H5O_free_real(H5O_SHARED, curr_msg->native); + else + curr_msg->native = H5O_free_real(type, curr_msg->native); + curr_msg->dirty = TRUE; oh->cache_info.dirty = TRUE; H5O_touch_oh(ent->file, oh, FALSE); } @@ -3095,6 +3066,51 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_get_share + * + * Purpose: Call the 'get_share' method for a + * particular class of object header. + * + * Return: Success: Non-negative, and SHARE describes the shared + * object. + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Oct 2 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share) +{ + const H5O_class_t *type; /* Actual H5O class type for the ID */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_get_share,FAIL); + + /* Check args */ + assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + type=message_type_g[type_id]; /* map the type ID to the actual type object */ + assert (type); + assert (type->get_share); + assert (f); + assert (mesg); + assert (share); + + /* Compute the raw data size for the mesg */ + if ((ret_value = (type->get_share)(f, mesg, share))<0) + HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_get_share() */ + + +/*------------------------------------------------------------------------- * Function: H5O_delete * * Purpose: Delete an object header from a file. This frees the file @@ -3173,33 +3189,13 @@ H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh) assert (f); assert (oh); - /* Walk through the list of object header messages, asking each on to + /* Walk through the list of object header messages, asking each one to * delete any file space used */ for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) { - const H5O_class_t *type = NULL; - - /* Don't handle shared messages yet */ - assert(!(curr_msg->flags & H5O_FLAG_SHARED)); - - /* Get the message's type */ - type = curr_msg->type; - - /* Check if there is a file space deletion callback for this type of message */ - if(type->del) { - /* - * Decode the message if necessary. - */ - if (NULL == curr_msg->native) { - assert(type->decode); - curr_msg->native = (type->decode) (f, dxpl_id, curr_msg->raw, NULL); - if (NULL == curr_msg->native) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message"); - } /* end if */ - - if ((type->del)(f, dxpl_id, curr_msg->native)<0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message"); - } /* end if */ + /* Free any space referred to in the file from this message */ + if(H5O_delete_mesg(f,dxpl_id,curr_msg)<0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message"); } /* end for */ /* Free all the chunks for the object header */ @@ -3227,6 +3223,62 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_delete_mesg + * + * Purpose: Internal function to: + * Delete an object header message from a file. This frees the file + * space used for anything referred to in the object header message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * September 26 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg) +{ + const H5O_class_t *type; /* Type of object to free */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOINIT(H5O_delete_mesg); + + /* Check args */ + assert (f); + assert (mesg); + + /* Get the message to free's type */ + if(mesg->flags & H5O_FLAG_SHARED) + type=H5O_SHARED; + else + type = mesg->type; + + /* Check if there is a file space deletion callback for this type of message */ + if(type->del) { + /* + * Decode the message if necessary. + */ + if (NULL == mesg->native) { + assert(type->decode); + mesg->native = (type->decode) (f, dxpl_id, mesg->raw, NULL); + if (NULL == mesg->native) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message"); + } /* end if */ + + if ((type->del)(f, dxpl_id, mesg->native)<0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message"); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_delete_msg() */ + + +/*------------------------------------------------------------------------- * Function: H5O_debug_id * * Purpose: Act as a proxy for calling the 'debug' method for a @@ -3410,7 +3462,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f decode = oh->mesg[i].type->decode; debug = oh->mesg[i].type->debug; } - if (NULL==oh->mesg[i].native && oh->mesg[i].type->decode) + if (NULL==oh->mesg[i].native && decode) oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw, NULL); if (NULL==oh->mesg[i].native) debug = NULL; diff --git a/src/H5Oattr.c b/src/H5Oattr.c index f1217a9..fdf24a6 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -35,6 +35,8 @@ static void *H5O_attr_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_sha static void *H5O_attr_copy (const void *_mesg, void *_dest); static size_t H5O_attr_size (H5F_t *f, const void *_mesg); static herr_t H5O_attr_reset (void *_mesg); +static herr_t H5O_attr_delete (H5F_t *f, hid_t dxpl_id, const void *_mesg); +static herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg); static herr_t H5O_attr_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -49,14 +51,22 @@ const H5O_class_t H5O_ATTR[1] = {{ H5O_attr_size, /* size of raw message */ H5O_attr_reset, /* reset method */ NULL, /* free method */ - NULL, /* file delete method */ + H5O_attr_delete, /* file delete method */ + H5O_attr_link, /* link method */ NULL, /* get share method */ NULL, /* set share method */ H5O_attr_debug, /* debug the message */ }}; +/* This is the initial version, which does not have support for shared datatypes */ #define H5O_ATTR_VERSION 1 +/* This version allows support for shared datatypes */ +#define H5O_ATTR_VERSION_NEW 2 + +/* Flags for attribute flag encoding */ +#define H5O_ATTR_FLAG_TYPE_SHARED 0x01 + /* Interface initialization */ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL @@ -99,6 +109,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED * H5S_simple_t *simple; /*simple dimensionality information */ size_t name_len; /*attribute name length */ int version; /*message version number*/ + unsigned flags=0; /* Attribute flags */ H5A_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_attr_decode, NULL); @@ -112,11 +123,14 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED * /* Version number */ version = *p++; - if (version!=H5O_ATTR_VERSION) + if (version!=H5O_ATTR_VERSION && version!=H5O_ATTR_VERSION_NEW) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for attribute message"); - /* Reserved */ - p++; + /* Get the flags byte if we have a later version of the attribute */ + if(version>H5O_ATTR_VERSION) + flags = *p++; + else + p++; /* Byte is unused when version<2 */ /* * Decode the sizes of the parts of the attribute. The sizes stored in @@ -130,12 +144,34 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED * if (NULL==(attr->name=H5MM_malloc(name_len))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); HDmemcpy(attr->name,p,name_len); - p += H5O_ALIGN(name_len); /* advance the memory pointer */ + if(version < H5O_ATTR_VERSION_NEW) + p += H5O_ALIGN(name_len); /* advance the memory pointer */ + else + p += name_len; /* advance the memory pointer */ /* decode the attribute datatype */ - if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p,NULL))==NULL) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); - p += H5O_ALIGN(attr->dt_size); + if (flags & H5O_ATTR_FLAG_TYPE_SHARED) { + H5O_shared_t *shared; /* Shared information */ + + /* Get the shared information */ + if (NULL == (shared = (H5O_SHARED->decode) (f, dxpl_id, p, NULL))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message"); + + /* Get the actual datatype information */ + if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_DTYPE, NULL))==NULL) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); + + /* Free the shared information */ + H5O_free_real(H5O_SHARED, shared); + } /* end if */ + else { + if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p,NULL))==NULL) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); + } /* end else */ + if(version < H5O_ATTR_VERSION_NEW) + p += H5O_ALIGN(attr->dt_size); + else + p += attr->dt_size; /* decode the attribute dataspace */ if (NULL==(attr->ds = H5FL_CALLOC(H5S_t))) @@ -159,7 +195,10 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED * /* Default to entire dataspace being selected */ if(H5S_select_all(attr->ds,0)<0) HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection"); - p += H5O_ALIGN(attr->ds_size); + if(version < H5O_ATTR_VERSION_NEW) + p += H5O_ALIGN(attr->ds_size); + else + p += attr->ds_size; /* Compute the size of the data */ H5_ASSIGN_OVERFLOW(attr->data_size,H5S_get_simple_extent_npoints(attr->ds)*H5T_get_size(attr->dt),hsize_t,size_t); @@ -206,9 +245,11 @@ done: static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) { - const H5A_t *attr = (const H5A_t *) mesg; - size_t name_len; /* Attribute name length */ - herr_t ret_value=SUCCEED; /* Return value */ + const H5A_t *attr = (const H5A_t *) mesg; + size_t name_len; /* Attribute name length */ + unsigned version; /* Attribute version */ + hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */ + herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_attr_encode, FAIL); @@ -217,16 +258,31 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) assert(p); assert(attr); - /* Version */ - *p++ = H5O_ATTR_VERSION; + /* Check whether datatype is shared */ + if(H5T_committed(attr->dt)) + type_shared = TRUE; + else + type_shared = FALSE; + + /* Check which version to write out */ + if(type_shared) + version = H5O_ATTR_VERSION_NEW; /* Write out new version if shared datatype */ + else + version = H5O_ATTR_VERSION; - /* Reserved */ - *p++ = 0; + /* Encode Version */ + *p++ = version; + + /* Set attribute flags if version >1 */ + if(version>H5O_ATTR_VERSION) + *p++ = (type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 ); /* Set flags for attribute */ + else + *p++ = 0; /* Reserved, for version <2 */ /* * Encode the lengths of the various parts of the attribute message. The * encoded lengths are exact but we pad each part except the data to be a - * multiple of eight bytes. + * multiple of eight bytes (in the first version). */ name_len = HDstrlen(attr->name)+1; UINT16ENCODE(p, name_len); @@ -239,19 +295,47 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) */ HDmemcpy(p, attr->name, name_len); HDmemset(p+name_len, 0, H5O_ALIGN(name_len)-name_len); - p += H5O_ALIGN(name_len); + if(version < H5O_ATTR_VERSION_NEW) + p += H5O_ALIGN(name_len); + else + p += name_len; /* encode the attribute datatype */ - if((H5O_DTYPE->encode)(f,p,attr->dt)<0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype"); - HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size); - p += H5O_ALIGN(attr->dt_size); + if(type_shared) { + H5O_shared_t sh_mesg; + + /* Reset shared message information */ + HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); + + /* Get shared message information from datatype */ + if ((H5O_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); + + /* Encode shared message information for datatype */ + if((H5O_SHARED->encode)(f,p,&sh_mesg)<0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); + } /* end if */ + else { + /* Encode datatype information */ + if((H5O_DTYPE->encode)(f,p,attr->dt)<0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype"); + } /* end else */ + if(version < H5O_ATTR_VERSION_NEW) { + HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size); + p += H5O_ALIGN(attr->dt_size); + } /* end if */ + else + p += attr->dt_size; /* encode the attribute dataspace */ if((H5O_SDSPACE->encode)(f,p,&(attr->ds->extent.u.simple))<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace"); - HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size); - p += H5O_ALIGN(attr->ds_size); + if(version < H5O_ATTR_VERSION_NEW) { + HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size); + p += H5O_ALIGN(attr->ds_size); + } /* end if */ + else + p += attr->ds_size; /* Store attribute data */ HDmemcpy(p,attr->data,attr->data_size); @@ -327,11 +411,13 @@ done: * Added padding between message parts for alignment. --------------------------------------------------------------------------*/ static size_t -H5O_attr_size(H5F_t UNUSED *f, const void *mesg) +H5O_attr_size(H5F_t UNUSED *f, const void *_mesg) { - size_t ret_value = 0; + const H5A_t *attr = (const H5A_t *)_mesg; size_t name_len; - const H5A_t *attr = (const H5A_t *) mesg; + unsigned version; /* Attribute version */ + hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */ + size_t ret_value = 0; FUNC_ENTER_NOAPI(H5O_attr_size, 0); @@ -339,14 +425,38 @@ H5O_attr_size(H5F_t UNUSED *f, const void *mesg) name_len = HDstrlen(attr->name)+1; - ret_value = 2 + /*name size inc. null */ - 2 + /*type size */ - 2 + /*space size */ - 2 + /*reserved */ - H5O_ALIGN(name_len) + /*attribute name */ - H5O_ALIGN(attr->dt_size) + /*data type */ - H5O_ALIGN(attr->ds_size) + /*data space */ - attr->data_size; /*the data itself */ + /* Check whether datatype is shared */ + if(H5T_committed(attr->dt)) + type_shared = TRUE; + else + type_shared = FALSE; + + /* Check which version to write out */ + if(type_shared) + version = H5O_ATTR_VERSION_NEW; /* Write out new version if shared datatype */ + else + version = H5O_ATTR_VERSION; + + if(version < H5O_ATTR_VERSION_NEW) + ret_value = 1 + /*version */ + 1 + /*reserved */ + 2 + /*name size inc. null */ + 2 + /*type size */ + 2 + /*space size */ + H5O_ALIGN(name_len) + /*attribute name */ + H5O_ALIGN(attr->dt_size) + /*data type */ + H5O_ALIGN(attr->ds_size) + /*data space */ + attr->data_size; /*the data itself */ + else + ret_value = 1 + /*version */ + 1 + /*flags */ + 2 + /*name size inc. null */ + 2 + /*type size */ + 2 + /*space size */ + name_len + /*attribute name */ + attr->dt_size + /*data type */ + attr->ds_size + /*data space */ + attr->data_size; /*the data itself */ done: FUNC_LEAVE_NOAPI(ret_value); @@ -390,6 +500,83 @@ done: } +/*------------------------------------------------------------------------- + * Function: H5O_attr_delete + * + * Purpose: Free file space referenced by message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, September 26, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_attr_delete(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg) +{ + const H5A_t *attr = (const H5A_t *) _mesg; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_attr_delete, FAIL); + + /* check args */ + assert(f); + assert(attr); + + /* Check whether datatype is shared */ + if(H5T_committed(attr->dt)) { + /* Decrement the reference count on the shared datatype */ + if(H5T_link(attr->dt,-1,dxpl_id)<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count"); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_attr_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_attr_link + * + * Purpose: Increment reference count on any objects referenced by + * message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, September 26, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg) +{ + const H5A_t *attr = (const H5A_t *) _mesg; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_attr_link, FAIL); + + /* check args */ + assert(f); + assert(attr); + + /* Check whether datatype is shared */ + if(H5T_committed(attr->dt)) { + /* Increment the reference count on the shared datatype */ + if(H5T_link(attr->dt,1,dxpl_id)<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count"); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_attr_link() */ + + /*-------------------------------------------------------------------------- NAME H5O_attr_debug @@ -413,6 +600,9 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in int fwidth) { const H5A_t *mesg = (const H5A_t *)_mesg; + H5O_shared_t sh_mesg; /* Shared message information */ + void *dt_mesg; /* Pointer to datatype message to dump */ + herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int)=NULL; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_attr_debug, FAIL); @@ -436,16 +626,38 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in H5G_ent_debug(f, dxpl_id, &(mesg->ent), stream, indent+3, MAX(0, fwidth-3), HADDR_UNDEF); - fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Data type size:", - (unsigned long)(mesg->dt_size)); fprintf(stream, "%*sData type...\n", indent, ""); - (H5O_DTYPE->debug)(f, dxpl_id, mesg->dt, stream, indent+3, MAX(0, fwidth-3)); + fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3), + "Size:", + (unsigned long)(mesg->dt_size)); + fprintf (stream, "%*s%-*s %s\n", indent+3, "", MAX(0,fwidth-3), + "Shared:", + (H5T_committed(mesg->dt) ? "Yes" : "No") + ); + if(H5T_committed(mesg->dt)) { + /* Reset shared message information */ + HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); + + /* Get shared message information from datatype */ + if ((H5O_DTYPE->get_share)(f, mesg->dt, &sh_mesg/*out*/)<0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't retrieve shared message information"); + + debug=H5O_SHARED->debug; + dt_mesg=&sh_mesg; + } /* end if */ + else { + debug=H5O_DTYPE->debug; + dt_mesg=mesg->dt; + } /* end else */ + if(debug) + (debug)(f, dxpl_id, dt_mesg, stream, indent+3, MAX(0, fwidth-3)); + else + fprintf(stream, "%*s<No info for this message>\n", indent + 6, ""); - fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Data space size:", - (unsigned long)(mesg->ds_size)); fprintf(stream, "%*sData space...\n", indent, ""); + fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3), + "Size:", + (unsigned long)(mesg->ds_size)); H5S_debug(f, dxpl_id, mesg->ds, stream, indent+3, MAX(0, fwidth-3)); done: diff --git a/src/H5Obogus.c b/src/H5Obogus.c index 90b7b3d..b049654 100644 --- a/src/H5Obogus.c +++ b/src/H5Obogus.c @@ -58,6 +58,7 @@ const H5O_class_t H5O_BOGUS[1] = {{ NULL, /*free internal memory */ NULL, /*free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_bogus_debug, /*debug the message */ diff --git a/src/H5Ocont.c b/src/H5Ocont.c index 4b54c4a..e8dca5b 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c @@ -55,6 +55,7 @@ const H5O_class_t H5O_CONT[1] = {{ NULL, /*reset method */ NULL, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_cont_debug, /*debugging */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 2c943cf..5ab3fb4 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -51,6 +51,7 @@ const H5O_class_t H5O_DTYPE[1] = {{ H5O_dtype_reset, /* reset method */ H5O_dtype_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ H5O_dtype_get_share, /* get share method */ H5O_dtype_set_share, /* set share method */ H5O_dtype_debug, /* debug the message */ diff --git a/src/H5Oefl.c b/src/H5Oefl.c index ec33293..4ecd5f8 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -54,6 +54,7 @@ const H5O_class_t H5O_EFL[1] = {{ H5O_efl_reset, /*reset method */ NULL, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_efl_debug, /*debug the message */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 13da259..b2595a0 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -61,6 +61,7 @@ const H5O_class_t H5O_FILL[1] = {{ H5O_fill_reset, /*free internal memory */ H5O_fill_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_fill_debug, /*debug the message */ @@ -78,6 +79,7 @@ const H5O_class_t H5O_FILL_NEW[1] = {{ H5O_fill_new_reset, /*free internal memory */ H5O_fill_new_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_fill_new_debug, /*debug the message */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index fc1eeae..b9a41ec 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -51,6 +51,7 @@ const H5O_class_t H5O_LAYOUT[1] = {{ H5O_layout_reset, /*reset method */ H5O_layout_free, /*free the struct */ H5O_layout_delete, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_layout_debug, /*debug the message */ diff --git a/src/H5Omtime.c b/src/H5Omtime.c index b1d7496..0f56ee1 100644 --- a/src/H5Omtime.c +++ b/src/H5Omtime.c @@ -58,6 +58,7 @@ const H5O_class_t H5O_MTIME[1] = {{ H5O_mtime_reset, /* reset method */ H5O_mtime_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_mtime_debug, /*debug the message */ @@ -76,6 +77,7 @@ const H5O_class_t H5O_MTIME_NEW[1] = {{ H5O_mtime_reset, /* reset method */ H5O_mtime_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_mtime_debug, /*debug the message */ diff --git a/src/H5Oname.c b/src/H5Oname.c index e6b9fb6..231a177 100644 --- a/src/H5Oname.c +++ b/src/H5Oname.c @@ -55,6 +55,7 @@ const H5O_class_t H5O_NAME[1] = {{ H5O_name_reset, /*free internal memory */ NULL, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_name_debug, /*debug the message */ diff --git a/src/H5Onull.c b/src/H5Onull.c index ca811da..bcf3da3 100644 --- a/src/H5Onull.c +++ b/src/H5Onull.c @@ -44,6 +44,7 @@ const H5O_class_t H5O_NULL[1] = {{ NULL, /*no reset method */ NULL, /*no free method */ NULL, /*no file delete method */ + NULL, /*no link method */ NULL, /*no get share method */ NULL, /*no set share method */ NULL, /*no debug method */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 1255764..866e1b7 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -67,6 +67,7 @@ typedef struct H5O_class_t { herr_t (*reset)(void *); /*free nested data structs */ herr_t (*free)(void *); /*free main data struct */ herr_t (*del)(H5F_t *, hid_t, const void *); /* Delete space in file referenced by this message */ + herr_t (*link)(H5F_t *, hid_t, const void *); /* Increment any links in file reference by this message */ herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*); /* Get shared information */ herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*); /* Set shared information */ herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int); @@ -195,6 +196,13 @@ H5_DLLVAR const H5O_class_t H5O_MTIME_NEW[1]; H5_DLLVAR const H5O_class_t H5O_PLIST[1]; /* Package-local function prototypes */ +H5_DLL void * H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, + int sequence, void *mesg, hid_t dxpl_id); +H5_DLL void * H5O_free_real(const H5O_class_t *type, void *mesg); + +/* Shared object operators */ +H5_DLL void * H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, + const H5O_class_t *type, void *mesg); /* Symbol table operators */ H5_DLL void *H5O_stab_fast(const H5G_cache_t *cache, const struct H5O_class_t *type, diff --git a/src/H5Opline.c b/src/H5Opline.c index 21e5b11..972e5e0 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -57,6 +57,7 @@ const H5O_class_t H5O_PLINE[1] = {{ H5O_pline_reset, /* reset method */ H5O_pline_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /* get share method */ NULL, /* set share method */ H5O_pline_debug, /* debug the message */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index ed07b24..bcd2e5b 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -208,7 +208,7 @@ H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/); H5_DLL herr_t H5O_open(H5G_entry_t *ent); H5_DLL herr_t H5O_close(H5G_entry_t *ent); -H5_DLL int H5O_link(H5G_entry_t *ent, int adjust, hid_t dxpl_id); +H5_DLL int H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id); H5_DLL int H5O_count(H5G_entry_t *ent, hid_t type_id, hid_t dxpl_id); H5_DLL htri_t H5O_exists(H5G_entry_t *ent, hid_t type_id, int sequence, hid_t dxpl_id); @@ -232,6 +232,7 @@ H5_DLL herr_t H5O_reset(hid_t type_id, void *native); H5_DLL void *H5O_free(hid_t type_id, void *mesg); H5_DLL void *H5O_copy(hid_t type_id, const void *mesg, void *dst); H5_DLL size_t H5O_raw_size(hid_t type_id, H5F_t *f, const void *mesg); +H5_DLL herr_t H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share); H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index 69e3de7..cc24e19 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -47,6 +47,7 @@ const H5O_class_t H5O_SDSPACE[1] = {{ H5O_sdspace_reset, /* default reset method */ H5O_sdspace_free, /* free method */ NULL, /* file delete method */ + NULL, /* link method */ NULL, /* get share method */ NULL, /* set share method */ H5O_sdspace_debug, /* debug the message */ diff --git a/src/H5Oshared.c b/src/H5Oshared.c index f3f399e..1444e03 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -25,17 +25,22 @@ * the global heap. */ +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ #define H5O_PACKAGE /*suppress error about including H5Opkg */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ #include "H5Gprivate.h" /* Groups */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ static void *H5O_shared_decode (H5F_t*, hid_t dxpl_id, const uint8_t*, H5O_shared_t *sh); static herr_t H5O_shared_encode (H5F_t*, uint8_t*, const void*); -static size_t H5O_shared_size (H5F_t*, const void*); +static void *H5O_shared_copy(const void *_mesg, void *_dest); +static size_t H5O_shared_size (H5F_t*, const void *_mesg); +static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg); +static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg); static herr_t H5O_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int); /* This message derives from H5O */ @@ -45,17 +50,22 @@ const H5O_class_t H5O_SHARED[1] = {{ sizeof(H5O_shared_t), /*native message size */ H5O_shared_decode, /*decode method */ H5O_shared_encode, /*encode method */ - NULL, /*no copy method */ + H5O_shared_copy, /*copy the native value */ H5O_shared_size, /*size method */ NULL, /*no reset method */ NULL, /*no free method */ - NULL, /* file delete method */ + H5O_shared_delete, /*file delete method */ + H5O_shared_link, /*link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_shared_debug, /*debug method */ }}; -#define H5O_SHARED_VERSION 1 +/* Old version, with full symbol table entry as link for object header sharing */ +#define H5O_SHARED_VERSION_1 1 + +/* New version, with just address of object as link for object header sharing */ +#define H5O_SHARED_VERSION 2 /* Interface initialization */ #define PABLO_MASK H5O_shared_mask @@ -64,6 +74,123 @@ static int interface_initialize_g = 0; /*------------------------------------------------------------------------- + * Function: H5O_shared_read + * + * Purpose: Reads a message referred to by a shared message. + * + * Return: Success: Ptr to message in native format. The message + * should be freed by calling H5O_reset(). If + * MESG is a null pointer then the caller should + * also call H5MM_xfree() on the return value + * after calling H5O_reset(). + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 24 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void * +H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_class_t *type, void *mesg) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_shared_read,NULL); + + /* check args */ + assert(f); + assert(shared); + assert(type); + + /* Get the shared message */ + if (shared->in_gh) { + void *tmp_buf, *tmp_mesg; + + if (NULL==(tmp_buf = H5HG_read (f, dxpl_id, &(shared->u.gh), NULL))) + HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to read shared message from global heap"); + tmp_mesg = (type->decode)(f, dxpl_id, tmp_buf, shared); + tmp_buf = H5MM_xfree (tmp_buf); + if (!tmp_mesg) + HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to decode object header shared message"); + if (mesg) { + HDmemcpy (mesg, tmp_mesg, type->native_size); + H5MM_xfree (tmp_mesg); + } /* end if */ + else + ret_value = tmp_mesg; + } /* end if */ + else { + ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id); + if (type->set_share && + (type->set_share)(f, ret_value, shared)<0) + HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information"); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_shared_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_shared_link_adj + * + * Purpose: Changes the link count for the object referenced by a shared + * message. + * + * Return: Success: New link count + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 26 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adjust) +{ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_shared_link_adj,FAIL); + + /* check args */ + assert(f); + assert(shared); + + if (shared->in_gh) { + /* + * The shared message is stored in the global heap. + * Adjust the reference count on the global heap message. + */ + if ((ret_value = H5HG_link (f, dxpl_id, &(shared->u.gh), adjust))<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); + } /* end if */ + else { + /* + * The shared message is stored in some other object header. + * The other object header must be in the same file as the + * new object header. Adjust the reference count on that + * object header. + */ + if (shared->u.ent.file->shared != f->shared) + HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed"); + if ((ret_value = H5O_link (&(shared->u.ent), adjust, dxpl_id))<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_shared_link_adj() */ + + +/*------------------------------------------------------------------------- * Function: H5O_shared_decode * * Purpose: Decodes a shared object message and returns it. @@ -95,28 +222,36 @@ H5O_shared_decode (H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *buf, H5O_share assert (!sh); /* Decode */ - if (NULL==(mesg = H5MM_calloc (sizeof *mesg))) + if (NULL==(mesg = H5MM_calloc (sizeof(H5O_shared_t)))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Version */ version = *buf++; - if (version!=H5O_SHARED_VERSION) + if (version!=H5O_SHARED_VERSION_1 && version!=H5O_SHARED_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for shared object message"); - /* Flags */ + /* Get the shared information flags */ flags = *buf++; mesg->in_gh = (flags & 0x01); - /* Reserved */ - buf += 6; + /* Skip reserved bytes (for version 1) */ + if(version==H5O_SHARED_VERSION_1) + buf += 6; /* Body */ if (mesg->in_gh) { - H5F_addr_decode (f, &buf, &(mesg->u.gh.addr)); - INT32DECODE (buf, mesg->u.gh.idx); - } else { - H5G_ent_decode (f, &buf, &(mesg->u.ent)); - } + H5F_addr_decode (f, &buf, &(mesg->u.gh.addr)); + INT32DECODE (buf, mesg->u.gh.idx); + } /* end if */ + else { + if(version==H5O_SHARED_VERSION_1) + H5G_ent_decode (f, &buf, &(mesg->u.ent)); + else { + assert(version==H5O_SHARED_VERSION); + H5F_addr_decode (f, &buf, &(mesg->u.ent.header)); + mesg->u.ent.file=f; + } /* end else */ + } /* end else */ /* Set return value */ ret_value=mesg; @@ -165,6 +300,7 @@ H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg) *buf++ = H5O_SHARED_VERSION; flags = mesg->in_gh ? 0x01 : 0x00; *buf++ = flags; +#ifdef OLD_WAY *buf++ = 0; /*reserved 1*/ *buf++ = 0; /*reserved 2*/ *buf++ = 0; /*reserved 3*/ @@ -175,9 +311,17 @@ H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg) if (mesg->in_gh) { H5F_addr_encode (f, &buf, mesg->u.gh.addr); INT32ENCODE (buf, mesg->u.gh.idx); - } else { + } /* end if */ + else H5G_ent_encode (f, &buf, &(mesg->u.ent)); - } +#else /* OLD_WAY */ + if (mesg->in_gh) { + H5F_addr_encode (f, &buf, mesg->u.gh.addr); + INT32ENCODE (buf, mesg->u.gh.idx); + } /* end if */ + else + H5F_addr_encode (f, &buf, mesg->u.ent.header); +#endif /* OLD_WAY */ done: FUNC_LEAVE_NOAPI(ret_value); @@ -185,6 +329,49 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_shared_copy + * + * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if + * necessary. + * + * Return: Success: Ptr to _DEST + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 26 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5O_shared_copy(const void *_mesg, void *_dest) +{ + const H5O_shared_t *mesg = (const H5O_shared_t *) _mesg; + H5O_shared_t *dest = (H5O_shared_t *) _dest; + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_shared_copy, NULL); + + /* check args */ + assert(mesg); + if (!dest && NULL==(dest = H5MM_malloc (sizeof(H5O_shared_t)))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* copy */ + *dest = *mesg; + + /* Set return value */ + ret_value=dest; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_shared_copy() */ + + +/*------------------------------------------------------------------------- * Function: H5O_shared_size * * Purpose: Returns the length of a shared object message. @@ -201,16 +388,18 @@ done: *------------------------------------------------------------------------- */ static size_t -H5O_shared_size (H5F_t *f, const void UNUSED *_mesg) +H5O_shared_size (H5F_t *f, const void *_mesg) { + const H5O_shared_t *shared = (const H5O_shared_t *) _mesg; size_t ret_value; FUNC_ENTER_NOAPI(H5O_shared_size, 0); - ret_value = 1 + /*the flags field */ - 7 + /*reserved */ - MAX (H5F_SIZEOF_ADDR(f)+4, /*sharing via global heap */ - H5G_SIZEOF_ENTRY(f)); /*sharing by another obj hdr */ + ret_value = 1 + /*version */ + 1 + /*the flags field */ + (shared->in_gh ? + (H5F_SIZEOF_ADDR(f)+4) : /*sharing via global heap */ + H5F_SIZEOF_ADDR(f)); /*sharing by another obj hdr */ done: FUNC_LEAVE_NOAPI(ret_value); @@ -218,6 +407,77 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_shared_delete + * + * Purpose: Free file space referenced by message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, September 26, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg) +{ + const H5O_shared_t *shared = (const H5O_shared_t *) _mesg; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_shared_delete, FAIL); + + /* check args */ + assert(f); + assert(shared); + + /* Decrement the reference count on the shared object */ + if(H5O_shared_link_adj(f,dxpl_id,shared,-1)<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_shared_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_shared_link + * + * Purpose: Increment reference count on any objects referenced by + * message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, September 26, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg) +{ + const H5O_shared_t *shared = (const H5O_shared_t *) _mesg; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_shared_link, FAIL); + + /* check args */ + assert(f); + assert(shared); + + /* Decrement the reference count on the shared object */ + if(H5O_shared_link_adj(f,dxpl_id,shared,1)<0) + HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_shared_link() */ + + +/*------------------------------------------------------------------------- * Function: H5O_shared_debug * * Purpose: Prints debugging info for the message diff --git a/src/H5Ostab.c b/src/H5Ostab.c index 521ffe3..8b33884 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -59,6 +59,7 @@ const H5O_class_t H5O_STAB[1] = {{ NULL, /*default reset method */ H5O_stab_free, /* free method */ H5O_stab_delete, /* file delete method */ + NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ H5O_stab_debug, /*debug the message */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 5582339..38e0e06 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -124,7 +124,7 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id) H5F_t *file = NULL; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5T_commit, FAIL); + FUNC_ENTER_NOINIT(H5T_commit); assert (loc); assert (name && *name); @@ -204,9 +204,71 @@ H5Tcommitted(hid_t type_id) HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); /* Set return value */ - ret_value= (H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state); + ret_value= H5T_committed(type); done: FUNC_LEAVE_API(ret_value); } + +/*------------------------------------------------------------------------- + * Function: H5T_committed + * + * Purpose: Determines if a data type is committed or not. + * + * Return: Success: TRUE if committed, FALSE otherwise. + * + * Programmer: Quincey Koziol + * Wednesday, September 24, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5T_committed(H5T_t *type) +{ + /* Use no-init for efficiency */ + FUNC_ENTER_NOINIT(H5T_committed); + + assert (type); + + FUNC_LEAVE_NOAPI(H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state); +} /* end H5T_committed() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_link + * + * Purpose: Adjust the link count for an object header by adding + * ADJUST to the link count. + * + * Return: Success: New link count + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, September 26, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id) +{ + int ret_value; /* Return value */ + + /* Use no-init for efficiency */ + FUNC_ENTER_NOAPI(H5T_link,FAIL); + + assert (type); + + /* Adjust the link count on the named datatype */ + if((ret_value=H5O_link(&(type->ent),adjust,dxpl_id))<0) + HGOTO_ERROR (H5E_DATATYPE, H5E_LINK, FAIL, "unable to adjust named datatype link count"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5T_link() */ + diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 1897dbf..ce975a1 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -72,6 +72,8 @@ H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *_op_data); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); +H5_DLL htri_t H5T_committed(H5T_t *type); +H5_DLL int H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id); /* Reference specific functions */ H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt); |