diff options
-rw-r--r-- | src/H5O.c | 105 | ||||
-rw-r--r-- | src/H5Ocache.c | 13 | ||||
-rw-r--r-- | src/H5Opkg.h | 20 | ||||
-rw-r--r-- | src/H5Opublic.h | 2 | ||||
-rw-r--r-- | src/H5private.h | 1 | ||||
-rw-r--r-- | src/H5timer.c | 36 | ||||
-rw-r--r-- | test/stab.c | 8 |
7 files changed, 136 insertions, 49 deletions
@@ -43,10 +43,6 @@ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ -#ifdef H5_HAVE_GETTIMEOFDAY -#include <sys/time.h> -#endif /* H5_HAVE_GETTIMEOFDAY */ - /****************/ /* Local Macros */ /****************/ @@ -849,6 +845,12 @@ H5O_new(H5F_t *f, hid_t dxpl_id, size_t chunk_size, H5O_loc_t *loc/*out*/, oh->nlink = 0; oh->skipped_mesg_size = 0; + /* Initialize version-specific fields */ + if(oh->version > H5O_VERSION_1) { + /* Initialize time fields */ + oh->atime = oh->mtime = oh->ctime = H5_now(); + } /* end if */ + /* Compute total size of initial object header */ /* (i.e. object header prefix and first chunk) */ oh_size = H5O_SIZEOF_HDR_OH(oh) + chunk_size; @@ -2253,7 +2255,6 @@ H5O_touch_oh(H5F_t *f, unsigned * oh_flags_ptr) { time_t now; /* Current time */ - unsigned idx; /* Index of modification time message to update */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_touch_oh) @@ -2261,46 +2262,50 @@ H5O_touch_oh(H5F_t *f, HDassert(oh); HDassert(oh_flags_ptr); - /* Look for existing message */ - for(idx = 0; idx < oh->nmesgs; idx++) - if(H5O_MSG_MTIME == oh->mesg[idx].type || H5O_MSG_MTIME_NEW == oh->mesg[idx].type) - break; + /* Get current time */ + now = H5_now(); -#ifdef H5_HAVE_GETTIMEOFDAY - { - struct timeval now_tv; + /* Check version, to determine how to store time information */ + if(oh->version == H5O_VERSION_1) { + unsigned idx; /* Index of modification time message to update */ - HDgettimeofday(&now_tv, NULL); - now = now_tv.tv_sec; - } -#else /* H5_HAVE_GETTIMEOFDAY */ - now = HDtime(NULL); -#endif /* H5_HAVE_GETTIMEOFDAY */ + /* Look for existing message */ + for(idx = 0; idx < oh->nmesgs; idx++) + if(H5O_MSG_MTIME == oh->mesg[idx].type || H5O_MSG_MTIME_NEW == oh->mesg[idx].type) + break; - /* Create a new message, if necessary */ - if(idx == oh->nmesgs) { - size_t size; /* New modification time message size */ + /* Create a new message, if necessary */ + if(idx == oh->nmesgs) { + size_t size; /* New modification time message size */ - /* If we have to create a new message, but we aren't 'forcing' it, get out now */ - if(!force) - HGOTO_DONE(SUCCEED); /*nothing to do*/ + /* If we would have to create a new message, but we aren't 'forcing' it, get out now */ + if(!force) + HGOTO_DONE(SUCCEED); /*nothing to do*/ - size = (H5O_MSG_MTIME_NEW->raw_size)(f, &now); - if((idx = H5O_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, size, oh_flags_ptr)) == UFAIL) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message") - } /* end if */ + size = (H5O_MSG_MTIME_NEW->raw_size)(f, &now); + if((idx = H5O_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, size, oh_flags_ptr)) == UFAIL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message") + } /* end if */ - /* Allocate 'native' space, if necessary */ - if(NULL == oh->mesg[idx].native) { - if(NULL == (oh->mesg[idx].native = H5FL_MALLOC(time_t))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for modification time message") - } /* end if */ + /* Allocate 'native' space, if necessary */ + if(NULL == oh->mesg[idx].native) { + if(NULL == (oh->mesg[idx].native = H5FL_MALLOC(time_t))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for modification time message") + } /* end if */ - /* Update the message */ - *((time_t *)(oh->mesg[idx].native)) = now; + /* Update the message */ + *((time_t *)(oh->mesg[idx].native)) = now; - /* Mark the message & object header as dirty */ - oh->mesg[idx].dirty = TRUE; + /* Mark the message as dirty */ + oh->mesg[idx].dirty = TRUE; + } /* end if */ + else { + /* XXX: For now, update access time & change fields in the object header */ + /* (will need to add some code to update modification time appropriately) */ + oh->atime = oh->ctime = now; + } /* end else */ + + /* Mark the object header as dirty */ *oh_flags_ptr |= H5AC__DIRTIED_FLAG; done: @@ -3852,13 +3857,29 @@ H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) oinfo->rc = oh->nlink; /* Get modification time for object */ - if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_ID, 0, &oinfo->mtime, dxpl_id)) { - H5E_clear_stack(NULL); - if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_NEW_ID, 0, &oinfo->mtime, dxpl_id)) { + if(oh->version > H5O_VERSION_1) { + oinfo->atime = oh->atime; + oinfo->mtime = oh->mtime; + oinfo->ctime = oh->ctime; + } /* end if */ + else { + /* No information for access & modification fields */ + /* (we stopped updating the "modification time" header message for + * raw data changes, so the "modification time" header message + * is closest to the 'change time', in POSIX terms - QAK) + */ + oinfo->atime = 0; + oinfo->mtime = 0; + + /* Might be information for modification time */ + if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_ID, 0, &oinfo->mtime, dxpl_id)) { H5E_clear_stack(NULL); - oinfo->mtime = 0; + if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_NEW_ID, 0, &oinfo->mtime, dxpl_id)) { + H5E_clear_stack(NULL); + oinfo->ctime = 0; + } /* end if */ } /* end if */ - } /* end if */ + } /* end else */ /* Set the version for the object header */ oinfo->hdr.version = oh->version; diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 8ebb6c2..defc14f 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -273,6 +273,14 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* Link count */ UINT32DECODE(p, oh->nlink); + /* Version-specific fields */ + if(oh->version > H5O_VERSION_1) { + /* Time fields */ + UINT32DECODE(p, oh->atime); + UINT32DECODE(p, oh->mtime); + UINT32DECODE(p, oh->ctime); + } /* end if */ + /* First chunk size */ UINT32DECODE(p, chunk_size); @@ -574,6 +582,11 @@ H5O_assert(oh); /* Link count */ UINT32ENCODE(p, oh->nlink); + /* Time fields */ + UINT32ENCODE(p, oh->atime); + UINT32ENCODE(p, oh->mtime); + UINT32ENCODE(p, oh->ctime); + /* Chunk size */ UINT32ENCODE(p, (oh->chunk[0].size - H5O_SIZEOF_HDR_OH(oh))); } /* end if */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 679e021..18a0804 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -85,12 +85,15 @@ 4 + /*reference count */ \ 4) /*header data size */ \ : \ - (H5O_SIZEOF_MAGIC + /*magic number */ \ + (H5O_SIZEOF_MAGIC + /*magic number */ \ 1 + /*version number */ \ 2 + /*number of messages */ \ 4 + /*reference count */ \ + 4 + /*access time */ \ + 4 + /*modification time */ \ + 4 + /*change time */ \ 4 + /*header data size */ \ - H5O_SIZEOF_CHKSUM) /*checksum size */ \ + H5O_SIZEOF_CHKSUM) /*checksum size */ \ ) #define H5O_SIZEOF_HDR_OH(O) \ H5O_SIZEOF_HDR_VERS((O)->version) @@ -184,12 +187,23 @@ typedef struct H5O_chunk_t { struct H5O_t { H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ + + /* General information */ unsigned version; /*version number */ unsigned nlink; /*link count */ - size_t skipped_mesg_size; /*size of skipped messages (for sanity checking) */ + + /* Time information */ + time_t atime; /*access time */ + time_t mtime; /*modification time */ + time_t ctime; /*change time */ + + /* Message management */ size_t nmesgs; /*number of messages */ size_t alloc_nmesgs; /*number of message slots */ H5O_mesg_t *mesg; /*array of messages */ + size_t skipped_mesg_size; /*size of skipped messages (for sanity checking) */ + + /* Chunk management */ size_t nchunks; /*number of chunks */ size_t alloc_nchunks; /*chunks allocated */ H5O_chunk_t *chunk; /*array of chunks */ diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 4591120..b1fa767 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -86,7 +86,9 @@ typedef struct H5O_info_t { haddr_t addr; /* Object address in file */ H5O_type_t type; /* Basic object type (group, dataset, etc.) */ unsigned rc; /* Reference count of object */ + time_t atime; /* Access time */ time_t mtime; /* Modification time */ + time_t ctime; /* Change time */ hsize_t num_attrs; /* # of attributes attached to object */ struct { unsigned version; /* Version number of header format in file */ diff --git a/src/H5private.h b/src/H5private.h index 77fd02b..2d5cbdb 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -511,6 +511,7 @@ H5_DLL void H5_timer_begin (H5_timer_t *timer); H5_DLL void H5_timer_end (H5_timer_t *sum/*in,out*/, H5_timer_t *timer/*in,out*/); H5_DLL void H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds); +H5_DLL time_t H5_now(void); /* Depth of object copy */ typedef enum { diff --git a/src/H5timer.c b/src/H5timer.c index 128c03f..cbbef3f 100644 --- a/src/H5timer.c +++ b/src/H5timer.c @@ -38,6 +38,10 @@ # include <sys/resource.h> #endif +#ifdef H5_HAVE_GETTIMEOFDAY +#include <sys/time.h> +#endif /* H5_HAVE_GETTIMEOFDAY */ + /****************/ /* Local Macros */ @@ -246,3 +250,35 @@ H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds) } } /* end H5_bandwidth() */ + +/*------------------------------------------------------------------------- + * Function: H5_now + * + * Purpose: Retrieves the current time, as seconds after the UNIX epoch. + * + * Return: # of seconds from the epoch (can't fail) + * + * Programmer: Quincey Koziol + * Tuesday, November 28, 2006 + * + *------------------------------------------------------------------------- + */ +time_t +H5_now(void) +{ + time_t now; /* Current time */ + +#ifdef H5_HAVE_GETTIMEOFDAY + { + struct timeval now_tv; + + HDgettimeofday(&now_tv, NULL); + now = now_tv.tv_sec; + } +#else /* H5_HAVE_GETTIMEOFDAY */ + now = HDtime(NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + + return(now); +} /* end H5_now() */ + diff --git a/test/stab.c b/test/stab.c index e23a5f4..1f8528d 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 != 205) TEST_ERROR + if(obj_stat.ohdr.size != 217) TEST_ERROR #else /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.size != 197) TEST_ERROR + if(obj_stat.ohdr.size != 209) TEST_ERROR #endif /* H5_HAVE_LARGE_HSIZET */ if(obj_stat.ohdr.free != 0) TEST_ERROR if(obj_stat.ohdr.nmesgs != 6) TEST_ERROR @@ -452,9 +452,9 @@ 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 != 205) TEST_ERROR + if(obj_stat.ohdr.size != 217) TEST_ERROR #else /* H5_HAVE_LARGE_HSIZET */ - if(obj_stat.ohdr.size != 197) TEST_ERROR + if(obj_stat.ohdr.size != 209) TEST_ERROR #endif /* H5_HAVE_LARGE_HSIZET */ if(obj_stat.ohdr.free != 116) TEST_ERROR if(obj_stat.ohdr.nmesgs != 3) TEST_ERROR |