summaryrefslogtreecommitdiffstats
path: root/src/H5Olayout.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-05-27 20:26:32 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-05-27 20:26:32 (GMT)
commit6e6760216bd2dc64bba0976cdf1a1fed5a8fa114 (patch)
tree13235c92a1c3d9be4a8dc988788cb2e383e264eb /src/H5Olayout.c
parent66be6f05d417671d1ef202931d769743ad8a83d9 (diff)
downloadhdf5-6e6760216bd2dc64bba0976cdf1a1fed5a8fa114.zip
hdf5-6e6760216bd2dc64bba0976cdf1a1fed5a8fa114.tar.gz
hdf5-6e6760216bd2dc64bba0976cdf1a1fed5a8fa114.tar.bz2
[svn-r8592] Purpose:
Code optimization & bug fix Description: When dimension information is being stored in the storage layout message on disk, it is stored as 32-bit quantities, possibly truncating the dimension information, if a dimension is greater than 32-bits in size. Solution: Fix the storage layout message problem by revising file format to not store dimension information, since it is already available in the dataspace. Also revise the storage layout data structures to be more compartmentalized for the information for contiguous, chunked and compact storage. Platforms tested: FreeBSD 4.9 (sleipnir) w/parallel Solaris 2.7 (arabica) h5committest
Diffstat (limited to 'src/H5Olayout.c')
-rw-r--r--src/H5Olayout.c387
1 files changed, 283 insertions, 104 deletions
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 5dca442..15013ee 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -58,9 +58,11 @@ const H5O_class_t H5O_LAYOUT[1] = {{
}};
/* For forward and backward compatibility. Version is 1 when space is
- * allocated; 2 when space is delayed for allocation. */
+ * allocated; 2 when space is delayed for allocation; 3
+ * is revised to just store information needed for each storage type. */
#define H5O_LAYOUT_VERSION_1 1
#define H5O_LAYOUT_VERSION_2 2
+#define H5O_LAYOUT_VERSION_3 3
/* Interface initialization */
#define PABLO_MASK H5O_layout_mask
@@ -98,7 +100,6 @@ static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
{
H5O_layout_t *mesg = NULL;
- int version;
unsigned u;
void *ret_value; /* Return value */
@@ -114,44 +115,108 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Version. 1 when space allocated; 2 when space allocation is delayed */
- version = *p++;
- if (version!=H5O_LAYOUT_VERSION_1 && version!=H5O_LAYOUT_VERSION_2)
+ mesg->version = *p++;
+ if (mesg->version<H5O_LAYOUT_VERSION_1 || mesg->version>H5O_LAYOUT_VERSION_3)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message");
- /* Dimensionality */
- mesg->ndims = *p++;
- if (mesg->ndims>H5O_LAYOUT_NDIMS)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");
-
- /* Layout class */
- mesg->type = *p++;
- assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);
-
- /* Reserved bytes */
- p += 5;
-
- /* Address */
- 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)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value");
- HDmemcpy(mesg->buf, p, mesg->size);
- p += mesg->size;
+ if(mesg->version < H5O_LAYOUT_VERSION_3) {
+ unsigned ndims; /* Num dimensions in chunk */
+
+ /* Dimensionality */
+ ndims = *p++;
+ if (ndims>H5O_LAYOUT_NDIMS)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");
+
+ /* Layout class */
+ mesg->type = *p++;
+ assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);
+
+ /* Reserved bytes */
+ p += 5;
+
+ /* Address */
+ if(mesg->type==H5D_CONTIGUOUS)
+ H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
+ else if(mesg->type==H5D_CHUNKED)
+ H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));
+
+ /* Read the size */
+ if(mesg->type!=H5D_CHUNKED) {
+ mesg->unused.ndims=ndims;
+
+ for (u = 0; u < ndims; u++)
+ UINT32DECODE(p, mesg->unused.dim[u]);
+
+ /* Don't compute size of contiguous storage here, due to possible
+ * truncation of the dimension sizes when they were stored in this
+ * version of the layout message. Compute the contiguous storage
+ * size in the dataset code, where we've got the dataspace
+ * information available also. - QAK 5/26/04
+ */
+ } /* end if */
+ else {
+ mesg->u.chunk.ndims=ndims;
+ for (u = 0; u < ndims; u++)
+ UINT32DECODE(p, mesg->u.chunk.dim[u]);
+
+ /* Compute chunk size */
+ for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<ndims; u++)
+ mesg->u.chunk.size *= mesg->u.chunk.dim[u];
+ } /* end if */
+
+ if(mesg->type == H5D_COMPACT) {
+ UINT32DECODE(p, mesg->u.compact.size);
+ if(mesg->u.compact.size > 0) {
+ if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
+ HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
+ p += mesg->u.compact.size;
+ }
}
- }
- else if(mesg->type == H5D_CHUNKED || mesg->type == H5D_CONTIGUOUS) {
- /* Compute chunk size */
- for (u=1, mesg->chunk_size=mesg->dim[0]; u<mesg->ndims; u++)
- mesg->chunk_size *= mesg->dim[u];
} /* end if */
+ else {
+ /* Layout class */
+ mesg->type = *p++;
+
+ /* Interpret the rest of the message according to the layout class */
+ switch(mesg->type) {
+ case H5D_CONTIGUOUS:
+ H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
+ H5F_DECODE_LENGTH(f, p, mesg->u.contig.size);
+ break;
+
+ case H5D_CHUNKED:
+ /* Dimensionality */
+ mesg->u.chunk.ndims = *p++;
+ if (mesg->u.chunk.ndims>H5O_LAYOUT_NDIMS)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");
+
+ /* B-tree address */
+ H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));
+
+ /* Chunk dimensions */
+ for (u = 0; u < mesg->u.chunk.ndims; u++)
+ UINT32DECODE(p, mesg->u.chunk.dim[u]);
+
+ /* Compute chunk size */
+ for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<mesg->u.chunk.ndims; u++)
+ mesg->u.chunk.size *= mesg->u.chunk.dim[u];
+ break;
+
+ case H5D_COMPACT:
+ UINT16DECODE(p, mesg->u.compact.size);
+ if(mesg->u.compact.size > 0) {
+ if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
+ HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
+ p += mesg->u.compact.size;
+ } /* end if */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class");
+ } /* end switch */
+ } /* end else */
/* Set return value */
ret_value=mesg;
@@ -197,45 +262,87 @@ H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg)
/* check args */
assert(f);
assert(mesg);
- assert(mesg->ndims > 0 && mesg->ndims <= H5O_LAYOUT_NDIMS);
+ assert(mesg->version>0);
assert(p);
- /* Version: 1 when space allocated; 2 when space allocation is delayed */
- if(mesg->type==H5D_CONTIGUOUS) {
- if(mesg->addr==HADDR_UNDEF)
- *p++ = H5O_LAYOUT_VERSION_2;
- else
- *p++ = H5O_LAYOUT_VERSION_1;
- } else if(mesg->type==H5D_COMPACT) {
- *p++ = H5O_LAYOUT_VERSION_2;
- } else
- *p++ = H5O_LAYOUT_VERSION_1;
-
- /* number of dimensions */
- *p++ = mesg->ndims;
-
- /* layout class */
- *p++ = mesg->type;
-
- /* reserved bytes should be zero */
- for (u=0; u<5; u++)
- *p++ = 0;
-
- /* data or B-tree address */
- 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) {
- HDmemcpy(p, mesg->buf, mesg->size);
- p += mesg->size;
+ /* Version */
+ *p++ = mesg->version;
+
+ /* Check for which information to write */
+ if(mesg->version<3) {
+ /* number of dimensions */
+ assert(mesg->unused.ndims > 0 && mesg->unused.ndims <= H5O_LAYOUT_NDIMS);
+ *p++ = mesg->unused.ndims;
+
+ /* layout class */
+ *p++ = mesg->type;
+
+ /* reserved bytes should be zero */
+ for (u=0; u<5; u++)
+ *p++ = 0;
+
+ /* data or B-tree address */
+ if(mesg->type==H5D_CONTIGUOUS)
+ H5F_addr_encode(f, &p, mesg->u.contig.addr);
+ else if(mesg->type==H5D_CHUNKED)
+ H5F_addr_encode(f, &p, mesg->u.chunk.addr);
+
+ /* dimension size */
+ if(mesg->type!=H5D_CHUNKED)
+ for (u = 0; u < mesg->unused.ndims; u++)
+ UINT32ENCODE(p, mesg->unused.dim[u])
+ else
+ for (u = 0; u < mesg->u.chunk.ndims; u++)
+ UINT32ENCODE(p, mesg->u.chunk.dim[u]);
+
+ if(mesg->type==H5D_COMPACT) {
+ UINT32ENCODE(p, mesg->u.compact.size);
+ if(mesg->u.compact.size>0 && mesg->u.compact.buf) {
+ HDmemcpy(p, mesg->u.compact.buf, mesg->u.compact.size);
+ p += mesg->u.compact.size;
+ }
}
- }
+ } /* end if */
+ else {
+ /* Layout class */
+ *p++ = mesg->type;
+
+ /* Write out layout class specific information */
+ switch(mesg->type) {
+ case H5D_CONTIGUOUS:
+ H5F_addr_encode(f, &p, mesg->u.contig.addr);
+ H5F_ENCODE_LENGTH(f, p, mesg->u.contig.size);
+ break;
+
+ case H5D_CHUNKED:
+ /* Number of dimensions */
+ assert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ *p++ = mesg->u.chunk.ndims;
+
+ /* B-tree address */
+ H5F_addr_encode(f, &p, mesg->u.chunk.addr);
+
+ /* Dimension sizes */
+ for (u = 0; u < mesg->u.chunk.ndims; u++)
+ UINT32ENCODE(p, mesg->u.chunk.dim[u]);
+ break;
+
+ case H5D_COMPACT:
+ /* Size of raw data */
+ UINT16ENCODE(p, mesg->u.compact.size);
+
+ /* Raw data */
+ if(mesg->u.compact.size>0 && mesg->u.compact.buf) {
+ HDmemcpy(p, mesg->u.compact.buf, mesg->u.compact.size);
+ p += mesg->u.compact.size;
+ } /* end if */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "Invalid layout class");
+ break;
+ } /* end switch */
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -279,11 +386,11 @@ H5O_layout_copy(const void *_mesg, void *_dest)
/* Deep copy the buffer for compact datasets also */
if(mesg->type==H5D_COMPACT) {
/* Allocate memory for the raw data */
- if (NULL==(dest->buf=H5MM_malloc(dest->size)))
+ if (NULL==(dest->u.compact.buf=H5MM_malloc(dest->u.compact.size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset");
/* Copy over the raw data */
- HDmemcpy(dest->buf,mesg->buf,dest->size);
+ HDmemcpy(dest->u.compact.buf,mesg->u.compact.buf,dest->u.compact.size);
} /* end if */
/* Set return value */
@@ -315,7 +422,8 @@ done:
size_t
H5O_layout_meta_size(H5F_t *f, const void *_mesg)
{
- const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg;
+ /* Casting away const OK - QAK */
+ H5O_layout_t *mesg = (H5O_layout_t *) _mesg;
size_t ret_value;
FUNC_ENTER_NOAPI(H5O_layout_meta_size, 0);
@@ -323,18 +431,80 @@ H5O_layout_meta_size(H5F_t *f, const void *_mesg)
/* 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 */
+ /* Check version information for new datasets */
+ if(mesg->version==0) {
+ unsigned u;
+
+ /* Check for dimension that would be truncated */
+ assert(mesg->unused.ndims > 0 && mesg->unused.ndims <= H5O_LAYOUT_NDIMS);
+ for (u = 0; u < mesg->unused.ndims; u++)
+ if(mesg->unused.dim[u]!=(0xffffffff&mesg->unused.dim[u])) {
+ /* Make certain the message is encoded with the new version */
+ mesg->version=3;
+ break;
+ } /* end if */
+
+ /* If the message doesn't _have_ to be encoded with the new version */
+ if(mesg->version==0) {
+ /* Version: 1 when space allocated; 2 when space allocation is delayed */
+ if(mesg->type==H5D_CONTIGUOUS) {
+ if(mesg->u.contig.addr==HADDR_UNDEF)
+ mesg->version = H5O_LAYOUT_VERSION_2;
+ else
+ mesg->version = H5O_LAYOUT_VERSION_1;
+ } else if(mesg->type==H5D_COMPACT) {
+ mesg->version = H5O_LAYOUT_VERSION_2;
+ } else
+ mesg->version = H5O_LAYOUT_VERSION_1;
+ } /* end if */
+ } /* end if */
+ assert(mesg->version>0);
- 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 */
+ if(mesg->version<H5O_LAYOUT_VERSION_3) {
+ ret_value = 1 + /* Version number */
+ 1 + /* layout class type */
+ 1 + /* dimensionality */
+ 5 + /* reserved bytes */
+ mesg->unused.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 */
+ } /* end if */
+ else {
+ ret_value = 1 + /* Version number */
+ 1; /* layout class type */
+
+ switch(mesg->type) {
+ case H5D_CONTIGUOUS:
+ ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
+ ret_value += H5F_SIZEOF_SIZE(f); /* Length of data */
+ break;
+
+ case H5D_CHUNKED:
+ /* Number of dimensions (1 byte) */
+ assert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ ret_value++;
+
+ /* B-tree address */
+ ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
+
+ /* Dimension sizes */
+ ret_value += mesg->u.chunk.ndims*4;
+ break;
+
+ case H5D_COMPACT:
+ /* Size of raw data */
+ ret_value+=2;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, 0, "Invalid layout class");
+ break;
+ } /* end switch */
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -370,11 +540,10 @@ H5O_layout_size(H5F_t *f, const void *_mesg)
/* check args */
assert(f);
assert(mesg);
- assert(mesg->ndims > 0 && mesg->ndims <= H5O_LAYOUT_NDIMS);
ret_value = H5O_layout_meta_size(f, mesg);
if(mesg->type==H5D_COMPACT)
- ret_value += mesg->size;/* data for compact dataset */
+ ret_value += mesg->u.compact.size;/* data for compact dataset */
done:
FUNC_LEAVE_NOAPI(ret_value);
}
@@ -406,10 +575,11 @@ H5O_layout_reset (void *_mesg)
if(mesg) {
/* Free the compact storage buffer */
if(mesg->type==H5D_COMPACT)
- mesg->buf=H5MM_xfree(mesg->buf);
+ mesg->u.compact.buf=H5MM_xfree(mesg->u.compact.buf);
/* Reset the message */
mesg->type=H5D_CONTIGUOUS;
+ mesg->version=0;
} /* end if */
done:
@@ -443,7 +613,7 @@ H5O_layout_free (void *_mesg)
/* Free the compact storage buffer */
if(mesg->type==H5D_COMPACT)
- mesg->buf=H5MM_xfree(mesg->buf);
+ mesg->u.compact.buf=H5MM_xfree(mesg->u.compact.buf);
H5FL_FREE(H5O_layout_t,mesg);
@@ -536,21 +706,30 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE
assert(indent >= 0);
assert(fwidth >= 0);
- HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
- H5D_CHUNKED == mesg->type ? "B-tree address:" : "Data address:",
- mesg->addr);
-
- HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Number of dimensions:",
- (unsigned long) (mesg->ndims));
-
- /* Size */
- HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Size:");
- for (u = 0; u < mesg->ndims; u++) {
- HDfprintf(stream, "%s%lu", u ? ", " : "",
- (unsigned long) (mesg->dim[u]));
- }
- HDfprintf(stream, "}\n");
+ if(mesg->type==H5D_CHUNKED) {
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "B-tree address:", mesg->u.chunk.addr);
+ HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Number of dimensions:",
+ (unsigned long) (mesg->u.chunk.ndims));
+ /* Size */
+ HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Size:");
+ for (u = 0; u < mesg->u.chunk.ndims; u++) {
+ HDfprintf(stream, "%s%lu", u ? ", " : "",
+ (unsigned long) (mesg->u.chunk.dim[u]));
+ }
+ HDfprintf(stream, "}\n");
+ } /* end if */
+ else if(mesg->type==H5D_CONTIGUOUS) {
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Data address:", mesg->u.contig.addr);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Data Size:", mesg->u.contig.size);
+ } /* end if */
+ else {
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Data Size:", mesg->u.compact.size);
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value);