summaryrefslogtreecommitdiffstats
path: root/src/H5Olayout.c
diff options
context:
space:
mode:
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);