summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-08-29 22:23:04 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-08-29 22:23:04 (GMT)
commitcbf1f8dbb5bebca21959d0eb8bb93100648b8c95 (patch)
tree79a007eca9740ad7b013e5eb168bfb9bb90f6870 /src
parent3ea316ff54d76b866325794d84e4a9c060a4b2b8 (diff)
downloadhdf5-cbf1f8dbb5bebca21959d0eb8bb93100648b8c95.zip
hdf5-cbf1f8dbb5bebca21959d0eb8bb93100648b8c95.tar.gz
hdf5-cbf1f8dbb5bebca21959d0eb8bb93100648b8c95.tar.bz2
[svn-r55] ./src/H5F.c
Added H5Fflush() and H5F_flush() which flush (and optionally invalidate the cache) and flush the file boot block. H5Fcreate() calls H5F_flush() to output the boot block. H5Fclose() calls H5F_flush() to update the boot block. H5F_debug() prints the root symbol table entry. ./src/H5Fpublic.h Added H5Fflush() prototype. ./src/H5G.c The name message is removed when an object moves from the root object position into a directory. Added H5G_debug() to print a symbol table entry. Most of the code was just moved from H5G_node_debug(). ./src/H5Gnode.c Moved some debugging code into H5G_debug(). ./src/H5Gprivate.c Added H5G_debug() prototype. ./src/H5O.c Implemented H5O_remove(). Added identifiers for H5O_SIM_DIM and H5O_SIM_DTYPE so they can be read from files. H5O_load() combines adjacent null messages for better memory management. ./src/H5Oprivate.h Changed minimum header data block size from 16 to 32 bytes. Changed prototype for H5O_remove()
Diffstat (limited to 'src')
-rw-r--r--src/H5F.c167
-rw-r--r--src/H5Fpublic.h1
-rw-r--r--src/H5G.c90
-rw-r--r--src/H5Gnode.c54
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5O.c108
-rw-r--r--src/H5Oprivate.h5
7 files changed, 304 insertions, 123 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 3d8b570..3b08963 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -53,6 +53,7 @@ static intn interface_initialize_g = FALSE;
static herr_t H5F_init_interface(void);
static hdf5_file_t *H5F_new (void);
static hdf5_file_t *H5F_dest (hdf5_file_t *f);
+static herr_t H5F_flush (hdf5_file_t *f, hbool_t invalidate);
/*--------------------------------------------------------------------------
NAME
@@ -415,13 +416,15 @@ H5F_dest (hdf5_file_t *f)
Robb Matzke, 18 Jul 1997
File struct creation and destruction is through H5F_new() H5F_dest().
Writing the root symbol table entry is done with H5G_encode().
+
+ Robb Matzke, 29 Aug 1997
+ Moved creation of the boot block to H5F_flush().
--------------------------------------------------------------------------*/
hatom_t H5Fcreate(const char *filename, uintn flags, hatom_t create_temp, hatom_t access_temp)
{
hdf5_file_t *new_file=NULL; /* file struct for new file */
hdf_file_t f_handle=H5F_INVALID_FILE; /* file handle */
const file_create_temp_t *f_create_parms; /* pointer to the parameters to use when creating the file */
- uint8 temp_buf[H5F_BOOTBLOCK_SIZE], *p; /* temporary buffer for encoding header */
intn file_exists=0; /* flag to indicate that file exists already */
hatom_t ret_value = FAIL;
@@ -485,46 +488,10 @@ hatom_t H5Fcreate(const char *filename, uintn flags, hatom_t create_temp, hatom_
HDmemcpy(&new_file->file_access_parms,f_access_parms,sizeof(file_access_temp_t));
#endif /* LATER */
- /* Create the basic skeleton of the file */
-
- /* Seek to the correct offset to write out the file signature & boot-block */
- if(new_file->file_create_parms.userblock_size>0)
- if(H5F_SEEK(new_file->file_handle,new_file->file_create_parms.userblock_size)==FAIL)
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL);
-
- /* Write out the file-signature */
- if(H5F_WRITE(new_file->file_handle,H5F_SIGNATURE,H5F_SIGNATURE_LEN)==FAIL)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL);
-
- /* Encode the boot block */
- p=temp_buf;
- *p++=f_create_parms->bootblock_ver; /* Encode Boot-block version # */
- *p++=f_create_parms->smallobject_ver; /* Encode Small-Object Heap version # */
- *p++=f_create_parms->freespace_ver; /* Encode Free-Space Info version # */
- *p++=f_create_parms->objectdir_ver; /* Encode Object Directory Format version # */
- *p++=f_create_parms->sharedheader_ver; /* Encode Shared-Header Info version # */
- *p++=f_create_parms->offset_size; /* Encode the number of bytes for the offset */
- *p++=f_create_parms->length_size; /* Encode the number of bytes for the length */
- *p++=0; /* Encode the reserved byte :-) */
- UINT16ENCODE(p,f_create_parms->sym_leaf_k); /*symbol table leaf node 1/2 rank */
- UINT16ENCODE(p,f_create_parms->btree_k[H5B_SNODE_ID]);/*stab internal node 1/2 rank */
- UINT32ENCODE(p,new_file->consist_flags); /* Encode File-Consistancy flags */
- H5F_encode_offset(new_file,p,new_file->smallobj_off); /* Encode offset of global small-object heap */
- H5F_encode_offset(new_file,p,new_file->freespace_off); /* Encode offset of global free-space heap */
- /* Predict the header length and encode it: */
- H5F_encode_length(new_file,p,((p-temp_buf) +
- H5F_SIZEOF_SIZE(new_file) +
- H5G_SIZEOF_ENTRY(new_file)));
-
- /* Encode the uninitialized root symbol-table entry, by adding it to the boot block */
- if (H5G_encode (new_file, &p, new_file->root_sym)<0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
-
- /* Write out the boot block */
- if(H5F_WRITE(new_file->file_handle,temp_buf,(size_t)(p-temp_buf))==FAIL)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL);
- new_file->logical_len = p - temp_buf;
-
+ /* Flush the file signature and boot block */
+ if (H5F_flush (new_file, FALSE)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL); /*can't write file boot block*/
+ }
/* Get an atom for the file */
if((ret_value=H5Aregister_atom(H5_FILE, new_file))==FAIL)
@@ -735,6 +702,115 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5Fflush
+ PURPOSE
+ Flush all cached data to disk and optionally invalidates all cached
+ data.
+ USAGE
+ herr_t H5Fclose(fid, invalidate)
+ hatom_t fid; IN: File ID of file to close.
+ hbool_t invalidate; IN: Invalidate all of the cache?
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ This function flushes all cached data to disk and, if INVALIDATE
+ is non-zero, removes cached objects from the cache so they must be
+ re-read from the file on the next access to the object.
+
+ MODIFICATIONS:
+--------------------------------------------------------------------------*/
+herr_t
+H5Fflush (hatom_t fid, hbool_t invalidate)
+{
+ hdf5_file_t *file = NULL;
+
+ FUNC_ENTER (H5Fflush, H5F_init_interface, FAIL);
+ H5ECLEAR;
+
+ /* check arguments */
+ if (H5_FILE!=H5Aatom_group (fid)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a file atom*/
+ }
+ if (NULL==(file=H5Aatom_object (fid))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL); /*can't get file struct*/
+ }
+
+ /* do work */
+ if (H5F_flush (file, invalidate)<0) {
+ HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL); /*flush failed*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_flush
+ *
+ * Purpose: Flushes (and optionally invalidates) cached data plus the
+ * file boot block. If the logical file size field is zero
+ * then it is updated to be the length of the boot block.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 29 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_flush (hdf5_file_t *f, hbool_t invalidate)
+{
+ uint8 buf[2048], *p=buf;
+
+ FUNC_ENTER (H5F_flush, H5F_init_interface, FAIL);
+
+ /* nothing to do if the file is read only */
+ if (0==(H5ACC_WRITE & f->acc_perm)) HRETURN (SUCCEED);
+
+ /* flush (and invalidate) the entire cache */
+ if (H5AC_flush (f, NULL, 0, invalidate)<0) {
+ HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL); /*can't flush cache*/
+ }
+
+ /* encode the file boot block */
+ HDmemcpy (p, H5F_SIGNATURE, H5F_SIGNATURE_LEN);
+ p += H5F_SIGNATURE_LEN;
+
+ *p++ = f->file_create_parms.bootblock_ver;
+ *p++ = f->file_create_parms.smallobject_ver;
+ *p++ = f->file_create_parms.freespace_ver;
+ *p++ = f->file_create_parms.objectdir_ver;
+ *p++ = f->file_create_parms.sharedheader_ver;
+ *p++ = H5F_SIZEOF_OFFSET (f);
+ *p++ = H5F_SIZEOF_SIZE (f);
+ *p++ = 0; /*reserved*/
+ UINT16ENCODE (p, f->file_create_parms.sym_leaf_k);
+ UINT16ENCODE (p, f->file_create_parms.btree_k[H5B_SNODE_ID]);
+ UINT32ENCODE (p, f->consist_flags);
+ H5F_encode_offset (f, p, f->smallobj_off);
+ H5F_encode_offset (f, p, f->freespace_off);
+ H5F_encode_length (f, p, f->logical_len);
+ H5G_encode (f, &p, f->root_sym);
+
+ /* write the boot block to disk */
+ if (H5F_block_write (f, 0, p-buf, buf)<0) {
+ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL); /*can't write header*/
+ }
+
+ /* update file length if necessary */
+ if (f->logical_len<=0) f->logical_len = p-buf;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+/*--------------------------------------------------------------------------
+ NAME
H5Fclose
PURPOSE
Close an open HDF5 file.
@@ -751,6 +827,10 @@ done:
MODIFICATIONS:
Robb Matzke, 18 Jul 1997
File struct destruction is through H5F_dest().
+
+ Robb Matzke, 29 Aug 1997
+ The file boot block is flushed to disk since it's contents may have
+ changed.
--------------------------------------------------------------------------*/
herr_t H5Fclose(hatom_t fid)
{
@@ -771,8 +851,8 @@ herr_t H5Fclose(hatom_t fid)
/* Decrement the ref. count and recycle the file structure */
if((--file->ref_count)==0)
{
- H5AC_flush (file, NULL, 0, TRUE);
if(file->file_handle!=H5F_INVALID_FILE) {
+ H5F_flush (file, TRUE);
H5F_CLOSE(file->file_handle);
}
H5F_dest (file);
@@ -955,6 +1035,9 @@ H5F_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
"Shared header version number:",
(unsigned)(f->file_create_parms.sharedheader_ver));
+
+ fprintf (stream, "%*sRoot symbol table entry:\n", indent, "");
+ H5G_debug (f, f->root_sym, stream, indent+3, MAX(0, fwidth-3));
FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index b5e3350..84bb359 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -36,6 +36,7 @@ hbool_t H5Fis_hdf5(const char *filename);
hatom_t H5Fcreate(const char *filename, uintn flags, hatom_t create_template, hatom_t access_template);
hatom_t H5Fopen(const char *filename, uintn flags, hatom_t access_template);
herr_t H5Fclose(hatom_t fid);
+herr_t H5Fflush (hatom_t fid, hbool_t invalidate);
hatom_t H5Fget_create_template(hatom_t fid);
#ifdef __cplusplus
diff --git a/src/H5G.c b/src/H5G.c
index b1441c6..3e756b5 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -327,12 +327,17 @@ H5G_mkroot (hdf5_file_t *f, size_t size_hint)
if (H5O_read (f, f->root_sym->header, f->root_sym, H5O_STAB, 0, &stab)) {
/* root directory already exists */
HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL);
+
} else if (H5O_read (f, f->root_sym->header, f->root_sym, H5O_NAME,
0, &name)) {
- root = *(f->root_sym);
- root_name = name.s; /*dont reset name until root_name is done*/
+ /*dont reset name until root_name is done*/
+ root_name = name.s;
reset = TRUE;
- H5O_remove (f, f->root_sym->header, f->root_sym, H5O_NAME, H5O_ALL);
+
+ /* remove all name messages -- don't care if it fails */
+ root = *(f->root_sym);
+ H5O_remove (f, root.header, &root, NULL, H5O_NAME, H5O_ALL);
+
} else {
root = *(f->root_sym);
root_name = "Root Object";
@@ -1260,4 +1265,83 @@ H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
FUNC_LEAVE (SUCCEED);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_debug
+ *
+ * Purpose: Prints debugging information about a symbol table entry.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 29 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_debug (hdf5_file_t *f, H5G_entry_t *ent, FILE *stream, intn indent,
+ intn fwidth)
+{
+ int i;
+ char buf[64];
+
+ FUNC_ENTER (H5G_debug, NULL, FAIL);
+
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Name offset into private heap:",
+ (unsigned long)(ent->name_off));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Object header address:",
+ (unsigned long)(ent->header));
+
+ fprintf (stream, "%*s%-*s ", indent, "", fwidth,
+ "Symbol type:");
+ switch (ent->type) {
+ case H5G_NOTHING_CACHED:
+ fprintf (stream, "Nothing Cached\n");
+ break;
+
+ case H5G_CACHED_SDATA:
+ fprintf (stream, "S-data\n");
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Number type length:",
+ (unsigned)(ent->cache.sdata.nt.length));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Number type architecture:",
+ (unsigned)(ent->cache.sdata.nt.arch));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Number type type:",
+ (unsigned)(ent->cache.sdata.nt.type));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Dimensionality:",
+ (unsigned)(ent->cache.sdata.ndim));
+ for (i=0; i<ent->cache.sdata.ndim && i<4; i++) {
+ sprintf (buf, "Dimension %d", i);
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ buf,
+ (unsigned)(ent->cache.sdata.dim[i]));
+ }
+ break;
+
+ case H5G_CACHED_STAB:
+ fprintf (stream, "Symbol Table\n");
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "B-tree address:",
+ (unsigned long)(ent->cache.stab.btree));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Heap address:",
+ (unsigned long)(ent->cache.stab.heap));
+ break;
+
+ default:
+ fprintf (stream, "*** Unknown symbol type %d\n", ent->type);
+ break;
+ }
+ FUNC_LEAVE (SUCCEED);
+}
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index dd3e832..6c0866b 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -863,8 +863,7 @@ herr_t
H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth, haddr_t heap)
{
- int i, j;
- char buf[64];
+ int i;
H5G_node_t *sn = NULL;
herr_t status;
const char *s;
@@ -909,56 +908,7 @@ H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
"Name:",
s);
}
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Name offset into private heap:",
- (unsigned long)(sn->entry[i].name_off));
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Object header address:",
- (unsigned long)(sn->entry[i].header));
-
- fprintf (stream, "%*s%-*s ", indent, "", fwidth,
- "Symbol type:");
- switch (sn->entry[i].type) {
- case H5G_NOTHING_CACHED:
- fprintf (stream, "Nothing Cached\n");
- break;
-
- case H5G_CACHED_SDATA:
- fprintf (stream, "S-data\n");
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Number type length:",
- (unsigned)(sn->entry[i].cache.sdata.nt.length));
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Number type architecture:",
- (unsigned)(sn->entry[i].cache.sdata.nt.arch));
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Number type type:",
- (unsigned)(sn->entry[i].cache.sdata.nt.type));
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Dimensionality:",
- (unsigned)(sn->entry[i].cache.sdata.ndim));
- for (j=0; j<sn->entry[i].cache.sdata.ndim && j<4; j++) {
- sprintf (buf, "Dimension %d", j);
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- buf,
- (unsigned)(sn->entry[i].cache.sdata.dim[j]));
- }
- break;
-
- case H5G_CACHED_STAB:
- fprintf (stream, "Symbol Table\n");
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "B-tree address:",
- (unsigned long)(sn->entry[i].cache.stab.btree));
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Heap address:",
- (unsigned long)(sn->entry[i].cache.stab.heap));
- break;
-
- default:
- fprintf (stream, "*** Unknown symbol type %d\n", sn->entry[i].type);
- break;
- }
+ H5G_debug (f, sn->entry+i, stream, indent, fwidth);
}
FUNC_LEAVE (SUCCEED);
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 945291e..744a525 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -170,6 +170,8 @@ herr_t H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent);
herr_t H5G_decode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n);
herr_t H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent);
herr_t H5G_encode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n);
+herr_t H5G_debug (hdf5_file_t *f, H5G_entry_t *ent, FILE *stream, intn indent,
+ intn fwidth);
#endif
diff --git a/src/H5O.c b/src/H5O.c
index eaf860a..256393c 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -47,9 +47,9 @@ static intn interface_initialize_g = FALSE;
/* ID to type mapping */
static const H5O_class_t *const message_type_g[] = {
H5O_NULL, /*0x0000 Null */
- NULL, /*0x0001 Simple dimensionality */
+ H5O_SIM_DIM, /*0x0001 Simple dimensionality */
NULL, /*0x0002 Data space (fiber bundle?) */
- NULL, /*0x0003 Simple data type */
+ H5O_SIM_DTYPE, /*0x0003 Simple data type */
NULL, /*0x0004 Compound data type */
NULL, /*0x0005 Data storage -- standard object */
NULL, /*0x0006 Data storage -- compact object */
@@ -253,16 +253,25 @@ H5O_load (hdf5_file_t *f, haddr_t addr, const void *_data)
HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, NULL);
}
- mesgno = oh->nmesgs++;
- if (mesgno>=nmesgs) {
- HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
+ if (H5O_NULL_ID==id && oh->nmesgs>0 &&
+ H5O_NULL_ID==oh->mesg[oh->nmesgs-1].type->id &&
+ oh->mesg[oh->nmesgs-1].chunkno==chunkno) {
+ /* combine adjacent null messages */
+ mesgno = oh->nmesgs - 1;
+ oh->mesg[mesgno].raw_size += 4 + mesg_size;
+ } else {
+ /* new message */
+ mesgno = oh->nmesgs++;
+ if (mesgno>=nmesgs) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
+ }
+ oh->mesg[mesgno].type = message_type_g[id];
+ oh->mesg[mesgno].dirty = FALSE;
+ oh->mesg[mesgno].native = NULL;
+ oh->mesg[mesgno].raw = p;
+ oh->mesg[mesgno].raw_size = mesg_size;
+ oh->mesg[mesgno].chunkno = chunkno;
}
- oh->mesg[mesgno].type = message_type_g[id];
- oh->mesg[mesgno].dirty = FALSE;
- oh->mesg[mesgno].native = NULL;
- oh->mesg[mesgno].raw = p;
- oh->mesg[mesgno].raw_size = mesg_size;
- oh->mesg[mesgno].chunkno = chunkno;
}
assert (p == oh->chunk[chunkno].image + chunk_size);
@@ -403,10 +412,8 @@ H5O_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh)
/* destroy messages */
for (i=0; i<oh->nmesgs; i++) {
- if (oh->mesg[i].native) {
- H5O_reset (oh->mesg[i].type, oh->mesg[i].native);
- oh->mesg[i].native = H5MM_xfree (oh->mesg[i].native);
- }
+ H5O_reset (oh->mesg[i].type, oh->mesg[i].native);
+ oh->mesg[i].native = H5MM_xfree (oh->mesg[i].native);
}
oh->mesg = H5MM_xfree (oh->mesg);
@@ -441,14 +448,16 @@ herr_t
H5O_reset (const H5O_class_t *type, void *native)
{
FUNC_ENTER (H5O_reset, NULL, FAIL);
-
- if (type->reset) {
- if ((type->reset)(native)<0) {
- /* reset class method failed */
- HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL);
+
+ if (native) {
+ if (type->reset) {
+ if ((type->reset)(native)<0) {
+ /* reset class method failed */
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL);
+ }
+ } else {
+ HDmemset (native, 0, type->native_size);
}
- } else {
- HDmemset (native, 0, type->native_size);
}
FUNC_LEAVE (SUCCEED);
@@ -776,6 +785,15 @@ H5O_modify (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
* the sequence numbers to change for subsequent messages of
* the same type.
*
+ * If the messaage was cached in the symbol table entry then
+ * the type field of the symbol table entry is changed to
+ * H5G_NOTHING_CACHED and the ENT_MODIFIED argument will point
+ * to non-zero (the ENT_MODIFIED argument is unchanged if
+ * the ENT type field doesn't change).
+ *
+ * No attempt is made to join adjacent free areas of the
+ * object header into a single larger free area.
+ *
* Return: Success: SUCCEED
*
* Failure: FAIL
@@ -790,11 +808,43 @@ H5O_modify (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
*/
herr_t
H5O_remove (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
- const H5O_class_t *type, intn sequence)
+ hbool_t *ent_modified, const H5O_class_t *type, intn sequence)
{
+ H5O_t *oh = NULL;
+ intn i, seq;
+
FUNC_ENTER (H5O_remove, NULL, FAIL);
- fprintf (stderr, "H5O_remove: not implemented yet (no-op)!\n");
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (type);
+
+ /* load the object header */
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
+ }
+
+ for (i=seq=0; i<oh->nmesgs; i++) {
+ if (type->id != oh->mesg[i].type->id) continue;
+ if (seq++ == sequence || H5O_ALL==sequence) {
+
+ /* clear symbol table entry cache */
+ if (ent && type->cache && H5G_NOTHING_CACHED!=ent->type) {
+ ent->type = H5G_NOTHING_CACHED;
+ if (ent_modified) *ent_modified = TRUE;
+ }
+
+ /* change message type to nil and zero it */
+ oh->mesg[i].type = H5O_NULL;
+ HDmemset (oh->mesg[i].raw, 0, oh->mesg[i].raw_size);
+ H5O_reset (type, oh->mesg[i].native);
+ oh->mesg[i].native = H5MM_xfree (oh->mesg[i].native);
+
+ oh->mesg[i].dirty = TRUE;
+ oh->dirty = TRUE;
+ }
+ }
FUNC_LEAVE (SUCCEED);
}
@@ -1113,6 +1163,16 @@ H5O_alloc (hdf5_file_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
oh->mesg[idx].raw_size>=size) break;
}
+#ifdef LATER
+ /*
+ * Perhaps if we join adjacent null messages we could make one
+ * large enough... we leave this as an exercise for future
+ * programmers :-) This isn't a high priority because when an
+ * object header is read from disk the null messages are combined
+ * anyway.
+ */
+#endif
+
/* if we didn't find one, then allocate more header space */
if (idx>=oh->nmesgs) {
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index f097195..0f774d3 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -25,7 +25,7 @@
#include <H5Tprivate.h>
#include <H5Pprivate.h>
-#define H5O_MIN_SIZE 16 /*min obj header data size */
+#define H5O_MIN_SIZE 32 /*min obj header data size */
#define H5O_NMESGS 32 /*initial number of messages */
#define H5O_NCHUNKS 8 /*initial number of chunks */
#define H5O_NEW_MESG (-1) /*new message */
@@ -175,7 +175,8 @@ intn H5O_modify (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
hbool_t *ent_modified, const H5O_class_t *type,
intn overwrite, const void *mesg);
herr_t H5O_remove (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
- const H5O_class_t *type, intn sequence);
+ hbool_t *ent_modified, const H5O_class_t *type,
+ intn sequence);
herr_t H5O_reset (const H5O_class_t *type, void *native);
herr_t H5O_debug (hdf5_file_t *f, haddr_t addr, FILE *stream,
intn indent, intn fwidth);