From 1b03a4cc34faee03625e2d71c5fd4a7e9a4adf07 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 28 Nov 2006 15:29:28 -0500 Subject: [svn-r12992] Description: Add fields for tracking attributes on objects to object header prefix, when using the latest version of the format. Reduce size used to store type of header message from 2 bytes to 1. (If we have >256 message types, we probably have a different problem... :-) Also, add "birth" time for object (i.e. creation time) [named to align with similar fields in file systems] Correct bug in H5Gget_objinfo() - retrieve the ctime field from object info, instead of the mtime field. Tested on: Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2) --- src/H5Gdeprec.c | 2 +- src/H5O.c | 35 +++++++++++++++++++++++++++++++---- src/H5Ocache.c | 43 ++++++++++++++++++++++++++++++++++++++++--- src/H5Ocopy.c | 30 ++++++++++++++++++++++++++---- src/H5Opkg.h | 34 ++++++++++++++++++++++++++-------- src/H5Opublic.h | 1 + test/stab.c | 10 +++++----- 7 files changed, 130 insertions(+), 25 deletions(-) diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 20b3096..3be71a8 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -901,7 +901,7 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_ statbuf->nlink = oinfo.rc; /* Get modification time for object */ - statbuf->mtime = oinfo.mtime; + statbuf->mtime = oinfo.ctime; /* Retrieve the object header information */ statbuf->ohdr.size = oinfo.hdr.hdr_size; diff --git a/src/H5O.c b/src/H5O.c index c74e34e..afb7121 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -844,12 +844,32 @@ H5O_new(H5F_t *f, hid_t dxpl_id, size_t chunk_size, H5O_loc_t *loc/*out*/, oh->version = H5F_USE_LATEST_FORMAT(f) ? H5O_VERSION_LATEST : H5O_VERSION_1; oh->nlink = 0; oh->skipped_mesg_size = 0; + oh->sizeof_size = H5F_SIZEOF_SIZE(f); + oh->sizeof_addr = H5F_SIZEOF_ADDR(f); /* Initialize version-specific fields */ if(oh->version > H5O_VERSION_1) { - /* Initialize time fields */ - oh->atime = oh->mtime = oh->ctime = H5_now(); + /* Initialize all time fields with current time */ + oh->atime = oh->mtime = oh->ctime = oh->btime = H5_now(); + + /* Initialize attribute tracking fields */ + oh->max_compact = 0; + oh->min_dense = 0; + oh->nattrs = 0; + oh->attr_fheap_addr = HADDR_UNDEF; + oh->name_bt2_addr = HADDR_UNDEF; } /* end if */ + else { + /* Reset unused time fields */ + oh->atime = oh->mtime = oh->ctime = oh->btime = 0; + + /* Reset unused attribute fields */ + oh->max_compact = 0; + oh->min_dense = 0; + oh->nattrs = 0; + oh->attr_fheap_addr = HADDR_UNDEF; + oh->name_bt2_addr = HADDR_UNDEF; + } /* end else */ /* Compute total size of initial object header */ /* (i.e. object header prefix and first chunk) */ @@ -3861,6 +3881,7 @@ H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) oinfo->atime = oh->atime; oinfo->mtime = oh->mtime; oinfo->ctime = oh->ctime; + oinfo->btime = oh->btime; } /* end if */ else { /* No information for access & modification fields */ @@ -3870,11 +3891,12 @@ H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) */ oinfo->atime = 0; oinfo->mtime = 0; + oinfo->btime = 0; /* Might be information for modification time */ - if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_ID, 0, &oinfo->mtime, dxpl_id)) { + if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_ID, 0, &oinfo->ctime, dxpl_id)) { H5E_clear_stack(NULL); - if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_NEW_ID, 0, &oinfo->mtime, dxpl_id)) { + if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_NEW_ID, 0, &oinfo->ctime, dxpl_id)) { H5E_clear_stack(NULL); oinfo->ctime = 0; } /* end if */ @@ -3920,6 +3942,11 @@ H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) if(curr_msg->flags & H5O_FLAG_SHARED) \ oinfo->hdr.msg_shared |= type_flag; } /* end for */ +#ifdef LATER +/* XXX: Uncomment this when attributes are tracked by the object header */ + if(oh->version > H5O_VERSION_1) + HDassert(oh->nattrs == oinfo->num_attrs); +#endif /* LATER */ /* Iterate over all the chunks, adding any gaps to the free space */ oinfo->hdr.hdr_size = 0; diff --git a/src/H5Ocache.c b/src/H5Ocache.c index defc14f..9f0da22 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -128,7 +128,10 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh) p = curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh); /* Encode the message prefix */ - UINT16ENCODE(p, curr_msg->type->id); + if(oh->version == H5O_VERSION_1) + UINT16ENCODE(p, curr_msg->type->id) + else + *p++ = (uint8_t)curr_msg->type->id; HDassert(curr_msg->raw_size < H5O_MESG_MAX_SIZE); UINT16ENCODE(p, curr_msg->raw_size); *p++ = curr_msg->flags; @@ -206,7 +209,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, { H5O_t *oh = NULL; /* Object header read in */ uint8_t read_buf[H5O_SPEC_READ_SIZE]; /* Buffer for speculative read */ - uint8_t *p; /* Pointer into buffer to decode */ + const uint8_t *p; /* Pointer into buffer to decode */ size_t spec_read_size; /* Size of buffer to speculatively read in */ size_t prefix_size; /* Size of object header prefix */ unsigned nmesgs; /* Total # of messages in this object header */ @@ -246,6 +249,10 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, if(NULL == (oh = H5FL_CALLOC(H5O_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + /* Generic, non-stored information */ + oh->sizeof_size = H5F_SIZEOF_SIZE(f); + oh->sizeof_addr = H5F_SIZEOF_ADDR(f); + /* Check for magic number */ /* (indicates version 2 or later) */ if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5O_SIZEOF_MAGIC)) { @@ -279,7 +286,26 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, UINT32DECODE(p, oh->atime); UINT32DECODE(p, oh->mtime); UINT32DECODE(p, oh->ctime); + UINT32DECODE(p, oh->btime); + + /* Attribute fields */ + UINT16DECODE(p, oh->max_compact); + UINT16DECODE(p, oh->min_dense); + H5F_DECODE_LENGTH(f, p, oh->nattrs); + H5F_addr_decode(f, &p, &(oh->attr_fheap_addr)); + H5F_addr_decode(f, &p, &(oh->name_bt2_addr)); } /* end if */ + else { + /* Reset unused time fields */ + oh->atime = oh->mtime = oh->ctime = oh->btime = 0; + + /* Reset unused attribute fields */ + oh->max_compact = 0; + oh->min_dense = 0; + oh->nattrs = 0; + oh->attr_fheap_addr = HADDR_UNDEF; + oh->name_bt2_addr = HADDR_UNDEF; + } /* end else */ /* First chunk size */ UINT32DECODE(p, chunk_size); @@ -382,7 +408,10 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, uint8_t flags; /* Flags for current message */ /* Decode message prefix info */ - UINT16DECODE(p, id); + if(oh->version == H5O_VERSION_1) + UINT16DECODE(p, id) + else + id = *p++; UINT16DECODE(p, mesg_size); HDassert(mesg_size == H5O_ALIGN_OH(oh, mesg_size)); flags = *p++; @@ -586,6 +615,14 @@ H5O_assert(oh); UINT32ENCODE(p, oh->atime); UINT32ENCODE(p, oh->mtime); UINT32ENCODE(p, oh->ctime); + UINT32ENCODE(p, oh->btime); + + /* Attribute fields */ + UINT16ENCODE(p, oh->max_compact); + UINT16ENCODE(p, oh->min_dense); + H5F_ENCODE_LENGTH(f, p, oh->nattrs); + H5F_addr_encode(f, &p, oh->attr_fheap_addr); + H5F_addr_encode(f, &p, oh->name_bt2_addr); /* Chunk size */ UINT32ENCODE(p, (oh->chunk[0].size - H5O_SIZEOF_HDR_OH(oh))); diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 44baa9e..1d8f400 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -336,7 +336,29 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Initialize header information */ oh_dst->version = oh_src->version; oh_dst->nlink = 0; - oh_dst->skipped_mesg_size = 0; + oh_dst->skipped_mesg_size = oh_src->skipped_mesg_size; + oh_dst->sizeof_size = H5F_SIZEOF_SIZE(oloc_dst->file); + oh_dst->sizeof_addr = H5F_SIZEOF_ADDR(oloc_dst->file); + + /* Copy time fields */ + oh_dst->atime = oh_src->atime; + oh_dst->mtime = oh_src->mtime; + oh_dst->ctime = oh_src->ctime; + oh_dst->btime = oh_src->btime; + + /* Copy attribute information */ + oh_dst->max_compact = oh_src->max_compact; + oh_dst->min_dense = oh_src->min_dense; + oh_dst->nattrs = oh_src->nattrs; + /* XXX: Bail out for now, if the source object has densely stored attributes */ + if(H5F_addr_defined(oh_src->attr_fheap_addr)) + HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "densely stored attributes not supported yet") + else { + HDassert(!H5F_addr_defined(oh_src->name_bt2_addr)); + oh_dst->attr_fheap_addr = HADDR_UNDEF; + oh_dst->name_bt2_addr = HADDR_UNDEF; + } /* end else */ + /* Initialize size of chunk array. The destination always has only one * chunk. @@ -467,9 +489,9 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* copy this message into destination file */ if(copy_type->copy_file) { /* - * Decode the message if necessary. If the message is shared then do - * a shared message, ignoring the message type. - */ + * Decode the message if necessary. If the message is shared then do + * a shared message, ignoring the message type. + */ if(NULL == mesg_src->native) { /* Decode the message if necessary */ HDassert(copy_type->decode); diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 657da10..e8b72e9 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -77,13 +77,13 @@ /* * Size of object header prefix. */ -#define H5O_SIZEOF_HDR_VERS(V) \ +#define H5O_SIZEOF_HDR_VERS(V,SOFS,SOFA) \ (((V) == H5O_VERSION_1) ? \ H5O_ALIGN_OLD(1 + /*version number */ \ 1 + /*reserved */ \ 2 + /*number of messages */ \ 4 + /*reference count */ \ - 4) /*header data size */ \ + 4) /*chunk data size */ \ : \ (H5O_SIZEOF_MAGIC + /*magic number */ \ 1 + /*version number */ \ @@ -92,13 +92,19 @@ 4 + /*access time */ \ 4 + /*modification time */ \ 4 + /*change time */ \ - 4 + /*header data size */ \ + 4 + /*birth time */ \ + 2 + /*max compact attributes */ \ + 2 + /*min dense attributes */ \ + (SOFS) + /*# of attributes */ \ + (SOFA) + /*addr of attribute heap */ \ + (SOFA) + /*addr of attribute name index */ \ + 4 + /*chunk data size */ \ H5O_SIZEOF_CHKSUM) /*checksum size */ \ ) #define H5O_SIZEOF_HDR_OH(O) \ - H5O_SIZEOF_HDR_VERS((O)->version) + H5O_SIZEOF_HDR_VERS((O)->version, (O)->sizeof_size, (O)->sizeof_addr) #define H5O_SIZEOF_HDR_F(F) \ - H5O_SIZEOF_HDR_VERS(H5F_USE_LATEST_FORMAT(F) ? H5O_VERSION_LATEST : H5O_VERSION_1) + H5O_SIZEOF_HDR_VERS(H5F_USE_LATEST_FORMAT(F) ? H5O_VERSION_LATEST : H5O_VERSION_1, H5F_SIZEOF_SIZE(F), H5F_SIZEOF_ADDR(F)) /* * Size of object header message prefix @@ -110,7 +116,7 @@ 1 + /*flags */ \ 3) /*reserved */ \ : \ - (2 + /*message type */ \ + (1 + /*message type */ \ 2 + /*sizeof message data */ \ 1) /*flags */ \ ) @@ -188,14 +194,26 @@ struct H5O_t { H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ - /* General information (stored) */ + /* General information (not stored) */ + size_t sizeof_size; /* Size of file sizes */ + size_t sizeof_addr; /* Size of file addresses */ + + /* Object information (stored) */ unsigned version; /*version number */ unsigned nlink; /*link count */ - /* Time information (stored) */ + /* Time information (stored, for versions > 1) */ time_t atime; /*access time */ time_t mtime; /*modification time */ time_t ctime; /*change time */ + time_t btime; /*birth time */ + + /* Attribute information (stored, for versions > 1) */ + uint16_t max_compact; /* Maximum # of compact attributes */ + uint16_t min_dense; /* Minimum # of "dense" attributes */ + hsize_t nattrs; /* Number of attributes in the group */ + haddr_t attr_fheap_addr; /* Address of fractal heap for storing "dense" attributes */ + haddr_t name_bt2_addr; /* Address of v2 B-tree for indexing names of attributes */ /* Message management (stored, indirectly) */ size_t nmesgs; /*number of messages */ diff --git a/src/H5Opublic.h b/src/H5Opublic.h index b1fa767..828506f 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -89,6 +89,7 @@ typedef struct H5O_info_t { time_t atime; /* Access time */ time_t mtime; /* Modification time */ time_t ctime; /* Change time */ + time_t btime; /* Birth time */ hsize_t num_attrs; /* # of attributes attached to object */ struct { unsigned version; /* Version number of header format in file */ diff --git a/test/stab.c b/test/stab.c index 2bb1cab..7f722fd 100644 --- a/test/stab.c +++ b/test/stab.c @@ -426,9 +426,9 @@ lifecycle(hid_t fapl) /* Check that the object header is only one chunk and the space has been allocated correctly */ if(H5Gget_objinfo(gid, ".", FALSE, &obj_stat) < 0) TEST_ERROR #ifdef H5_HAVE_LARGE_HSIZET - if(obj_stat.ohdr.size != 209) TEST_ERROR + if(obj_stat.ohdr.size != 235) TEST_ERROR #else /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.size != 201) TEST_ERROR + if(obj_stat.ohdr.size != 215) TEST_ERROR #endif /* H5_HAVE_LARGE_HSIZET */ if(obj_stat.ohdr.free != 0) TEST_ERROR if(obj_stat.ohdr.nmesgs != 6) TEST_ERROR @@ -452,11 +452,11 @@ lifecycle(hid_t fapl) /* Check that the object header is still one chunk and the space has been allocated correctly */ if(H5Gget_objinfo(gid, ".", FALSE, &obj_stat) < 0) TEST_ERROR #ifdef H5_HAVE_LARGE_HSIZET - if(obj_stat.ohdr.size != 209) TEST_ERROR + if(obj_stat.ohdr.size != 235) TEST_ERROR #else /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.size != 201) TEST_ERROR + if(obj_stat.ohdr.size != 215) TEST_ERROR #endif /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.free != 116) TEST_ERROR + if(obj_stat.ohdr.free != 112) TEST_ERROR if(obj_stat.ohdr.nmesgs != 3) TEST_ERROR if(obj_stat.ohdr.nchunks != 1) TEST_ERROR -- cgit v0.12