summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2002-08-20 16:18:02 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2002-08-20 16:18:02 (GMT)
commit29da4951f8aa861cc972c48fef03334c47ff0136 (patch)
tree07183a9df7ec5d173943197c69c00b2a9f199470 /src
parent45a34cf267b823c6f1b62cce215b38546c18a031 (diff)
downloadhdf5-29da4951f8aa861cc972c48fef03334c47ff0136.zip
hdf5-29da4951f8aa861cc972c48fef03334c47ff0136.tar.gz
hdf5-29da4951f8aa861cc972c48fef03334c47ff0136.tar.bz2
[svn-r5879]
Purpose: Design for compact dataset Description: Compact dataset is stored in the header message for dataset layout. Platforms tested: arabica, eirene.
Diffstat (limited to 'src')
-rw-r--r--src/H5D.c226
-rw-r--r--src/H5Dcompact.c121
-rw-r--r--src/H5Dprivate.h3
-rw-r--r--src/H5Dseq.c25
-rw-r--r--src/H5F.c13
-rw-r--r--src/H5Farray.c10
-rw-r--r--src/H5Fcompact.c121
-rw-r--r--src/H5Fpkg.h9
-rw-r--r--src/H5Fprivate.h9
-rw-r--r--src/H5Fseq.c25
-rw-r--r--src/H5O.c4
-rw-r--r--src/H5Olayout.c99
-rw-r--r--src/H5Oprivate.h12
-rw-r--r--src/H5Pfapl.c6
-rw-r--r--src/Makefile.in18
15 files changed, 601 insertions, 100 deletions
diff --git a/src/H5D.c b/src/H5D.c
index b033e48..5612ca5 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -50,10 +50,10 @@
* A dataset is the following struct.
*/
struct H5D_t {
- H5G_entry_t ent; /*cached object header stuff */
- H5T_t *type; /*datatype of this dataset */
- hid_t dcpl_id; /*dataset creation property id */
- H5O_layout_t layout; /*data layout */
+ H5G_entry_t ent; /* cached object header stuff */
+ H5T_t *type; /* datatype of this dataset */
+ hid_t dcpl_id; /* dataset creation property id */
+ H5O_layout_t layout; /* data layout */
};
@@ -1500,6 +1500,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
H5D_t *new_dset = NULL;
H5D_t *ret_value = NULL;
int i, ndims;
+ hsize_t comp_data_size;
unsigned u;
hsize_t max_dim[H5O_LAYOUT_NDIMS]={0};
H5O_efl_t efl;
@@ -1532,8 +1533,12 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter");
if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ if(H5P_get(plist, H5D_CRT_SPACE_TIME_NAME, &space_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
if(dcpl_pline.nfilters > 0 && H5D_CHUNKED != dcpl_layout)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout");
+ if(dcpl_layout==H5D_COMPACT && space_time==H5D_SPACE_ALLOC_LATE)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset doesn't support late space allocation");
/* What file is the dataset being added to? */
if (NULL==(f=H5G_insertion_file(loc, name)))
@@ -1584,7 +1589,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
assert((unsigned)(new_dset->layout.ndims) <= NELMTS(new_dset->layout.dim));
new_dset->layout.dim[new_dset->layout.ndims-1] = H5T_get_size(new_dset->type);
- switch (dcpl_layout) {
+ switch (new_dset->layout.type) {
case H5D_CONTIGUOUS:
/*
* The maximum size of the dataset cannot exceed the storage size.
@@ -1643,6 +1648,24 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
new_dset->layout.dim[u] = chunk_size[u];
break;
+ case H5D_COMPACT:
+ /*
+ * Compact dataset is stored in dataset object header message of
+ * layout.
+ */
+ new_dset->layout.size = H5S_get_simple_extent_npoints(space) *
+ H5T_get_size(type);
+ /* Verify data size is smaller than maximum header message size
+ * (64KB) minus other layout message fields.
+ */
+ comp_data_size=H5O_MAX_SIZE-H5O_layout_meta_size(f, &(new_dset->layout));
+ if(new_dset->layout.size > comp_data_size)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "compact dataset size is bigger than header message maximum size");
+ if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize dimension size of compact dataset storage");
+ /* remember to check if size is small enough to fit header message */
+ break;
+
default:
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
} /* end switch */
@@ -1718,11 +1741,13 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to name dataset");
/*
- * Initialize storage. We assume that external storage is already
- * initialized by the caller, or at least will be before I/O is performed.
+ * Allocate storage. We assume that external storage is already
+ * allocated by the caller, or at least will be before I/O is performed.
* For parallelization, space is always allocated now except using
* external storage. For contiguous layout, space is allocated now if
* space allocate time is early; otherwise delay allocation until H5Dwrite.
+ * For compact dataset, space is allocated regardless of space allocation
+ * time.
*/
#ifdef H5_HAVE_PARALLEL
if (0==efl.nused) {
@@ -1733,7 +1758,8 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
new_dset->layout.addr = HADDR_UNDEF;
#else /*H5_HAVE_PARALLEL*/
if (0==efl.nused) {
- if(dcpl_layout==H5D_CHUNKED || (dcpl_layout==H5D_CONTIGUOUS && space_time==H5D_SPACE_ALLOC_EARLY)) {
+ if(dcpl_layout==H5D_CHUNKED || dcpl_layout==H5D_COMPACT ||
+ (dcpl_layout==H5D_CONTIGUOUS && space_time==H5D_SPACE_ALLOC_EARLY)) {
if (H5F_arr_create(f, &(new_dset->layout))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
} /* end if */
@@ -1744,10 +1770,6 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
new_dset->layout.addr = HADDR_UNDEF;
#endif /*H5_HAVE_PARALLEL*/
- /* Update layout message */
- if (H5O_modify (&(new_dset->ent), H5O_LAYOUT, 0, 0, &(new_dset->layout))<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update layout message");
-
/* Update external storage message */
if (efl.nused>0) {
size_t heap_size = H5HL_ALIGN (1);
@@ -1774,15 +1796,29 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
* 2. layout is contiguous, space allocation time is early, fill value
* writing time is upon allocation
* 3. external space is treated the same as internal except it's always
- * assumed as early for space allocation time. */
+ * assumed as early for space allocation time
+ * 4. compact dataset and fill value writing time is upon allocation
+ */
#ifdef H5_HAVE_PARALLEL
if (H5D_init_storage(new_dset, space)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
#else /*H5_HAVE_PARALLEL*/
- if(fill_time==H5D_FILL_TIME_ALLOC && ((space_time==H5D_SPACE_ALLOC_EARLY && !efl.nused) || (efl.nused)))
- if (H5D_init_storage(new_dset, space)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
+ if(fill_time==H5D_FILL_TIME_ALLOC) {
+ if((dcpl_layout==H5D_CONTIGUOUS && space_time==H5D_SPACE_ALLOC_EARLY)
+ || (dcpl_layout==H5D_CHUNKED && space_time==H5D_SPACE_ALLOC_EARLY)
+ || dcpl_layout==H5D_COMPACT ) {
+ if (H5D_init_storage(new_dset, space)<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
+ }
+ }
+ }
#endif /*H5_HAVE_PARALLEL*/
+
+ /* Update layout message */
+ if (H5D_COMPACT != new_dset->layout.type && H5O_modify (&(new_dset->ent), H5O_LAYOUT, 0, 0, &(new_dset->layout))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update layout");
+ if (H5D_COMPACT == new_dset->layout.type)
+ new_dset->layout.dirty = TRUE;
/* Success */
ret_value = new_dset;
@@ -2048,6 +2084,12 @@ H5D_open_oid(H5G_entry_t *ent)
if(H5P_set(plist, H5D_CRT_CHUNK_SIZE_NAME, dataset->layout.dim) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set chunk size");
break;
+
+ case H5D_COMPACT:
+ layout = H5D_COMPACT;
+ if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set layout");
+ break;
default:
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
} /* end switch */
@@ -2128,6 +2170,13 @@ H5D_close(H5D_t *dataset)
free_failed = (H5T_close(dataset->type) < 0 ||
H5I_dec_ref(dataset->dcpl_id) < 0);
+ /*Update header message of layout for compact dataset.*/
+ if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty) {
+ if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
+ HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
+ dataset->layout.dirty = FALSE;
+ }
+
/* Close the dataset object */
H5O_close(&(dataset->ent));
@@ -2307,7 +2356,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
/* If space hasn't been allocated and not using external storage,
* return fill value to buffer if fill time is upon allocation, or
- * do nothing if fill time is never. */
+ * do nothing if fill time is never. If the dataset is compact and
+ * fill time is NEVER, there is no way to tell whether part of data
+ * has been overwritten. So just proceed in reading.
+ */
if(nelmts > 0 && efl.nused==0 && dataset->layout.type==H5D_CONTIGUOUS
&& dataset->layout.addr==HADDR_UNDEF) {
@@ -2373,7 +2425,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
/* Sanity check dataset, then read it */
- assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused>0);
+ assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused>0 || dataset->layout.type==H5D_COMPACT);
status = (sconv->read)(dataset->ent.file, &(dataset->layout),
dc_plist, H5T_get_size(dataset->type),
file_space, mem_space, dxpl_id, buf/*out*/);
@@ -2667,6 +2719,15 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+ if (!file_space) {
+ if (NULL==(free_this_space=H5S_read (&(dataset->ent))))
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
+ file_space = free_this_space;
+ } /* end if */
+ if (!mem_space)
+ mem_space = file_space;
+ nelmts = (*mem_space->select.get_npoints)(mem_space);
+
#ifdef H5_HAVE_PARALLEL
/* If MPIO or MPIPOSIX is used, no VL datatype support yet. */
/* This is because they use the global heap in the file and we don't */
@@ -2687,15 +2748,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (0==(H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR))
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file");
- if (!file_space) {
- if (NULL==(free_this_space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
- file_space = free_this_space;
- } /* end if */
- if (!mem_space)
- mem_space = file_space;
- nelmts = (*mem_space->select.get_npoints)(mem_space);
-
#ifdef H5_HAVE_PARALLEL
/* Collect Parallel I/O information for possible later use */
if (H5FD_MPIO==H5P_peek_hid_t(dx_plist,H5D_XFER_VFL_ID_NAME)) {
@@ -2706,11 +2758,20 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
xfer_mode = dx->xfer_mode;
}
} /* end if */
+
/* Collective access is not permissible without the MPIO or MPIPOSIX driver */
if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE &&
!(IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file)))
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPIO driver only");
+ /* If dataset is compact, collective access is only allowed when file space
+ * selection is H5S_ALL */
+ if(doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE
+ && dataset->layout.type==H5D_COMPACT) {
+ if(file_space->select.type != H5S_SEL_ALL)
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access to compact dataset doesn't support partial access");
+ }
+
/* Set the "parallel I/O possible" flag, for H5S_find() */
if (H5S_mpi_opt_types_g && IS_H5FD_MPIO(dataset->ent.file)) {
/* Only collective write should call this since it eventually
@@ -3211,18 +3272,27 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
if(H5P_get(plist, H5D_CRT_SPACE_TIME_NAME, &space_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
switch (dset->layout.type) {
+ case H5D_COMPACT:
+ /*
+ * zero set data buf. If fill value is defined, fall through
+ * the H5D_CONTIGUOUS case and initialize with fill value.
+ */
+ if(!fill.buf)
+ HDmemset(dset->layout.buf, 0, dset->layout.size);
+
case H5D_CONTIGUOUS:
/*
* If the fill value is set then write it to the entire extent
- * of the dataset.
+ * of the dataset. Note: library default(fill.buf is NULL) is
+ * not handled here. How to do it?
*/
snpoints = H5S_get_simple_extent_npoints(space);
assert(snpoints>=0);
H5_ASSIGN_OVERFLOW(npoints,snpoints,hssize_t,size_t);
-
+
if (fill.buf) {
/*
* Fill the entire current extent with the fill value. We can do
@@ -3355,22 +3425,27 @@ H5D_get_storage_size(H5D_t *dset)
FUNC_ENTER_NOAPI(H5D_get_storage_size, 0);
- if (H5D_CHUNKED==dset->layout.type) {
- ret_value = H5F_istore_allocated(dset->ent.file, dset->layout.ndims,
- dset->layout.addr);
- } else {
- /* Sanity Check */
- assert(dset->layout.type==H5D_CONTIGUOUS);
-
- /* Datasets which are not allocated yet are using no space on disk */
- if(dset->layout.addr == HADDR_UNDEF)
- ret_value=0;
- else {
- for (u=0, ret_value=1; u<dset->layout.ndims; u++)
- ret_value *= dset->layout.dim[u];
- } /* end else */
- } /* end else */
-
+ switch(dset->layout.type) {
+ case H5D_CHUNKED:
+ ret_value = H5F_istore_allocated(dset->ent.file, dset->layout.ndims,
+ dset->layout.addr);
+ break;
+ case H5D_CONTIGUOUS:
+ /* Datasets which are not allocated yet are using no space on disk */
+ if(dset->layout.addr == HADDR_UNDEF)
+ ret_value=0;
+ else {
+ for (u=0, ret_value=1; u<dset->layout.ndims; u++)
+ ret_value *= dset->layout.dim[u];
+ } /* end else */
+ break;
+ case H5D_COMPACT:
+ ret_value = dset->layout.size;
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset type");
+ }
+
done:
FUNC_LEAVE(ret_value);
}
@@ -4000,6 +4075,64 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_flush
+ *
+ * Purpose: Flush any compact datasets cached in memory
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *
+ * Programmer: Ray Lu
+ *
+ * Date: August 14, 2002
+ *
+ * Comments: Private function
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_flush(H5F_t *f)
+{
+ unsigned num_dsets; /* Number of datasets in file */
+ hid_t *id_list=NULL; /* list of dataset IDs */
+ H5D_t *dataset=NULL; /* Dataset pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+ unsigned j; /* Index variable */
+
+ FUNC_ENTER_NOAPI(H5D_flush, FAIL);
+
+ /* Check args */
+ assert(f);
+
+ /* Update layout message for compact dataset */
+ if(H5F_get_obj_count(f, H5F_OBJ_DATASET, &num_dsets)<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset number");
+ if(num_dsets>0) {
+ if(NULL==(id_list=H5MM_malloc(num_dsets*sizeof(hid_t))))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate memory for ID list");
+ if(H5F_get_obj_ids(f, H5F_OBJ_DATASET, id_list)<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset ID list");
+ for(j=0; j<num_dsets; j++) {
+ if(NULL==(dataset=H5I_object_verify(id_list[j], H5I_DATASET)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset object");
+ if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty)
+ if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message");
+ dataset->layout.dirty = FALSE;
+ }
+ }
+
+done:
+ if(id_list!=NULL)
+ H5MM_xfree(id_list);
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Ddebug
*
* Purpose: Prints various information about a dataset. This function is
@@ -4039,4 +4172,3 @@ H5Ddebug(hid_t dset_id, unsigned UNUSED flags)
done:
FUNC_LEAVE(ret_value);
}
-
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
new file mode 100644
index 0000000..3a36edb
--- /dev/null
+++ b/src/H5Dcompact.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2000-2001 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
+ * August 5, 2002
+ *
+ * Purpose: Compact dataset I/O functions. These routines are similar
+ * H5F_contig_* and H5F_istore_*.
+ */
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+#include "H5private.h"
+#include "H5Eprivate.h"
+#include "H5Fpkg.h"
+#include "H5Oprivate.h"
+#include "H5FDprivate.h" /*file driver */
+#include "H5FLprivate.h" /*Free Lists */
+
+/* Interface initialization */
+#define PABLO_MASK H5Fcompact_mask
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_compact_readv
+ *
+ * Purpose: Reads some data vectors from a dataset into a buffer.
+ * The data is in compact dataset. The address is relative
+ * to the beginning address of the dataset. The offsets and
+ * sequence lengths are in bytes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * August 5, 2002
+ *
+ * Notes:
+ * Offsets in the sequences must be monotonically increasing
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_compact_readv(H5F_t *f, const H5O_layout_t *layout, size_t nseq,
+ size_t size_arr[], hsize_t offset_arr[],
+ hid_t dxpl_id, void *_buf/*out*/)
+{
+ unsigned char *buf=(unsigned char *)_buf;
+ size_t size;
+ haddr_t offset;
+ unsigned u;
+ herr_t ret_value=SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5F_compact_readv, FAIL);
+
+ for(u=0; u<nseq; u++) {
+ size=size_arr[u];
+ offset=offset_arr[u];
+ if(size > 0) {
+ HDmemcpy(buf, (unsigned char*)layout->buf+offset, size);
+ buf +=size;
+ }
+ }
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5F_compact_readv() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_compact_writev
+ *
+ * Purpose: Writes some data vectors from a dataset into a buffer.
+ * The data is in compact dataset. The address is relative
+ * to the beginning address for the file. The offsets and
+ * sequence lengths are in bytes. This function only copies
+ * data into the buffer in the LAYOUT struct and mark it
+ * as DIRTY. Later in H5D_close, the data is copied into
+ * header message in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * August 5, 2002
+ *
+ * Notes:
+ * Offsets in the sequences must be monotonically increasing
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_compact_writev(H5F_t *f, H5O_layout_t *layout, size_t nseq,
+ size_t size_arr[], hsize_t offset_arr[],
+ hid_t dxpl_id, const void *_buf)
+{
+ unsigned char *buf=(unsigned char *)_buf;
+ size_t size;
+ haddr_t offset;
+ unsigned u;
+ herr_t ret_value=SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5F_compact_writev, FAIL);
+
+ for(u=0; u<nseq; u++) {
+ size=size_arr[u];
+ offset=offset_arr[u];
+ if(size > 0) {
+ HDmemcpy((unsigned char*)layout->buf+offset, buf, size);
+ buf += size;
+ }
+ }
+
+ layout->dirty = TRUE;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5F_compact_writev */
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index b0b1609..a60c041 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -142,7 +142,7 @@
#define H5D_XFER_HYPER_VECTOR_SIZE_DEF 1024
typedef struct H5D_t H5D_t;
-
+
/* Functions defined in H5D.c */
__DLL__ herr_t H5D_init(void);
__DLL__ H5D_t *H5D_create(H5G_entry_t *loc, const char *name,
@@ -175,6 +175,7 @@ __DLL__ herr_t H5D_xfer_copy(hid_t new_plist_id, hid_t old_plist_id,
void *copy_data);
__DLL__ herr_t H5D_xfer_close(hid_t dxpl_id, void *close_data);
__DLL__ herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size);
+__DLL__ herr_t H5D_flush(H5F_t *f);
#endif
diff --git a/src/H5Dseq.c b/src/H5Dseq.c
index a3f2941..f3f70de 100644
--- a/src/H5Dseq.c
+++ b/src/H5Dseq.c
@@ -102,7 +102,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_seq_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
const H5S_t *file_space, size_t elmt_size,
size_t seq_len, hsize_t file_offset, const void *buf)
@@ -215,7 +215,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
/* Collective MPIO access is unsupported for non-contiguous datasets */
- if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
+ if (H5D_CHUNKED==layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
@@ -498,6 +498,13 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
break;
+ case H5D_COMPACT:
+
+ /* Pass along the vector of sequences to read */
+ if (H5F_compact_readv(f, layout, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+
+ break;
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
@@ -532,7 +539,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
const H5S_t *file_space, size_t elmt_size,
size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[],
@@ -599,8 +606,8 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
/* Collective MPIO access is unsupported for non-contiguous datasets */
- if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
- HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
+ if (H5D_CHUNKED==layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
+ HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on chunked datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
/* Get necessary properties from property list */
@@ -880,6 +887,14 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
break;
+ case H5D_COMPACT:
+
+ /* Pass along the vector of sequences to write */
+ if (H5F_compact_writev(f, layout, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ break;
+
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
diff --git a/src/H5F.c b/src/H5F.c
index 3afd64f..564fefc 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -69,9 +69,6 @@ static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
hbool_t alloc_only, hbool_t closing);
static haddr_t H5F_locate_signature(H5FD_t *file);
static int H5F_flush_all_cb(H5F_t *f, hid_t fid, const void *_invalidate);
-static herr_t H5F_get_obj_count(H5F_t *f, unsigned types,
- unsigned *obj_id_count);
-static herr_t H5F_get_obj_ids(H5F_t *f, unsigned types, hid_t *obj_id_list);
static herr_t H5F_get_objects(H5F_t *f, unsigned types, hid_t *obj_id_list,
unsigned *obj_id_count);
static herr_t H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
@@ -943,7 +940,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5F_get_obj_count(H5F_t *f, unsigned types, unsigned *obj_id_count)
{
herr_t ret_value = SUCCEED;
@@ -1010,7 +1007,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5F_get_obj_ids(H5F_t *f, unsigned types, hid_t *oid_list)
{
herr_t ret_value = SUCCEED;
@@ -2318,7 +2315,7 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
int btree_k[H5B_NUM_BTREE_ID]; /* B-tree size info */
unsigned sym_leaf_k; /* Number of symbols in B-tree leafs */
H5P_genplist_t *plist; /* Property list */
- herr_t ret_value; /* Return value */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_NOINIT(H5F_flush);
@@ -2346,6 +2343,10 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
/* Avoid flushing buffers & caches when alloc_only set */
if(!alloc_only) {
+ /* flush any cached compact storage raw data */
+ if (H5D_flush(f)<0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache");
+
/* If we are invalidating everything (which only happens just before
* the file closes), release the unused portion of the metadata and
* "small data" blocks back to the free lists in the file.
diff --git a/src/H5Farray.c b/src/H5Farray.c
index 1e389f4..e3657d0 100644
--- a/src/H5Farray.c
+++ b/src/H5Farray.c
@@ -80,6 +80,14 @@ H5F_arr_create (H5F_t *f, struct H5O_layout_t *layout/*in,out*/)
HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage");
break;
+ case H5D_COMPACT:
+ /* Reserve space in layout header message for the entire array. */
+ assert(layout->size>0);
+ if (NULL==(layout->buf=H5MM_malloc(layout->size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset");
+ layout->dirty = TRUE;
+ break;
+
default:
assert ("not implemented yet" && 0);
HGOTO_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL,
@@ -366,7 +374,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_arr_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+H5F_arr_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
const hsize_t _hslab_size[], const hsize_t mem_size[],
const hssize_t mem_offset[], const hssize_t file_offset[],
diff --git a/src/H5Fcompact.c b/src/H5Fcompact.c
new file mode 100644
index 0000000..3a36edb
--- /dev/null
+++ b/src/H5Fcompact.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2000-2001 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
+ * August 5, 2002
+ *
+ * Purpose: Compact dataset I/O functions. These routines are similar
+ * H5F_contig_* and H5F_istore_*.
+ */
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+#include "H5private.h"
+#include "H5Eprivate.h"
+#include "H5Fpkg.h"
+#include "H5Oprivate.h"
+#include "H5FDprivate.h" /*file driver */
+#include "H5FLprivate.h" /*Free Lists */
+
+/* Interface initialization */
+#define PABLO_MASK H5Fcompact_mask
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_compact_readv
+ *
+ * Purpose: Reads some data vectors from a dataset into a buffer.
+ * The data is in compact dataset. The address is relative
+ * to the beginning address of the dataset. The offsets and
+ * sequence lengths are in bytes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * August 5, 2002
+ *
+ * Notes:
+ * Offsets in the sequences must be monotonically increasing
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_compact_readv(H5F_t *f, const H5O_layout_t *layout, size_t nseq,
+ size_t size_arr[], hsize_t offset_arr[],
+ hid_t dxpl_id, void *_buf/*out*/)
+{
+ unsigned char *buf=(unsigned char *)_buf;
+ size_t size;
+ haddr_t offset;
+ unsigned u;
+ herr_t ret_value=SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5F_compact_readv, FAIL);
+
+ for(u=0; u<nseq; u++) {
+ size=size_arr[u];
+ offset=offset_arr[u];
+ if(size > 0) {
+ HDmemcpy(buf, (unsigned char*)layout->buf+offset, size);
+ buf +=size;
+ }
+ }
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5F_compact_readv() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_compact_writev
+ *
+ * Purpose: Writes some data vectors from a dataset into a buffer.
+ * The data is in compact dataset. The address is relative
+ * to the beginning address for the file. The offsets and
+ * sequence lengths are in bytes. This function only copies
+ * data into the buffer in the LAYOUT struct and mark it
+ * as DIRTY. Later in H5D_close, the data is copied into
+ * header message in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * August 5, 2002
+ *
+ * Notes:
+ * Offsets in the sequences must be monotonically increasing
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_compact_writev(H5F_t *f, H5O_layout_t *layout, size_t nseq,
+ size_t size_arr[], hsize_t offset_arr[],
+ hid_t dxpl_id, const void *_buf)
+{
+ unsigned char *buf=(unsigned char *)_buf;
+ size_t size;
+ haddr_t offset;
+ unsigned u;
+ herr_t ret_value=SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5F_compact_writev, FAIL);
+
+ for(u=0; u<nseq; u++) {
+ size=size_arr[u];
+ offset=offset_arr[u];
+ if(size > 0) {
+ HDmemcpy((unsigned char*)layout->buf+offset, buf, size);
+ buf += size;
+ }
+ }
+
+ layout->dirty = TRUE;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5F_compact_writev */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 189cbc7..92e6a5b 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -210,5 +210,14 @@ __DLL__ herr_t H5F_contig_readv(H5F_t *f, hsize_t max_data, H5FD_mem_t type, had
__DLL__ herr_t H5F_contig_writev(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
size_t nseq, size_t size[], hsize_t offset[], hid_t dxpl_id, const void *buf);
+/* Functions that operate on compact dataset storage */
+__DLL__ herr_t H5F_compact_readv(H5F_t *f, const struct H5O_layout_t *layout, size_t nseq,
+ size_t size_arr[], hsize_t offset_arr[],
+ hid_t dxpl_id, void *_buf/*out*/);
+__DLL__ herr_t H5F_compact_writev(H5F_t *f, struct H5O_layout_t *layout, size_t nseq,
+ size_t size_arr[], hsize_t offset_arr[],
+ hid_t dxpl_id, const void *_buf);
+
+
#endif
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index dd7cbd9..15ef548 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -340,6 +340,9 @@ __DLL__ herr_t H5F_init(void);
__DLL__ unsigned H5F_get_intent(const H5F_t *f);
__DLL__ hid_t H5F_get_driver_id(const H5F_t *f);
__DLL__ herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum);
+__DLL__ herr_t H5F_get_obj_count(H5F_t *f, unsigned types,
+ unsigned *obj_id_count);
+__DLL__ herr_t H5F_get_obj_ids(H5F_t *f, unsigned types, hid_t *obj_id_list);
/* Functions that operate on array storage */
__DLL__ herr_t H5F_arr_create(H5F_t *f,
@@ -352,7 +355,7 @@ __DLL__ herr_t H5F_arr_read (H5F_t *f, hid_t dxpl_id,
const hssize_t mem_offset[],
const hssize_t file_offset[], void *_buf/*out*/);
__DLL__ herr_t H5F_arr_write (H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
+ struct H5O_layout_t *layout,
struct H5P_genplist_t *dc_plist,
const hsize_t _hslab_size[],
const hsize_t mem_size[],
@@ -372,7 +375,7 @@ __DLL__ herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id,
const struct H5S_t *file_space, size_t elmt_size, size_t seq_len,
hsize_t file_offset, void *_buf/*out*/);
__DLL__ herr_t H5F_seq_write (H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
+ struct H5O_layout_t *layout,
struct H5P_genplist_t *dc_plist,
const struct H5S_t *file_space, size_t elmt_size, size_t seq_len,
hsize_t file_offset, const void *_buf);
@@ -384,7 +387,7 @@ __DLL__ herr_t H5F_seq_readv(H5F_t *f, hid_t dxpl_id,
const struct H5S_t *file_space, size_t elmt_size, size_t nseq,
size_t seq_len[], hsize_t file_offset[], void *_buf/*out*/);
__DLL__ herr_t H5F_seq_writev(H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
+ struct H5O_layout_t *layout,
struct H5P_genplist_t *dc_plist,
const struct H5S_t *file_space, size_t elmt_size, size_t nseq,
size_t seq_len[], hsize_t file_offset[], const void *_buf);
diff --git a/src/H5Fseq.c b/src/H5Fseq.c
index a3f2941..f3f70de 100644
--- a/src/H5Fseq.c
+++ b/src/H5Fseq.c
@@ -102,7 +102,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_seq_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
const H5S_t *file_space, size_t elmt_size,
size_t seq_len, hsize_t file_offset, const void *buf)
@@ -215,7 +215,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
/* Collective MPIO access is unsupported for non-contiguous datasets */
- if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
+ if (H5D_CHUNKED==layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
@@ -498,6 +498,13 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
break;
+ case H5D_COMPACT:
+
+ /* Pass along the vector of sequences to read */
+ if (H5F_compact_readv(f, layout, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+
+ break;
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
@@ -532,7 +539,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
H5P_genplist_t *dc_plist,
const H5S_t *file_space, size_t elmt_size,
size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[],
@@ -599,8 +606,8 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
/* Collective MPIO access is unsupported for non-contiguous datasets */
- if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
- HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
+ if (H5D_CHUNKED==layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
+ HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on chunked datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
/* Get necessary properties from property list */
@@ -880,6 +887,14 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
break;
+ case H5D_COMPACT:
+
+ /* Pass along the vector of sequences to write */
+ if (H5F_compact_writev(f, layout, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ break;
+
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
diff --git a/src/H5O.c b/src/H5O.c
index 324d28d..900cd8c 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -584,7 +584,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
id = oh->mesg[u].type->id;
UINT16ENCODE(p, id);
- assert (oh->mesg[u].raw_size<65536);
+ assert (oh->mesg[u].raw_size<H5O_MAX_SIZE);
UINT16ENCODE(p, oh->mesg[u].raw_size);
*p++ = oh->mesg[u].flags;
*p++ = 0; /*reserved*/
@@ -1280,7 +1280,7 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
}
if (0==(flags & H5O_FLAG_SHARED)) {
size = (type->raw_size) (ent->file, mesg);
- if (size>=65536)
+ 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);
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 7a65fb9..65f4cdb 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -81,7 +81,7 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
{
H5O_layout_t *mesg = NULL;
int version;
- unsigned u;
+ unsigned u;
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_layout_decode, NULL);
@@ -107,18 +107,31 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
/* Layout class */
mesg->type = *p++;
- assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type);
+ assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);
/* Reserved bytes */
p += 5;
/* Address */
- H5F_addr_decode(f, &p, &(mesg->addr));
+ if(mesg->type!=H5D_COMPACT)
+ H5F_addr_decode(f, &p, &(mesg->addr));
/* Read the size */
for (u = 0; u < mesg->ndims; u++)
UINT32DECODE(p, mesg->dim[u]);
+ if(mesg->type == H5D_COMPACT) {
+ UINT32DECODE(p, mesg->size);
+ if(mesg->size > 0) {
+ if(NULL==(mesg->buf=H5MM_malloc(mesg->size))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for fill value");
+ }
+ HDmemcpy(mesg->buf, p, mesg->size);
+ p += mesg->size;
+ }
+ }
+
/* Set return value */
ret_value=mesg;
@@ -155,7 +168,7 @@ static herr_t
H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg)
{
const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg;
- unsigned u;
+ unsigned u;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_layout_encode, FAIL);
@@ -172,7 +185,9 @@ H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg)
*p++ = H5O_LAYOUT_VERSION_2;
else
*p++ = H5O_LAYOUT_VERSION_1;
- } else
+ } else if(mesg->type==H5D_COMPACT) {
+ *p++ = H5O_LAYOUT_VERSION_2;
+ } else
*p++ = H5O_LAYOUT_VERSION_1;
/* number of dimensions */
@@ -186,12 +201,22 @@ H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg)
*p++ = 0;
/* data or B-tree address */
- H5F_addr_encode(f, &p, mesg->addr);
+ if(mesg->type!=H5D_COMPACT)
+ H5F_addr_encode(f, &p, mesg->addr);
/* dimension size */
for (u = 0; u < mesg->ndims; u++)
UINT32ENCODE(p, mesg->dim[u]);
+ if(mesg->type==H5D_COMPACT) {
+ UINT32ENCODE(p, mesg->size);
+ if(mesg->size>0 && mesg->buf) {
+ H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t);
+ HDmemcpy(p, mesg->buf, mesg->size);
+ p += mesg->size;
+ }
+ }
+
done:
FUNC_LEAVE(ret_value);
}
@@ -240,11 +265,58 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_layout_meta_size
+ *
+ * Purpose: Returns the size of the raw message in bytes except raw data
+ * part for compact dataset. This function doesn't take into
+ * account message alignment.
+ *
+ * Return: Success: Message data size in bytes(except raw data
+ * for compact dataset)
+ * Failure: 0
+ *
+ * Programmer: Raymond Lu
+ * August 14, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5O_layout_meta_size(H5F_t *f, const void *_mesg)
+{
+ const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg;
+ size_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5O_layout_meta_size, 0);
+
+ /* check args */
+ assert(f);
+ assert(mesg);
+ assert(mesg->ndims > 0 && mesg->ndims <= H5O_LAYOUT_NDIMS);
+
+ ret_value = 1 + /* Version number */
+ 1 + /* layout class type */
+ 1 + /* dimensionality */
+ 5 + /* reserved bytes */
+ mesg->ndims * 4; /* size of each dimension */
+
+ if(mesg->type==H5D_COMPACT)
+ ret_value += 4; /* size field for compact dataset */
+ else
+ ret_value += H5F_SIZEOF_ADDR(f); /* file address of data or B-tree for chunked dataset */
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_layout_size
*
- * Purpose: Returns the size of the raw message in bytes not counting the
- * message type or size fields, but only the data fields. This
- * function doesn't take into account message alignment.
+ * Purpose: Returns the size of the raw message in bytes. If it's
+ * compact dataset, the data part is also included.
+ * This function doesn't take into account message alignment.
*
* Return: Success: Message data size in bytes
*
@@ -270,12 +342,9 @@ H5O_layout_size(H5F_t *f, const void *_mesg)
assert(mesg);
assert(mesg->ndims > 0 && mesg->ndims <= H5O_LAYOUT_NDIMS);
- ret_value = H5F_SIZEOF_ADDR(f) + /* B-tree address */
- 1 + /* max dimension index */
- 1 + /* layout class number */
- 6 + /* reserved bytes */
- mesg->ndims * 4; /* alignment */
-
+ ret_value = H5O_layout_meta_size(f, mesg);
+ if(mesg->type==H5D_COMPACT)
+ ret_value += mesg->size;/* data for compact dataset */
done:
FUNC_LEAVE(ret_value);
}
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 786ae69..8c66bcc 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -38,6 +38,7 @@
#define H5O_ALIGN(X) (8*(((X)+8-1)/8))
#define H5O_MIN_SIZE H5O_ALIGN(32) /*min obj header data size */
+#define H5O_MAX_SIZE 65536 /*max 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 */
@@ -165,7 +166,6 @@ typedef struct H5O_fill_new_t {
htri_t fill_defined; /* whether fill value is defined */
} H5O_fill_new_t;
-
/*
* External File List Message
*/
@@ -197,9 +197,12 @@ __DLLVAR__ const H5O_class_t H5O_LAYOUT[1];
typedef struct H5O_layout_t {
int type; /*type of layout, H5D_layout_t */
- haddr_t addr; /*file address of data or B-tree */
+ haddr_t addr; /*file address of data or B-tree */
unsigned ndims; /*num dimensions in stored data */
- hsize_t dim[H5O_LAYOUT_NDIMS]; /*size of data or chunk */
+ hsize_t dim[H5O_LAYOUT_NDIMS]; /*size of data or chunk in bytes */
+ hbool_t dirty; /*dirty flag for compact dataset */
+ size_t size; /*size of compact dataset in bytes */
+ void *buf; /*buffer for compact dataset */
} H5O_layout_t;
/*
@@ -312,6 +315,9 @@ __DLL__ herr_t H5O_share(H5F_t *f, const H5O_class_t *type, const void *mesg,
__DLL__ herr_t H5O_debug(H5F_t *f, haddr_t addr, FILE * stream, int indent,
int fwidth);
+/* Layout operators */
+__DLL__ size_t H5O_layout_meta_size(H5F_t *f, const void *_mesg);
+
/* EFL operators */
__DLL__ hsize_t H5O_efl_total_size(H5O_efl_t *efl);
__DLL__ herr_t H5O_efl_read(H5F_t *f, const H5O_efl_t *efl, haddr_t addr,
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index a20a1b1..c58711e 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -882,12 +882,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Pget_fclose_degree
*
- * Purpose: Returns the current setting for the garbage collection
+ * Purpose: Returns the degree for the file close behavior.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * June, 1999
+ * Programmer: Raymond Lu
+ * November, 2001
*
* Modifications:
*
diff --git a/src/Makefile.in b/src/Makefile.in
index 4f7a155..2b5d416 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -20,15 +20,15 @@ CLEAN=libhdf5.settings
## Source and object files for the library (lexicographically)...
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcontig.c \
- H5Fistore.c H5Fseq.c H5FD.c H5FDcore.c H5FDfamily.c H5FDgass.c H5FDlog.c \
- H5FDmpio.c H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDsrb.c H5FDstdio.c \
- H5FDstream.c H5FL.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c \
- H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c \
- H5Ofill.c H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Osdspace.c \
- H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5R.c \
- H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5T.c \
- H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c \
- H5Zdeflate.c
+ H5Fcompact.c H5Fistore.c H5Fseq.c H5FD.c H5FDcore.c H5FDfamily.c \
+ H5FDgass.c H5FDlog.c H5FDmpio.c H5FDmpiposix.c H5FDmulti.c H5FDsec2.c \
+ H5FDsrb.c H5FDstdio.c H5FDstream.c H5FL.c H5G.c H5Gent.c H5Gnode.c \
+ H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocomp.c \
+ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c H5Oname.c \
+ H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c \
+ H5Pfapl.c H5Pfcpl.c H5R.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c \
+ H5Spoint.c H5Sselect.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c \
+ H5TB.c H5TS.c H5V.c H5Z.c H5Zdeflate.c
LIB_OBJ=$(LIB_SRC:.c=.lo)