summaryrefslogtreecommitdiffstats
path: root/src/H5D.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5D.c')
-rw-r--r--src/H5D.c188
1 files changed, 93 insertions, 95 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 8ab6b19..d3c1a5d 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -45,6 +45,18 @@ static char RcsId[] = "@(#)$Revision$";
#define PABLO_MASK H5D_mask
+/*
+ * A dataset is the following struct.
+ */
+typedef struct H5D_t {
+ hdf5_file_t *file; /* File store for this object */
+ H5G_entry_t *ent; /* Cached object header stuff */
+ h5_datatype_t *type; /* Datatype of this dataset */
+ H5P_dim_t *dim; /* Dimensionality of this dataset */
+ haddr_t data_addr; /* Data storage address */
+ hbool_t dirty; /* Header messages not updated yet */
+} H5D_t;
+
/*--------------------- Locally scoped variables -----------------------------*/
/* Whether we've installed the library termination function yet for this interface */
@@ -110,15 +122,16 @@ void H5D_term_interface (void)
RETURNS
Returns ID (atom) on success, FAIL on failure
DESCRIPTION
- This function actually creates the dataset object, but it cannot be
- accessed by name until it is stored in the file.
+ This function actually creates a dataset object in a file (of course,
+ output might not happen for some time).
--------------------------------------------------------------------------*/
hatom_t H5D_create(hatom_t owner_id, hobjtype_t type, const char *name)
{
H5D_t *new_dset; /* new dataset object to create */
hatom_t ret_value = SUCCEED;
- hdf5_file_t *file = NULL;
-
+ hdf5_file_t *file = NULL;
+ H5G_entry_t tmp_ent;
+
FUNC_ENTER(H5D_create, H5D_init_interface, FAIL);
/* Clear errors and check args and all the boring stuff. */
@@ -135,14 +148,37 @@ hatom_t H5D_create(hatom_t owner_id, hobjtype_t type, const char *name)
/* Initialize the dataset object */
new_dset->file = file;
- new_dset->name = H5MM_xstrdup (name);
- new_dset->cwd = file->root_sym;
- new_dset->ent.header = -1; /* Not on disk yet */
- new_dset->ent.type = H5G_NOTHING_CACHED;
new_dset->type=NULL; /* No type yet */
new_dset->dim=NULL; /* No dimensions yet */
new_dset->data_addr = -1; /* No data yet */
- new_dset->modified=BTRUE; /* Yep, we're new */
+ new_dset->dirty = FALSE; /* There are no messages yet */
+
+ /* Create the (empty) object header in the file */
+ memset (&tmp_ent, 0, sizeof(tmp_ent));
+ if ((tmp_ent.header = H5O_new (file, 0, H5D_MINHDR_SIZE))<0) {
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create header*/
+ }
+
+ /*
+ * Link the (empty) object header into the symbol table so others can
+ * access it. At least that way no one will try to create another one of
+ * these things with the same name. We also hold the object open while
+ * H5D has a handle, preventing others from moving or deleting it from
+ * under us.
+ */
+#ifdef LATER
+ /* We should use the real CWD instead of always the root object! */
+#else
+ H5G_shadow_sync (file->root_sym);
+ if (H5G_insert (file, file->root_sym, NULL, name, &tmp_ent)<0) {
+ /* Something by that name already exists, or some other failure */
+ HGOTO_ERROR (H5E_SYM, H5E_EXISTS, FAIL);
+ }
+ if (NULL==(new_dset->ent = H5G_open (file, file->root_sym, name))) {
+ /* Can't open the header we just created -- should never happen */
+ HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
+#endif
/* Register the new datatype and get an ID for it */
if((ret_value=H5Aregister_atom(H5_DATASET, (const VOIDP)new_dset))<0)
@@ -197,39 +233,44 @@ hatom_t H5D_find_name(hatom_t grp_id, hobjtype_t type, const char *name)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
/* Initialize file, directory, name fields */
- dset->modified = FALSE;
dset->file = file;
- dset->name = H5MM_xstrdup (name);
-/* WARNING! WARNING! WARNING! */
-/* The following line explicitly uses the root symbol as the
- current working directory. This should be changed to something more
- appropriate and is only hacked in here to get the prototype working. -QAK
-*/
-/* WARNING! WARNING! WARNING! */
- dset->cwd = file->root_sym;
-
- /* Get the dataset's symbol table entry */
- if (H5G_find (dset->file, dset->cwd, NULL, dset->name, &(dset->ent))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL);
+ dset->dirty = FALSE;
+
+#ifdef LATER
+ /* We should really use the real CWD instead of the root object! */
+#else
+ /*
+ * WARNING! WARNING! WARNING!
+ * The following line explicitly uses the root symbol as the current
+ * working directory. This should be changed to something more
+ * appropriate and is only hacked in here to get the prototype working.
+ * -QAK
+ * WARNING! WARNING! WARNING!
+ */
+ H5G_shadow_sync (file->root_sym);
+ if (NULL==(dset->ent=H5G_open (file, file->root_sym, name))) {
+ HGOTO_ERROR (H5E_DATASET, H5E_NOTFOUND, FAIL);
+ }
+#endif
/* Get the dataset's type (currently only atomic types) */
if((dset->type=HDcalloc(1,sizeof(h5_datatype_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- if (NULL==H5O_read (dset->file, dset->ent.header, &(dset->ent),
- H5O_SIM_DTYPE, 0, dset->type))
+ if (NULL==H5O_read (dset->file, NO_ADDR, dset->ent, H5O_SIM_DTYPE, 0,
+ dset->type))
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
/* Get the dataset's dimensionality (currently only simple dataspaces) */
if((dset->dim=HDcalloc(1,sizeof(H5P_dim_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
dset->dim->type=H5P_TYPE_SIMPLE; /* for now... */
- if (NULL==(dset->dim->s=H5O_read (dset->file, dset->ent.header,
- &(dset->ent), H5O_SIM_DIM, 0, NULL)))
+ if (NULL==(dset->dim->s=H5O_read (dset->file, NO_ADDR, dset->ent,
+ H5O_SIM_DIM, 0, NULL)))
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
/* Get the dataset's data offset (currently only standard storage) */
- if (NULL==H5O_read (dset->file, dset->ent.header ,&(dset->ent),
- H5O_STD_STORE, 0, &store))
+ if (NULL==H5O_read (dset->file, NO_ADDR, dset->ent, H5O_STD_STORE, 0,
+ &store))
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
dset->data_addr=store.off;
@@ -241,7 +282,6 @@ done:
if(ret_value == FAIL)
{ /* Error condition cleanup */
if (dset) {
- dset->name = H5MM_xfree (dset->name);
#ifdef LATER
/* We might need to free the `type' and `dim' fields also... */
#endif
@@ -290,9 +330,10 @@ herr_t H5Dset_info(hatom_t oid, hatom_t tid, hatom_t did)
if(dataset->type || dataset->dim)
HGOTO_ERROR(H5E_FUNC, H5E_ALREADYINIT, FAIL);
+ /* Update the dataset in memory */
dataset->type=H5Aatom_object(tid);
dataset->dim=H5Aatom_object(did);
- dataset->modified=BTRUE; /* indicate the values have changed */
+ dataset->dirty = TRUE;
done:
if(ret_value == FAIL)
@@ -499,7 +540,7 @@ herr_t H5Dwrite(hatom_t oid, hatom_t did, VOIDP buf)
if(dataset->data_addr<0) {
if((dataset->data_addr=H5MF_alloc(dataset->file,towrite))<0)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- dataset->modified = TRUE;
+ dataset->dirty = TRUE;
}
/* Check memory to disk datatype conversions, etc. */
@@ -551,9 +592,6 @@ herr_t H5D_flush(hatom_t oid)
{
H5D_t *dataset; /* dataset object to release */
herr_t ret_value = SUCCEED;
- intn mesg_sequence = 0; /*message sequence number */
- hbool_t new_dataset; /*is this a new dataset on disk?*/
- hbool_t entry_changed = FALSE; /*did symbol table entry change?*/
FUNC_ENTER(H5D_flush, H5D_init_interface, FAIL);
@@ -564,37 +602,15 @@ herr_t H5D_flush(hatom_t oid)
if((dataset=H5Aatom_object(oid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- if (dataset->modified) {
- /*
- * A new dataset is one which doesn't exist on disk yet.
- */
- new_dataset = (dataset->ent.header < 0);
-
-
- /*
- * If the dataset is new then create an object header for it. Set the
- * message sequence numbers to H5O_NEW_MESSAGE so we create new
- * messages instead of trying to modify existing messages.
- */
- if (new_dataset) {
- dataset->ent.type = H5G_NOTHING_CACHED;
- if ((dataset->ent.header = H5O_new (dataset->file, 0,
- H5D_MINHDR_SIZE))<0) {
- /* Can't create header. */
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- mesg_sequence = H5O_NEW_MESG;
- }
-
+ if (dataset->dirty) {
/*
- * Create or update messages for this dataset. Begin with the
+ * Modify/create messages for this dataset. Begin with the
* type information.
*/
if (H5T_is_atomic (dataset->type)) {
- if (H5O_modify (dataset->file, dataset->ent.header,
- &(dataset->ent), &entry_changed, H5O_SIM_DTYPE,
- mesg_sequence, dataset->type)<0) {
+ if (H5O_modify (dataset->file, NO_ADDR, dataset->ent,
+ H5O_SIM_DTYPE, 0, dataset->type)<0) {
/* Can't create/update type message */
HGOTO_ERROR (H5E_INTERNAL, H5E_CANTCREATE, FAIL);
}
@@ -604,12 +620,11 @@ herr_t H5D_flush(hatom_t oid)
}
/*
- * Write the dimensionality information.
+ * Modify/create the dimensionality information.
*/
if (H5P_is_simple (dataset->dim)) {
- if (H5O_modify (dataset->file, dataset->ent.header,
- &(dataset->ent), &entry_changed, H5O_SIM_DIM,
- mesg_sequence, dataset->dim->s)<0) {
+ if (H5O_modify (dataset->file, NO_ADDR, dataset->ent,
+ H5O_SIM_DIM, 0, dataset->dim->s)<0) {
/* Can't create/update dimensionality message */
HGOTO_ERROR (H5E_INTERNAL, H5E_CANTCREATE, FAIL);
}
@@ -619,7 +634,7 @@ herr_t H5D_flush(hatom_t oid)
}
/*
- * Write the dataset's storage information.
+ * Modify/create the dataset's storage information.
*/
if (dataset->data_addr>=0) {
H5O_std_store_t store; /* standard storage info */
@@ -627,41 +642,21 @@ herr_t H5D_flush(hatom_t oid)
store.len = H5T_size (dataset->type, BTRUE) *
H5P_nelem (dataset->dim);
store.off = dataset->data_addr;
- if (H5O_modify (dataset->file, dataset->ent.header,
- &(dataset->ent), &entry_changed, H5O_STD_STORE,
- mesg_sequence, &store)<0) {
+ if (H5O_modify (dataset->file, NO_ADDR, dataset->ent,
+ H5O_STD_STORE, 0, &store)<0) {
/* Can't create/modify storage information */
HGOTO_ERROR (H5E_INTERNAL, H5E_CANTCREATE, FAIL);
}
}
- /*
- * If this is a new dataset then we must give it a name so others can
- * access it.
- */
- if (new_dataset) {
- assert (dataset->name);
- if (H5G_insert (dataset->file, dataset->cwd, NULL,
- dataset->name, &(dataset->ent))<0) {
- /* Can't name dataset */
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- } else if (entry_changed) {
- if (H5G_modify (dataset->file, dataset->cwd, NULL,
- dataset->name, &(dataset->ent))<0) {
- /* Can't update symbol table entry */
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- }
-
-#ifdef ROBB
- /* Flush dataset header to disk */
- if (H5O_flush (dataset->file, FALSE, dataset->ent.header, NULL)<0) {
+#if 1
+ /* Flush dataset header to disk -- just for debugging */
+ if (H5AC_flush (dataset->file, NULL, dataset->ent->header, FALSE)<0) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTFLUSH, FAIL);
}
-#endif /* ROBB */
-
- dataset->modified = FALSE; /*it's clean now*/
+#endif
+
+ dataset->dirty = FALSE; /*it's clean now*/
}
done:
@@ -703,13 +698,16 @@ herr_t H5D_release(hatom_t oid)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
/* Check if we have information to flush to the file... */
- if(dataset->modified && H5D_flush(oid)<0) {
+ if(dataset->dirty && H5D_flush(oid)<0) {
/* Can't flush dataset */
HGOTO_ERROR (H5E_OHDR, H5E_CANTFLUSH, FAIL);
}
+
+ /* Close the dataset object */
+ H5G_close (dataset->file, dataset->ent);
+ dataset->ent = NULL;
/* release the memory used for the dataset */
- dataset->name = H5MM_xfree (dataset->name);
H5MM_xfree (dataset);
/* Delete the dataset from the atom group */