mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-04-24 17:51:25 +08:00
[svn-r8791] Purpose: Rewrote metadata cache (H5AC.c, etc.) to improve performance.
Description: Replaced the old metadata cache with a cache with a modified LRU replacement policy. This should improve the hit rate. Solution: Since we want to flush cache entries in increasing address order, I used the threaded binary B-tree code to store the cache entries. There is a fair bit of overhead here, so we may want to consider other options. While the code is designed to allow the support of other replacement algorithms, at present, only a modified version of LRU is supported. The modified LRU algorithm requires that a user selectable portion of the cache entries be clean. The clean entries are evicted first when writes are not permitted. If the pool of clean entries is used up, the cache grows beyond its user specified maximum size. The cache can also exceed its maximum size if the combined size of the protected (or locked) entries exceeds the maximum size of the cache. Platforms tested: eirene (serial, parallel, fp), h5committested Misc. update:
This commit is contained in:
parent
072919b9d7
commit
c49dd7fa36
4
MANIFEST
4
MANIFEST
@ -774,6 +774,9 @@
|
||||
./src/H5Bpkg.h
|
||||
./src/H5Bprivate.h
|
||||
./src/H5Bpublic.h
|
||||
./src/H5C.c
|
||||
./src/H5Cprivate.h
|
||||
./src/H5Cpublic.h
|
||||
./src/H5D.c
|
||||
./src/H5Dcontig.c
|
||||
./src/H5Dcompact.c
|
||||
@ -959,6 +962,7 @@
|
||||
./test/Makefile.in
|
||||
./test/big.c
|
||||
./test/bittests.c
|
||||
./test/cache.c
|
||||
./test/cmpd_dset.c
|
||||
./test/createnoenc.c
|
||||
./test/dangle.c
|
||||
|
2
src/H5.c
2
src/H5.c
@ -137,6 +137,8 @@ H5_init_library(void)
|
||||
* & dataset interfaces though, in order to provide them with the proper
|
||||
* property classes.
|
||||
*/
|
||||
if (H5E_init()<0)
|
||||
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface")
|
||||
if (H5P_init()<0)
|
||||
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface")
|
||||
if (H5F_init()<0)
|
||||
|
1868
src/H5AC.c
1868
src/H5AC.c
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,9 @@
|
||||
* Purpose: Constants and typedefs available to the rest of the
|
||||
* library.
|
||||
*
|
||||
* Modifications:
|
||||
* Modifications: JRM - 6/4/04
|
||||
* Complete re-write for a new caching algorithm
|
||||
* located in H5C.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -29,21 +31,20 @@
|
||||
#ifndef _H5ACprivate_H
|
||||
#define _H5ACprivate_H
|
||||
|
||||
#include "H5ACpublic.h" /*public prototypes */
|
||||
#include "H5ACpublic.h" /*public prototypes */
|
||||
|
||||
/* Pivate headers needed by this header */
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5Fprivate.h" /* File access */
|
||||
#include "H5Cprivate.h" /* cache */
|
||||
|
||||
/*
|
||||
* Feature: Define H5AC_DEBUG on the compiler command line if you want to
|
||||
* debug H5AC_protect() and H5AC_unprotect() by insuring that
|
||||
* nothing accesses protected objects. NDEBUG must not be defined
|
||||
* in order for this to have any effect.
|
||||
*/
|
||||
#ifdef NDEBUG
|
||||
# undef H5AC_DEBUG
|
||||
#endif
|
||||
|
||||
#define H5AC_BT_ID 0 /*B-tree nodes */
|
||||
#define H5AC_SNODE_ID 1 /*symbol table nodes */
|
||||
#define H5AC_LHEAP_ID 2 /*local heap */
|
||||
#define H5AC_GHEAP_ID 3 /*global heap */
|
||||
#define H5AC_OHDR_ID 4 /*object header */
|
||||
#define H5AC_NTYPES 5
|
||||
|
||||
/*
|
||||
* Class methods pertaining to caching. Each type of cached object will
|
||||
@ -64,28 +65,38 @@
|
||||
* DEST: Just frees memory allocated by the LOAD method.
|
||||
*
|
||||
* CLEAR: Just marks object as non-dirty.
|
||||
*
|
||||
* SIZE: Report the size (on disk) of the specified cache object.
|
||||
* Note that the space allocated on disk may not be contiguous.
|
||||
*/
|
||||
typedef enum H5AC_subid_t {
|
||||
H5AC_BT_ID = 0, /*B-tree nodes */
|
||||
H5AC_SNODE_ID = 1, /*symbol table nodes */
|
||||
H5AC_LHEAP_ID = 2, /*local heap */
|
||||
H5AC_GHEAP_ID = 3, /*global heap */
|
||||
H5AC_OHDR_ID = 4, /*object header */
|
||||
H5AC_NTYPES = 5 /*THIS MUST BE LAST! */
|
||||
} H5AC_subid_t;
|
||||
|
||||
typedef void *(*H5AC_load_func_t)(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
|
||||
typedef herr_t (*H5AC_flush_func_t)(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing);
|
||||
typedef herr_t (*H5AC_dest_func_t)(H5F_t *f, void *thing);
|
||||
typedef herr_t (*H5AC_clear_func_t)(H5F_t *f, void *thing, hbool_t dest);
|
||||
typedef H5C_load_func_t H5AC_load_func_t;
|
||||
typedef H5C_flush_func_t H5AC_flush_func_t;
|
||||
typedef H5C_dest_func_t H5AC_dest_func_t;
|
||||
typedef H5C_clear_func_t H5AC_clear_func_t;
|
||||
typedef H5C_size_func_t H5AC_size_func_t;
|
||||
|
||||
typedef H5C_class_t H5AC_class_t;
|
||||
|
||||
|
||||
/* The H5AC_NSLOTS #define is now obsolete, as the metadata cache no longer
|
||||
* uses slots. However I am leaving it in for now to avoid modifying the
|
||||
* interface between the metadata cache and the rest of HDF. It should
|
||||
* be removed when we get to dealing with the size_hint parameter in
|
||||
* H5AC_create().
|
||||
* JRM - 5/20/04
|
||||
*
|
||||
* Old comment on H5AC_NSLOTS follows:
|
||||
*
|
||||
* A cache has a certain number of entries. Objects are mapped into a
|
||||
* cache entry by hashing the object's file address. Each file has its
|
||||
* own cache, an array of slots.
|
||||
*/
|
||||
#define H5AC_NSLOTS 10330 /* The library "likes" this number... */
|
||||
|
||||
|
||||
typedef H5C_cache_entry_t H5AC_info_t;
|
||||
|
||||
typedef struct H5AC_class_t {
|
||||
H5AC_subid_t id;
|
||||
H5AC_load_func_t load;
|
||||
H5AC_flush_func_t flush;
|
||||
H5AC_dest_func_t dest;
|
||||
H5AC_clear_func_t clear;
|
||||
} H5AC_class_t;
|
||||
|
||||
/*===----------------------------------------------------------------------===
|
||||
* Protect Types
|
||||
@ -95,27 +106,15 @@ typedef struct H5AC_class_t {
|
||||
* type of operation you're planning on doing to the metadata. The
|
||||
* Flexible Parallel HDF5 locking can then act accordingly.
|
||||
*/
|
||||
|
||||
typedef enum H5AC_protect_t {
|
||||
H5AC_WRITE, /* Protect object for writing */
|
||||
H5AC_READ /* Protect object for reading */
|
||||
} H5AC_protect_t;
|
||||
|
||||
/*
|
||||
* A cache has a certain number of entries. Objects are mapped into a
|
||||
* cache entry by hashing the object's file address. Each file has its
|
||||
* own cache, an array of slots.
|
||||
*/
|
||||
#define H5AC_NSLOTS 10330 /* The library "likes" this number... */
|
||||
|
||||
typedef struct H5AC_info_t {
|
||||
const H5AC_class_t *type; /*type of object stored here */
|
||||
haddr_t addr; /*file address for object */
|
||||
hbool_t dirty; /* 'Dirty' flag for cached object */
|
||||
} H5AC_info_t;
|
||||
typedef H5AC_info_t *H5AC_info_ptr_t; /* Typedef for free lists */
|
||||
|
||||
/* Typedef for metadata cache (defined in H5AC.c) */
|
||||
typedef struct H5AC_t H5AC_t;
|
||||
/* Typedef for metadata cache (defined in H5C.c) */
|
||||
typedef H5C_t H5AC_t;
|
||||
|
||||
/* Metadata specific properties for FAPL */
|
||||
/* (Only used for parallel I/O) */
|
||||
@ -158,9 +157,9 @@ H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, hadd
|
||||
H5_DLL herr_t H5AC_rename(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
|
||||
haddr_t old_addr, haddr_t new_addr);
|
||||
H5_DLL herr_t H5AC_dest(H5F_t *f, hid_t dxpl_id);
|
||||
#ifdef H5AC_DEBUG
|
||||
|
||||
H5_DLL herr_t H5AC_stats(H5F_t *f);
|
||||
#endif /* H5AC_DEBUG */
|
||||
|
||||
|
||||
#endif /* !_H5ACprivate_H */
|
||||
|
||||
|
52
src/H5B.c
52
src/H5B.c
@ -156,6 +156,7 @@ static H5B_t *H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type,
|
||||
static herr_t H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *b);
|
||||
static herr_t H5B_dest(H5F_t *f, H5B_t *b);
|
||||
static herr_t H5B_clear(H5F_t *f, H5B_t *b, hbool_t destroy);
|
||||
static herr_t H5B_compute_size(H5F_t *f, H5B_t *bt, size_t *size_ptr);
|
||||
|
||||
/* H5B inherits cache-like properties from H5AC */
|
||||
static const H5AC_class_t H5AC_BT[1] = {{
|
||||
@ -164,6 +165,7 @@ static const H5AC_class_t H5AC_BT[1] = {{
|
||||
(H5AC_flush_func_t)H5B_flush,
|
||||
(H5AC_dest_func_t)H5B_dest,
|
||||
(H5AC_clear_func_t)H5B_clear,
|
||||
(H5AC_size_func_t)H5B_compute_size,
|
||||
}};
|
||||
|
||||
/* Declare a free list to manage the page information */
|
||||
@ -628,6 +630,56 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5B_clear() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5B_compute_size
|
||||
*
|
||||
* Purpose: Compute the size in bytes of the specified instance of
|
||||
* H5B_t on disk, and return it in *len_ptr. On failure,
|
||||
* the value of *len_ptr is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 5/13/04
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5B_compute_size(H5F_t *f, H5B_t *bt, size_t *size_ptr)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
size_t size;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5B_compute_size, FAIL)
|
||||
|
||||
/* check arguments */
|
||||
HDassert(f);
|
||||
HDassert(bt);
|
||||
HDassert(bt->type);
|
||||
HDassert(size_ptr);
|
||||
|
||||
size = H5B_nodesize(f, bt->type, NULL, bt->sizeof_rkey);
|
||||
|
||||
if ( size == 0 ) {
|
||||
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, \
|
||||
"H5B_nodesize() failed");
|
||||
|
||||
} else {
|
||||
|
||||
*size_ptr = size;
|
||||
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5B_H5B_compute_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5B_find
|
||||
|
374
src/H5Cprivate.h
Normal file
374
src/H5Cprivate.h
Normal file
@ -0,0 +1,374 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Created: H5Cprivate.h
|
||||
* 6/3/04
|
||||
* John Mainzer
|
||||
*
|
||||
* Purpose: Constants and typedefs available to the rest of the
|
||||
* library.
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _H5Cprivate_H
|
||||
#define _H5Cprivate_H
|
||||
|
||||
#include "H5Cpublic.h" /*public prototypes */
|
||||
|
||||
/* Pivate headers needed by this header */
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5Fprivate.h" /* File access */
|
||||
|
||||
#define H5C_DO_SANITY_CHECKS 0
|
||||
|
||||
/* This sanity checking constant was picked out of the air. Increase
|
||||
* or decrease it if appropriate. Its purposes is to detect corrupt
|
||||
* object sizes, so it probably doesn't matter if it is a bit big.
|
||||
*
|
||||
* JRM - 5/17/04
|
||||
*/
|
||||
#define H5C_MAX_ENTRY_SIZE ((size_t)(100 * 1024))
|
||||
|
||||
/* H5C_COLLECT_CACHE_STATS controls overall collection of statistics
|
||||
* on cache activity. In general, this #define should be set to 0.
|
||||
*/
|
||||
#define H5C_COLLECT_CACHE_STATS 0
|
||||
|
||||
/* H5C_COLLECT_CACHE_ENTRY_STATS controls collection of statistics
|
||||
* in individual cache entries.
|
||||
*
|
||||
* H5C_COLLECT_CACHE_ENTRY_STATS should only be defined to true if
|
||||
* H5C_COLLECT_CACHE_STATS is also defined to true.
|
||||
*/
|
||||
#if H5C_COLLECT_CACHE_STATS
|
||||
|
||||
#define H5C_COLLECT_CACHE_ENTRY_STATS 1
|
||||
|
||||
#else
|
||||
|
||||
#define H5C_COLLECT_CACHE_ENTRY_STATS 0
|
||||
|
||||
#endif /* H5C_COLLECT_CACHE_STATS */
|
||||
|
||||
/*
|
||||
* Class methods pertaining to caching. Each type of cached object will
|
||||
* have a constant variable with permanent life-span that describes how
|
||||
* to cache the object. That variable will be of type H5C_class_t and
|
||||
* have the following required fields...
|
||||
*
|
||||
* LOAD: Loads an object from disk to memory. The function
|
||||
* should allocate some data structure and return it.
|
||||
*
|
||||
* FLUSH: Writes some data structure back to disk. It would be
|
||||
* wise for the data structure to include dirty flags to
|
||||
* indicate whether it really needs to be written. This
|
||||
* function is also responsible for freeing memory allocated
|
||||
* by the LOAD method if the DEST argument is non-zero (by
|
||||
* calling the DEST method).
|
||||
*
|
||||
* DEST: Just frees memory allocated by the LOAD method.
|
||||
*
|
||||
* CLEAR: Just marks object as non-dirty.
|
||||
*
|
||||
* SIZE: Report the size (on disk) of the specified cache object.
|
||||
* Note that the space allocated on disk may not be contiguous.
|
||||
*/
|
||||
|
||||
typedef void *(*H5C_load_func_t)(H5F_t *f,
|
||||
hid_t dxpl_id,
|
||||
haddr_t addr,
|
||||
const void *udata1,
|
||||
void *udata2);
|
||||
typedef herr_t (*H5C_flush_func_t)(H5F_t *f,
|
||||
hid_t dxpl_id,
|
||||
hbool_t dest,
|
||||
haddr_t addr,
|
||||
void *thing);
|
||||
typedef herr_t (*H5C_dest_func_t)(H5F_t *f,
|
||||
void *thing);
|
||||
typedef herr_t (*H5C_clear_func_t)(H5F_t *f,
|
||||
void *thing,
|
||||
hbool_t dest);
|
||||
typedef herr_t (*H5C_size_func_t)(H5F_t *f,
|
||||
void *thing,
|
||||
size_t *size_ptr);
|
||||
|
||||
typedef struct H5C_class_t {
|
||||
int id;
|
||||
H5C_load_func_t load;
|
||||
H5C_flush_func_t flush;
|
||||
H5C_dest_func_t dest;
|
||||
H5C_clear_func_t clear;
|
||||
H5C_size_func_t size;
|
||||
} H5C_class_t;
|
||||
|
||||
|
||||
/* Type defintions of call back functions used by the cache as a whole */
|
||||
|
||||
typedef herr_t (*H5C_write_permitted_func_t)(H5F_t *f,
|
||||
hid_t dxpl_id,
|
||||
hbool_t * write_permitted_ptr);
|
||||
|
||||
|
||||
/* Default max cache size and min clean size are give here to make
|
||||
* them generally accessable.
|
||||
*/
|
||||
|
||||
#define H5C__DEFAULT_MAX_CACHE_SIZE ((size_t)(2 * 1024 * 1024))
|
||||
#define H5C__DEFAULT_MIN_CLEAN_SIZE ((size_t)(1 * 1024 * 1024))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* structure H5C_cache_entry_t
|
||||
*
|
||||
* Instances of the H5C_cache_entry_t structure are used to store meta data
|
||||
* cache entries in an a threaded binary B-tree. See H5TB.c for the
|
||||
* particulars of the B-tree.
|
||||
*
|
||||
* In typical application, this structure is the first field in a
|
||||
* structure to be cached. For historical reasons, the external module
|
||||
* is responsible for managing the dirty field. All other fields are
|
||||
* managed by the cache.
|
||||
*
|
||||
* Note that our current implementation of a threaded binary B-tree will
|
||||
* occasionaly change the node a particular datum is associated with. Thus
|
||||
* this structure does not have a back pointer to its B-tree node. If we
|
||||
* ever modify the threaded binary B-tree code to fix this, a back pointer
|
||||
* would save us a few tree traversals.
|
||||
*
|
||||
* The fields of this structure are discussed individually below:
|
||||
*
|
||||
* JRM - 4/26/04
|
||||
*
|
||||
* addr: Base address of the cache entry on disk.
|
||||
*
|
||||
* size: Length of the cache entry on disk. Note that unlike normal
|
||||
* caches, the entries in this cache are of variable length.
|
||||
* The entries should never overlap, and when we do writebacks,
|
||||
* we will want to writeback adjacent entries where possible.
|
||||
*
|
||||
* type: Pointer to the instance of H5C_class_t containing pointers
|
||||
* to the methods for cache entries of the current type. This
|
||||
* field should be NULL when the instance of H5C_cache_entry_t
|
||||
* is not in use.
|
||||
*
|
||||
* The name is not particularly descriptive, but is retained
|
||||
* to avoid changes in existing code.
|
||||
*
|
||||
* dirty: Boolean flag indicating whether the contents of the cache
|
||||
* entry has been modified since the last time it was written
|
||||
* to disk.
|
||||
*
|
||||
* NOTE: For historical reasons, this field is not maintained
|
||||
* by the cache. Instead, the module using the cache
|
||||
* sets this flag when it modifies the entry, and the
|
||||
* flush and clear functions supplied by that module
|
||||
* reset the dirty when appropriate.
|
||||
*
|
||||
* This is a bit quirky, so we may want to change this
|
||||
* someday. However it will require a change in the
|
||||
* cache interface.
|
||||
*
|
||||
* protected: Boolean flag indicating whether this entry is protected
|
||||
* (or locked, to use more conventional terms). When it is
|
||||
* protected, the entry cannot be flushed or accessed until
|
||||
* it is unprotected (or unlocked -- again to use more
|
||||
* conventional terms).
|
||||
*
|
||||
* Note that protected entries are removed from the LRU lists
|
||||
* and inserted on the protected list.
|
||||
*
|
||||
*
|
||||
* Fields supporting replacement policies:
|
||||
*
|
||||
* The cache must have a replacement policy, and it will usually be
|
||||
* necessary for this structure to contain fields supporting that policy.
|
||||
*
|
||||
* While there has been interest in several replacement policies for
|
||||
* this cache, the initial development schedule is tight. Thus I have
|
||||
* elected to support only a modified LRU policy for the first cut.
|
||||
*
|
||||
* When additional replacement policies are added, the fields in this
|
||||
* section will be used in different ways or not at all. Thus the
|
||||
* documentation of these fields is repeated for each replacement policy.
|
||||
*
|
||||
* Modified LRU:
|
||||
*
|
||||
* When operating in parallel mode, we must ensure that a read does not
|
||||
* cause a write. If it does, the process will hang, as the write will
|
||||
* be collective and the other processes will not know to participate.
|
||||
*
|
||||
* To deal with this issue, I have modified the usual LRU policy by adding
|
||||
* clean and dirty LRU lists to the usual LRU list. When reading in
|
||||
* parallel mode, we evict from the clean LRU list only. This implies
|
||||
* that we must try to ensure that the clean LRU list is reasonably well
|
||||
* stocked. See the comments on H5C_t in H5C.c for more details.
|
||||
*
|
||||
* Note that even if we start with a completely clean cache, a sequence
|
||||
* of protects without unprotects can empty the clean LRU list. In this
|
||||
* case, the cache must grow temporarily. At the next write, we will
|
||||
* attempt to evict enough entries to get the cache down to its nominal
|
||||
* maximum size.
|
||||
*
|
||||
* The use of the replacement policy fields under the Modified LRU policy
|
||||
* is discussed below:
|
||||
*
|
||||
* next: Next pointer in either the LRU or the protected list,
|
||||
* depending on the current value of protected. If there
|
||||
* is no next entry on the list, this field should be set
|
||||
* to NULL.
|
||||
*
|
||||
* prev: Prev pointer in either the LRU or the protected list,
|
||||
* depending on the current value of protected. If there
|
||||
* is no previous entry on the list, this field should be
|
||||
* set to NULL.
|
||||
*
|
||||
* aux_next: Next pointer on either the clean or dirty LRU lists.
|
||||
* This entry should be NULL when protected is true. When
|
||||
* protected is false, and dirty is true, it should point
|
||||
* to the next item on the dirty LRU list. When protected
|
||||
* is false, and dirty is false, it should point to the
|
||||
* next item on the clean LRU list. In either case, when
|
||||
* there is no next item, it should be NULL.
|
||||
*
|
||||
* aux_prev: Previous pointer on either the clean or dirty LRU lists.
|
||||
* This entry should be NULL when protected is true. When
|
||||
* protected is false, and dirty is true, it should point
|
||||
* to the previous item on the dirty LRU list. When protected
|
||||
* is false, and dirty is false, it should point to the
|
||||
* previous item on the clean LRU list. In either case, when
|
||||
* there is no previous item, it should be NULL.
|
||||
*
|
||||
*
|
||||
* Cache entry stats collection fields:
|
||||
*
|
||||
* These fields should only be compiled in when both H5C_COLLECT_CACHE_STATS
|
||||
* and H5C_COLLECT_CACHE_ENTRY_STATS are true. When present, they allow
|
||||
* collection of statistics on individual cache entries.
|
||||
*
|
||||
* accesses: int32_t containing the number of times this cache entry has
|
||||
* been referenced in its lifetime.
|
||||
*
|
||||
* clears: int32_t containing the number of times this cache entry has
|
||||
* been cleared in its life time.
|
||||
*
|
||||
* flushes: int32_t containing the number of times this cache entry has
|
||||
* been flushed to file in its life time.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct H5C_cache_entry_t
|
||||
{
|
||||
haddr_t addr;
|
||||
size_t size;
|
||||
const H5C_class_t * type;
|
||||
hbool_t dirty;
|
||||
hbool_t protected;
|
||||
|
||||
/* fields supporting replacement policies: */
|
||||
|
||||
struct H5C_cache_entry_t * next;
|
||||
struct H5C_cache_entry_t * prev;
|
||||
struct H5C_cache_entry_t * aux_next;
|
||||
struct H5C_cache_entry_t * aux_prev;
|
||||
|
||||
#if H5C_COLLECT_CACHE_ENTRY_STATS
|
||||
|
||||
/* cache entry stats fields */
|
||||
|
||||
int32_t accesses;
|
||||
int32_t clears;
|
||||
int32_t flushes;
|
||||
|
||||
#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */
|
||||
|
||||
} H5C_cache_entry_t;
|
||||
|
||||
|
||||
/* Typedef for the main structure for the cache (defined in H5C.c) */
|
||||
|
||||
typedef struct H5C_t H5C_t;
|
||||
|
||||
/*
|
||||
* Library prototypes.
|
||||
*/
|
||||
H5_DLL H5C_t * H5C_create(size_t max_cache_size,
|
||||
size_t min_clean_size,
|
||||
int max_type_id,
|
||||
const char * (* type_name_table_ptr)[],
|
||||
H5C_write_permitted_func_t check_write_permitted);
|
||||
|
||||
H5_DLL herr_t H5C_dest(H5F_t * f,
|
||||
hid_t primary_dxpl_id,
|
||||
hid_t secondary_dxpl_id,
|
||||
H5C_t * cache_ptr);
|
||||
|
||||
H5_DLL herr_t H5C_dest_empty(H5C_t * cache_ptr);
|
||||
|
||||
H5_DLL herr_t H5C_flush_cache(H5F_t * f,
|
||||
hid_t primary_dxpl_id,
|
||||
hid_t secondary_dxpl_id,
|
||||
H5C_t * cache_ptr,
|
||||
unsigned flags);
|
||||
|
||||
H5_DLL herr_t H5C_insert_entry(H5F_t * f,
|
||||
hid_t primary_dxpl_id,
|
||||
hid_t secondary_dxpl_id,
|
||||
H5C_t * cache_ptr,
|
||||
const H5C_class_t * type,
|
||||
haddr_t addr,
|
||||
void * thing);
|
||||
|
||||
H5_DLL herr_t H5C_rename_entry(H5F_t * f,
|
||||
H5C_t * cache_ptr,
|
||||
const H5C_class_t * type,
|
||||
haddr_t old_addr,
|
||||
haddr_t new_addr);
|
||||
|
||||
H5_DLL void * H5C_protect(H5F_t * f,
|
||||
hid_t primary_dxpl_id,
|
||||
hid_t secondary_dxpl_id,
|
||||
H5C_t * cache_ptr,
|
||||
const H5C_class_t * type,
|
||||
haddr_t addr,
|
||||
const void * udata1,
|
||||
void * udata2);
|
||||
|
||||
H5_DLL herr_t H5C_unprotect(H5F_t * f,
|
||||
hid_t primary_dxpl_id,
|
||||
hid_t secondary_dxpl_id,
|
||||
H5C_t * cache_ptr,
|
||||
const H5C_class_t * type,
|
||||
haddr_t addr,
|
||||
void * thing,
|
||||
hbool_t deleted);
|
||||
|
||||
H5_DLL herr_t H5C_stats(H5C_t * cache_ptr,
|
||||
const char * cache_name,
|
||||
hbool_t display_detailed_stats);
|
||||
|
||||
void H5C_stats__reset(H5C_t * cache_ptr);
|
||||
|
||||
H5_DLL herr_t H5C_set_skip_flags(H5C_t * cache_ptr,
|
||||
hbool_t skip_file_checks,
|
||||
hbool_t skip_dxpl_id_checks);
|
||||
|
||||
#endif /* !_H5Cprivate_H */
|
||||
|
40
src/H5Cpublic.h
Normal file
40
src/H5Cpublic.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Created: H5Cproto.h
|
||||
* June 4, 2005
|
||||
* John Mainzer
|
||||
*
|
||||
* Purpose: Public include file for cache functions.
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef _H5Cpublic_H
|
||||
#define _H5Cpublic_H
|
||||
|
||||
/* Public headers needed by this file */
|
||||
#include "H5public.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
29
src/H5E.c
29
src/H5E.c
@ -120,6 +120,35 @@ static herr_t H5E_walk_cb(unsigned n, const H5E_error_t *err_desc, void *client
|
||||
static herr_t H5E_get_auto(const H5E_t *estack, H5E_auto_t *func, void **client_data);
|
||||
static herr_t H5E_set_auto(H5E_t *estack, H5E_auto_t func, void *client_data);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5E_init
|
||||
*
|
||||
* Purpose: Initialize the interface from some other layer.
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
*
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, June 29, 2004
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5E_init(void)
|
||||
{
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5E_init, FAIL)
|
||||
/* FUNC_ENTER() does all the work */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Function: H5E_init_interface
|
||||
*
|
||||
|
@ -90,8 +90,7 @@ hid_t H5E_NOFILTER_g = FAIL; /* Requested filter is not available */
|
||||
hid_t H5E_CALLBACK_g = FAIL; /* Callback failed */
|
||||
hid_t H5E_CANAPPLY_g = FAIL; /* Error from filter 'can apply' callback */
|
||||
hid_t H5E_SETLOCAL_g = FAIL; /* Error from filter 'set local' callback */
|
||||
hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoder not enabled */
|
||||
hid_t H5E_NODECODER_g = FAIL; /* Filter present but decoder not enabled */
|
||||
hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled */
|
||||
|
||||
/* Datatype conversion errors */
|
||||
hid_t H5E_CANTCONVERT_g = FAIL; /* Can't convert datatypes */
|
||||
@ -116,6 +115,7 @@ hid_t H5E_ALREADYEXISTS_g = FAIL; /* Object already exists */
|
||||
hid_t H5E_CANTLOCK_g = FAIL; /* Unable to lock object */
|
||||
hid_t H5E_CANTUNLOCK_g = FAIL; /* Unable to unlock object */
|
||||
hid_t H5E_CANTGC_g = FAIL; /* Unable to garbage collect */
|
||||
hid_t H5E_CANTGETSIZE_g = FAIL; /* Unable to compute size */
|
||||
|
||||
/* Generic low-level file I/O errors */
|
||||
hid_t H5E_SEEKERROR_g = FAIL; /* Seek failed */
|
||||
@ -151,6 +151,11 @@ hid_t H5E_CANTSERIALIZE_g = FAIL; /* Unable to serialize data from cache *
|
||||
hid_t H5E_CANTLOAD_g = FAIL; /* Unable to load metadata into cache */
|
||||
hid_t H5E_PROTECT_g = FAIL; /* Protected metadata error */
|
||||
hid_t H5E_NOTCACHED_g = FAIL; /* Metadata not currently cached */
|
||||
hid_t H5E_SYSTEM_g = FAIL; /* Internal error detected */
|
||||
hid_t H5E_CANTINS_g = FAIL; /* Unable to insert metadata into cache */
|
||||
hid_t H5E_CANTRENAME_g = FAIL; /* Unable to rename metadata */
|
||||
hid_t H5E_CANTPROTECT_g = FAIL; /* Unable to protect metadata */
|
||||
hid_t H5E_CANTUNPROTECT_g = FAIL; /* Unable to unprotect metadata */
|
||||
|
||||
/* Group related errors */
|
||||
hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */
|
||||
|
@ -321,15 +321,10 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'set local' callback
|
||||
if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_NOENCODER_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'no encoder' callback"))==NULL)
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter present but encoding disabled"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_NODECODER_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'no decoder' callback"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_NODECODER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
|
||||
/* Datatype conversion errors */
|
||||
assert(H5E_CANTCONVERT_g==(-1));
|
||||
@ -418,6 +413,11 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to garbage collect"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_CANTGC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_CANTGETSIZE_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to compute size"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_CANTGETSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
|
||||
/* Generic low-level file I/O errors */
|
||||
assert(H5E_SEEKERROR_g==(-1));
|
||||
@ -561,6 +561,31 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Metadata not currently cached"))==NULL
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_NOTCACHED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_SYSTEM_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Internal error detected"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_SYSTEM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_CANTINS_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert metadata into cache"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_CANTINS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_CANTRENAME_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to rename metadata"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_CANTRENAME_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_CANTPROTECT_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to protect metadata"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_CANTPROTECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
assert(H5E_CANTUNPROTECT_g==(-1));
|
||||
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to unprotect metadata"))==NULL)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
|
||||
if((H5E_CANTUNPROTECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
|
||||
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
|
||||
|
||||
/* Group related errors */
|
||||
assert(H5E_CANTOPENOBJ_g==(-1));
|
||||
|
@ -108,6 +108,7 @@ typedef struct H5E_print_t {
|
||||
#define HGOTO_DONE(ret_val) {ret_value = ret_val; goto done;}
|
||||
|
||||
/* Library-private functions defined in H5E package */
|
||||
H5_DLL herr_t H5E_init(void);
|
||||
H5_DLL herr_t H5E_push(H5E_t *estack, const char *file, const char *func, unsigned line,
|
||||
hid_t cls_id, hid_t maj_id, hid_t min_id, const char *desc);
|
||||
H5_DLL herr_t H5E_clear(H5E_t *estack);
|
||||
|
@ -147,14 +147,12 @@ H5_DLLVAR hid_t H5E_CANTALLOC_g; /* Can't allocate from file */
|
||||
#define H5E_CALLBACK (H5OPEN H5E_CALLBACK_g)
|
||||
#define H5E_CANAPPLY (H5OPEN H5E_CANAPPLY_g)
|
||||
#define H5E_SETLOCAL (H5OPEN H5E_SETLOCAL_g)
|
||||
#define H5E_NOENCODER (H5OPEN H5E_NOENCODER_g)
|
||||
#define H5E_NODECODER (H5OPEN H5E_NODECODER_g)
|
||||
#define H5E_NOENCODER (H5OPEN H5E_NOENCODER_g)
|
||||
H5_DLLVAR hid_t H5E_NOFILTER_g; /* Requested filter is not available */
|
||||
H5_DLLVAR hid_t H5E_CALLBACK_g; /* Callback failed */
|
||||
H5_DLLVAR hid_t H5E_CANAPPLY_g; /* Error from filter 'can apply' callback */
|
||||
H5_DLLVAR hid_t H5E_SETLOCAL_g; /* Error from filter 'set local' callback */
|
||||
H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present, but encoding disabled */
|
||||
H5_DLLVAR hid_t H5E_NODECODER_g; /* Filter present, but decoding disabled */
|
||||
H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present but encoding disabled */
|
||||
|
||||
/* Datatype conversion errors */
|
||||
#define H5E_CANTCONVERT (H5OPEN H5E_CANTCONVERT_g)
|
||||
@ -188,6 +186,7 @@ H5_DLLVAR hid_t H5E_CANTDELETE_g; /* Can't delete message */
|
||||
#define H5E_CANTLOCK (H5OPEN H5E_CANTLOCK_g)
|
||||
#define H5E_CANTUNLOCK (H5OPEN H5E_CANTUNLOCK_g)
|
||||
#define H5E_CANTGC (H5OPEN H5E_CANTGC_g)
|
||||
#define H5E_CANTGETSIZE (H5OPEN H5E_CANTGETSIZE_g)
|
||||
H5_DLLVAR hid_t H5E_NOSPACE_g; /* No space available for allocation */
|
||||
H5_DLLVAR hid_t H5E_CANTCOPY_g; /* Unable to copy object */
|
||||
H5_DLLVAR hid_t H5E_CANTFREE_g; /* Unable to free object */
|
||||
@ -195,6 +194,7 @@ H5_DLLVAR hid_t H5E_ALREADYEXISTS_g;/* Object already exists */
|
||||
H5_DLLVAR hid_t H5E_CANTLOCK_g; /* Unable to lock object */
|
||||
H5_DLLVAR hid_t H5E_CANTUNLOCK_g; /* Unable to unlock object */
|
||||
H5_DLLVAR hid_t H5E_CANTGC_g; /* Unable to garbage collect */
|
||||
H5_DLLVAR hid_t H5E_CANTGETSIZE_g; /* Unable to compute size */
|
||||
|
||||
/* Generic low-level file I/O errors */
|
||||
#define H5E_SEEKERROR (H5OPEN H5E_SEEKERROR_g)
|
||||
@ -252,11 +252,21 @@ H5_DLLVAR hid_t H5E_MOUNT_g; /* File mount error */
|
||||
#define H5E_CANTLOAD (H5OPEN H5E_CANTLOAD_g)
|
||||
#define H5E_PROTECT (H5OPEN H5E_PROTECT_g)
|
||||
#define H5E_NOTCACHED (H5OPEN H5E_NOTCACHED_g)
|
||||
#define H5E_SYSTEM (H5OPEN H5E_SYSTEM_g)
|
||||
#define H5E_CANTINS (H5OPEN H5E_CANTINS_g)
|
||||
#define H5E_CANTRENAME (H5OPEN H5E_CANTRENAME_g)
|
||||
#define H5E_CANTPROTECT (H5OPEN H5E_CANTPROTECT_g)
|
||||
#define H5E_CANTUNPROTECT (H5OPEN H5E_CANTUNPROTECT_g)
|
||||
H5_DLLVAR hid_t H5E_CANTFLUSH_g; /* Unable to flush data from cache */
|
||||
H5_DLLVAR hid_t H5E_CANTSERIALIZE_g;/* Unable to serialize data from cache */
|
||||
H5_DLLVAR hid_t H5E_CANTLOAD_g; /* Unable to load metadata into cache */
|
||||
H5_DLLVAR hid_t H5E_PROTECT_g; /* Protected metadata error */
|
||||
H5_DLLVAR hid_t H5E_NOTCACHED_g; /* Metadata not currently cached */
|
||||
H5_DLLVAR hid_t H5E_SYSTEM_g; /* Internal error detected */
|
||||
H5_DLLVAR hid_t H5E_CANTINS_g; /* Unable to insert metadata into cache */
|
||||
H5_DLLVAR hid_t H5E_CANTRENAME_g; /* Unable to rename metadata */
|
||||
H5_DLLVAR hid_t H5E_CANTPROTECT_g; /* Unable to protect metadata */
|
||||
H5_DLLVAR hid_t H5E_CANTUNPROTECT_g;/* Unable to unprotect metadata */
|
||||
|
||||
/* Group related errors */
|
||||
#define H5E_CANTOPENOBJ (H5OPEN H5E_CANTOPENOBJ_g)
|
||||
|
@ -91,9 +91,8 @@ H5E_CANTALLOC_g=
|
||||
H5E_NOFILTER_g=
|
||||
H5E_CALLBACK_g=
|
||||
H5E_CANAPPLY_g=
|
||||
H5E_SETLOCAL_g=
|
||||
H5E_SETLOCAL_g=
|
||||
H5E_NOENCODER_g=
|
||||
H5E_NODECODER_g=
|
||||
|
||||
/* Datatype conversion errors */
|
||||
H5E_CANTCONVERT_g=
|
||||
@ -117,7 +116,8 @@ H5E_CANTFREE_g=
|
||||
H5E_ALREADYEXISTS_g=
|
||||
H5E_CANTLOCK_g=
|
||||
H5E_CANTUNLOCK_g=
|
||||
H5E_CANTGC_g=
|
||||
H5E_CANTGC_g=
|
||||
H5E_CANTGETSIZE_g=
|
||||
|
||||
/* Generic low-level file I/O errors */
|
||||
H5E_SEEKERROR_g=
|
||||
@ -152,7 +152,12 @@ H5E_CANTFLUSH_g=
|
||||
H5E_CANTSERIALIZE_g=
|
||||
H5E_CANTLOAD_g=
|
||||
H5E_PROTECT_g=
|
||||
H5E_NOTCACHED_g=
|
||||
H5E_NOTCACHED_g=
|
||||
H5E_SYSTEM_g=
|
||||
H5E_CANTINS_g=
|
||||
H5E_CANTRENAME_g=
|
||||
H5E_CANTPROTECT_g=
|
||||
H5E_CANTUNPROTECT_g=
|
||||
|
||||
/* Group related errors */
|
||||
H5E_CANTOPENOBJ_g=
|
||||
|
@ -1838,6 +1838,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
* We've just opened a fresh new file (or truncated one). We need
|
||||
* to create & write the superblock.
|
||||
*/
|
||||
|
||||
#ifdef H5_HAVE_FPHDF5
|
||||
if (!H5FD_is_fphdf5_driver(lf) || H5FD_fphdf5_is_captain(lf)) {
|
||||
#endif /* H5_HAVE_FPHDF5 */
|
||||
@ -1979,7 +1980,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
if(fc_degree!=H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match")
|
||||
}
|
||||
|
||||
|
||||
/* Success */
|
||||
ret_value = file;
|
||||
|
||||
@ -1987,6 +1988,7 @@ done:
|
||||
if (!ret_value && file)
|
||||
if(H5F_dest(file, dxpl_id)<0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
@ -3272,9 +3274,9 @@ H5F_close(H5F_t *f)
|
||||
/* Only flush at this point if the file will be closed */
|
||||
assert(closing);
|
||||
/* Dump debugging info */
|
||||
#ifdef H5AC_DEBUG
|
||||
#if H5C_COLLECT_CACHE_STATS
|
||||
H5AC_stats(f);
|
||||
#endif /* H5AC_DEBUG */
|
||||
#endif /* H5AC_COLLECT_CACHE_STATS */
|
||||
|
||||
/* Only try to flush the file if it was opened with write access */
|
||||
if(f->intent&H5F_ACC_RDWR) {
|
||||
|
@ -72,6 +72,7 @@ static herr_t H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t a
|
||||
H5G_node_t *sym);
|
||||
static herr_t H5G_node_dest(H5F_t *f, H5G_node_t *sym);
|
||||
static herr_t H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy);
|
||||
static herr_t H5G_compute_size(H5F_t *f, H5G_node_t *sym, size_t *size_ptr);
|
||||
|
||||
/* B-tree callbacks */
|
||||
static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *_udata);
|
||||
@ -107,6 +108,7 @@ const H5AC_class_t H5AC_SNODE[1] = {{
|
||||
(H5AC_flush_func_t)H5G_node_flush,
|
||||
(H5AC_dest_func_t)H5G_node_dest,
|
||||
(H5AC_clear_func_t)H5G_node_clear,
|
||||
(H5AC_size_func_t)H5G_compute_size,
|
||||
}};
|
||||
|
||||
/* H5G inherits B-tree like properties from H5B */
|
||||
@ -617,6 +619,43 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* end H5G_node_clear() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_compute_size
|
||||
*
|
||||
* Purpose: Compute the size in bytes of the specified instance of
|
||||
* H5G_node_t on disk, and return it in *size_ptr. On failure
|
||||
* the value of size_ptr is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 5/13/04
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5G_compute_size(H5F_t *f, H5G_node_t UNUSED *sym, size_t *size_ptr)
|
||||
{
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5G_compute_size, FAIL);
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
assert(f);
|
||||
assert(size_ptr);
|
||||
|
||||
*size_ptr = H5G_node_size(f);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
|
||||
} /* H5G_compute_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_node_create
|
||||
|
187
src/H5HG.c
187
src/H5HG.c
@ -120,7 +120,7 @@
|
||||
/* Private typedefs */
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static H5HG_heap_t *H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size);
|
||||
static haddr_t H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size);
|
||||
#ifdef NOT_YET
|
||||
static void *H5HG_peek(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj);
|
||||
#endif /* NOT_YET */
|
||||
@ -132,6 +132,7 @@ static herr_t H5HG_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
|
||||
H5HG_heap_t *heap);
|
||||
static herr_t H5HG_dest(H5F_t *f, H5HG_heap_t *heap);
|
||||
static herr_t H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy);
|
||||
static herr_t H5HG_compute_size(H5F_t *f, H5HG_heap_t *heap, size_t *size_ptr);
|
||||
|
||||
/*
|
||||
* H5HG inherits cache-like properties from H5AC
|
||||
@ -142,6 +143,7 @@ const H5AC_class_t H5AC_GHEAP[1] = {{
|
||||
(H5AC_flush_func_t)H5HG_flush,
|
||||
(H5AC_dest_func_t)H5HG_dest,
|
||||
(H5AC_clear_func_t)H5HG_clear,
|
||||
(H5AC_size_func_t)H5HG_compute_size,
|
||||
}};
|
||||
|
||||
/* Declare a free list to manage the H5HG_t struct */
|
||||
@ -173,18 +175,27 @@ H5FL_BLK_DEFINE_STATIC(heap_chunk);
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
* John Mainzer 5/26/04
|
||||
* Modified function to return the disk address of the new
|
||||
* global heap collection, or HADDR_UNDEF on failure. This
|
||||
* is necessary, as in some cases (i.e. flexible parallel)
|
||||
* H5AC_set() will imediately flush and destroy the in memory
|
||||
* version of the new collection. For the same reason, I
|
||||
* moved the code which places the new collection on the cwfs
|
||||
* list to just before the call to H5AC_set().
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5HG_heap_t *
|
||||
static haddr_t
|
||||
H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size)
|
||||
{
|
||||
H5HG_heap_t *heap = NULL;
|
||||
H5HG_heap_t *ret_value = NULL;
|
||||
haddr_t ret_value = HADDR_UNDEF;
|
||||
uint8_t *p = NULL;
|
||||
haddr_t addr;
|
||||
size_t n;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5HG_create, NULL);
|
||||
FUNC_ENTER_NOAPI(H5HG_create, HADDR_UNDEF);
|
||||
|
||||
/* Check args */
|
||||
assert (f);
|
||||
@ -194,19 +205,24 @@ H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size)
|
||||
|
||||
/* Create it */
|
||||
H5_CHECK_OVERFLOW(size,size_t,hsize_t);
|
||||
if (HADDR_UNDEF==(addr=H5MF_alloc(f, H5FD_MEM_GHEAP, dxpl_id, (hsize_t)size)))
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, NULL, "unable to allocate file space for global heap");
|
||||
if ( HADDR_UNDEF==
|
||||
(addr=H5MF_alloc(f, H5FD_MEM_GHEAP, dxpl_id, (hsize_t)size)))
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, \
|
||||
"unable to allocate file space for global heap");
|
||||
if (NULL==(heap = H5FL_MALLOC (H5HG_heap_t)))
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
|
||||
"memory allocation failed");
|
||||
heap->addr = addr;
|
||||
heap->size = size;
|
||||
heap->cache_info.dirty = TRUE;
|
||||
if (NULL==(heap->chunk = H5FL_BLK_MALLOC (heap_chunk,size)))
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
|
||||
"memory allocation failed");
|
||||
heap->nalloc = H5HG_NOBJS (f, size);
|
||||
heap->next_idx = 1; /* skip index 0, which is used for the free object */
|
||||
if (NULL==(heap->obj = H5FL_SEQ_MALLOC (H5HG_obj_t,heap->nalloc)))
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
|
||||
"memory allocation failed");
|
||||
|
||||
/* Initialize the header */
|
||||
HDmemcpy (heap->chunk, H5HG_MAGIC, H5HG_SIZEOF_MAGIC);
|
||||
@ -243,32 +259,42 @@ H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size)
|
||||
HDmemset (p, 0, (size_t)((heap->chunk+heap->size) - p));
|
||||
#endif /* OLD_WAY */
|
||||
|
||||
/* Add the heap to the cache */
|
||||
if (H5AC_set (f, dxpl_id, H5AC_GHEAP, addr, heap)<0)
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, NULL, "unable to cache global heap collection");
|
||||
|
||||
/* Add this heap to the beginning of the CWFS list */
|
||||
if (NULL==f->shared->cwfs) {
|
||||
f->shared->cwfs = H5MM_malloc (H5HG_NCWFS * sizeof(H5HG_heap_t*));
|
||||
if (NULL==(f->shared->cwfs))
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
|
||||
"memory allocation failed");
|
||||
f->shared->cwfs[0] = heap;
|
||||
f->shared->ncwfs = 1;
|
||||
} else {
|
||||
HDmemmove (f->shared->cwfs+1, f->shared->cwfs, MIN (f->shared->ncwfs, H5HG_NCWFS-1)*sizeof(H5HG_heap_t*));
|
||||
HDmemmove (f->shared->cwfs+1, f->shared->cwfs,
|
||||
MIN (f->shared->ncwfs, H5HG_NCWFS-1)*sizeof(H5HG_heap_t*));
|
||||
f->shared->cwfs[0] = heap;
|
||||
f->shared->ncwfs = MIN (H5HG_NCWFS, f->shared->ncwfs+1);
|
||||
}
|
||||
|
||||
ret_value = heap;
|
||||
/* Add the heap to the cache */
|
||||
if (H5AC_set (f, dxpl_id, H5AC_GHEAP, addr, heap)<0)
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, \
|
||||
"unable to cache global heap collection");
|
||||
|
||||
ret_value = addr;
|
||||
|
||||
done:
|
||||
if (!ret_value && heap) {
|
||||
if(H5HG_dest(f,heap)<0)
|
||||
HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy global heap collection");
|
||||
|
||||
if ( ( ! ( H5F_addr_defined(addr) ) ) && ( heap ) ) {
|
||||
|
||||
if ( H5HG_dest(f,heap) < 0 ) {
|
||||
|
||||
HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, HADDR_UNDEF, \
|
||||
"unable to destroy global heap collection");
|
||||
}
|
||||
}
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
}
|
||||
|
||||
} /* H5HG_create() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -586,6 +612,41 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5HG_clear() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5HG_compute_size
|
||||
*
|
||||
* Purpose: Compute the size in bytes of the specified instance of
|
||||
* H5HG_heap_t on disk, and return it in *len_ptr. On failure,
|
||||
* the value of *len_ptr is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 5/13/04
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5HG_compute_size(H5F_t UNUSED *f, H5HG_heap_t *heap, size_t *size_ptr)
|
||||
{
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5HG_compute_size, FAIL);
|
||||
|
||||
/* Check arguments */
|
||||
HDassert(heap);
|
||||
HDassert(size_ptr);
|
||||
|
||||
*size_ptr = heap->size;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
|
||||
} /* H5HG_compute_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5HG_alloc
|
||||
@ -816,6 +877,23 @@ done:
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
* John Mainzer -- 5/24/04
|
||||
* The function used to modify the heap without protecting
|
||||
* the relevant collection first. I did a half assed job
|
||||
* of fixing the problem, which should hold until we try to
|
||||
* support multi-threading. At that point it will have to
|
||||
* be done right.
|
||||
*
|
||||
* See in line comment of this date for more details.
|
||||
*
|
||||
* John Mainzer - 5/26/04
|
||||
* Modified H5HG_create() to return the disk address of the
|
||||
* new collection, instead of the address of its
|
||||
* representation in core. This was necessary as in FP
|
||||
* mode, the cache will immediately flush and destroy any
|
||||
* entry inserted in it via H5AC_set(). I then modified
|
||||
* this function to account for the change in H5HG_create().
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
@ -824,6 +902,7 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
|
||||
size_t need; /*total space needed for object */
|
||||
int cwfsno;
|
||||
unsigned idx;
|
||||
haddr_t addr = HADDR_UNDEF;
|
||||
H5HG_heap_t *heap = NULL;
|
||||
hbool_t found=0; /* Flag to indicate a heap with enough space was found */
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
@ -840,8 +919,36 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
|
||||
|
||||
/* Find a large enough collection on the CWFS list */
|
||||
need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size);
|
||||
|
||||
/* Note that we don't have metadata cache locks on the entries in
|
||||
* f->shared->cwfs.
|
||||
*
|
||||
* In the current situation, this doesn't matter, as we are single
|
||||
* threaded, and as best I can tell, entries are added to and deleted
|
||||
* from f->shared->cwfs as they are added to and deleted from the
|
||||
* metadata cache.
|
||||
*
|
||||
* To be proper, we should either lock each entry in f->shared->cwfs
|
||||
* as we examine it, or lock the whole array. However, at present
|
||||
* I don't see the point as there will be significant overhead,
|
||||
* and protecting and unprotecting all the collections in the global
|
||||
* heap on a regular basis will skew the replacement policy.
|
||||
*
|
||||
* However, there is a bigger issue -- as best I can tell, we only look
|
||||
* for free space in global heap chunks that are in cache. If we can't
|
||||
* find any, we allocate a new chunk. This may be a problem in FP mode,
|
||||
* as the metadata cache is disabled. Do we allocate a new heap
|
||||
* collection for every entry in this case?
|
||||
*
|
||||
* Note that all this comes from a cursory read of the source. Don't
|
||||
* take any of it as gospel.
|
||||
* JRM - 5/24/04
|
||||
*/
|
||||
|
||||
for (cwfsno=0; cwfsno<f->shared->ncwfs; cwfsno++) {
|
||||
if (f->shared->cwfs[cwfsno]->obj[0].size>=need) {
|
||||
|
||||
addr = f->shared->cwfs[cwfsno]->addr;
|
||||
found=1;
|
||||
break;
|
||||
} /* end if */
|
||||
@ -856,6 +963,7 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
|
||||
if((f->shared->cwfs[cwfsno]->size+need)<=H5HG_MAXSIZE && H5MF_can_extend(f,H5FD_MEM_GHEAP,f->shared->cwfs[cwfsno]->addr,(hsize_t)f->shared->cwfs[cwfsno]->size,(hsize_t)need)) {
|
||||
if(H5HG_extend(f,f->shared->cwfs[cwfsno],size)<0)
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, "unable to extend global heap collection");
|
||||
addr = f->shared->cwfs[cwfsno]->addr;
|
||||
found=1;
|
||||
break;
|
||||
} /* end if */
|
||||
@ -866,19 +974,23 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
|
||||
* If we didn't find any collection with enough free space then allocate a
|
||||
* new collection large enough for the message plus the collection header.
|
||||
*/
|
||||
|
||||
if (!found) {
|
||||
if (NULL==(heap=H5HG_create (f, dxpl_id, need+H5HG_SIZEOF_HDR (f))))
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, "unable to allocate a global heap collection");
|
||||
assert (f->shared->ncwfs>0);
|
||||
assert (f->shared->cwfs[0]==heap);
|
||||
assert (f->shared->cwfs[0]->obj[0].size >= need);
|
||||
|
||||
addr = H5HG_create(f, dxpl_id, need+H5HG_SIZEOF_HDR (f));
|
||||
|
||||
if ( ! ( H5F_addr_defined(addr) ) ) {
|
||||
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, \
|
||||
"unable to allocate a global heap collection");
|
||||
}
|
||||
cwfsno = 0;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Found a heap with enough space */
|
||||
heap = f->shared->cwfs[cwfsno];
|
||||
|
||||
/* Move the collection forward in the CWFS list, if it's not already at the front */
|
||||
/* Move the collection forward in the CWFS list, if it's not
|
||||
* already at the front
|
||||
*/
|
||||
if (cwfsno>0) {
|
||||
H5HG_heap_t *tmp = f->shared->cwfs[cwfsno];
|
||||
f->shared->cwfs[cwfsno] = f->shared->cwfs[cwfsno-1];
|
||||
@ -886,7 +998,15 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
|
||||
--cwfsno;
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
|
||||
HDassert(H5F_addr_defined(addr));
|
||||
|
||||
if ( NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP,
|
||||
addr, NULL, NULL, H5AC_WRITE)) ) {
|
||||
|
||||
HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
|
||||
}
|
||||
|
||||
/* Split the free space to make room for the new object */
|
||||
idx = H5HG_alloc (f, heap, size);
|
||||
assert (idx>0);
|
||||
@ -907,8 +1027,17 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
|
||||
hobj->idx = idx;
|
||||
|
||||
done:
|
||||
|
||||
if ( heap &&
|
||||
H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, heap->addr, heap, FALSE)
|
||||
!= SUCCEED ) {
|
||||
|
||||
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to unprotect heap.");
|
||||
}
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
}
|
||||
|
||||
} /* H5HG_insert() */
|
||||
|
||||
#ifdef NOT_YET
|
||||
|
||||
|
38
src/H5HL.c
38
src/H5HL.c
@ -72,6 +72,7 @@ static H5HL_t *H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udat
|
||||
static herr_t H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, H5HL_t *heap);
|
||||
static herr_t H5HL_dest(H5F_t *f, H5HL_t *heap);
|
||||
static herr_t H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy);
|
||||
static herr_t H5HL_compute_size(H5F_t *f, H5HL_t *heap, size_t *size_ptr);
|
||||
|
||||
/*
|
||||
* H5HL inherits cache-like properties from H5AC
|
||||
@ -82,6 +83,7 @@ const H5AC_class_t H5AC_LHEAP[1] = {{
|
||||
(H5AC_flush_func_t)H5HL_flush,
|
||||
(H5AC_dest_func_t)H5HL_dest,
|
||||
(H5AC_clear_func_t)H5HL_clear,
|
||||
(H5AC_size_func_t)H5HL_compute_size,
|
||||
}};
|
||||
|
||||
/* Declare a free list to manage the H5HL_free_t struct */
|
||||
@ -667,6 +669,42 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* end H5HL_clear() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5HL_compute_size
|
||||
*
|
||||
* Purpose: Compute the size in bytes of the specified instance of
|
||||
* H5HL_t on disk, and return it in *len_ptr. On failure,
|
||||
* the value of *len_ptr is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 5/13/04
|
||||
*
|
||||
* Modifications:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5HL_compute_size(H5F_t *f, H5HL_t *heap, size_t *size_ptr)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5HL_compute_size, FAIL);
|
||||
|
||||
/* check arguments */
|
||||
HDassert(f);
|
||||
HDassert(heap);
|
||||
HDassert(size_ptr);
|
||||
|
||||
*size_ptr = H5HL_SIZEOF_HDR(f) + heap->disk_alloc;
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5HL_compute_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5HL_read
|
||||
|
56
src/H5O.c
56
src/H5O.c
@ -91,6 +91,7 @@ static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata
|
||||
static herr_t H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh);
|
||||
static herr_t H5O_dest(H5F_t *f, H5O_t *oh);
|
||||
static herr_t H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy);
|
||||
static herr_t H5O_compute_size(H5F_t *f, H5O_t *oh, size_t *size_ptr);
|
||||
|
||||
/* H5O inherits cache-like properties from H5AC */
|
||||
static const H5AC_class_t H5AC_OHDR[1] = {{
|
||||
@ -99,6 +100,7 @@ static const H5AC_class_t H5AC_OHDR[1] = {{
|
||||
(H5AC_flush_func_t)H5O_flush,
|
||||
(H5AC_dest_func_t)H5O_dest,
|
||||
(H5AC_clear_func_t)H5O_clear,
|
||||
(H5AC_size_func_t)H5O_compute_size,
|
||||
}};
|
||||
|
||||
/* ID to type mapping */
|
||||
@ -891,6 +893,60 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* end H5O_clear() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_compute_size
|
||||
*
|
||||
* Purpose: Compute the size in bytes of the specified instance of
|
||||
* H5O_t on disk, and return it in *len_ptr. On failure,
|
||||
* the value of *len_ptr is undefined.
|
||||
*
|
||||
* The value returned will probably be low unless the object
|
||||
* has just been flushed, as we simply total up the size of
|
||||
* the header with the sizes of the chunks. Thus any message
|
||||
* that has been added since the last flush will not be
|
||||
* reflected in the total.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 5/13/04
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5O_compute_size(H5F_t *f, H5O_t *oh, size_t *size_ptr)
|
||||
{
|
||||
unsigned u;
|
||||
size_t size;
|
||||
herr_t ret_value=SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_compute_size, FAIL);
|
||||
|
||||
/* check args */
|
||||
HDassert(f);
|
||||
HDassert(oh);
|
||||
HDassert(size_ptr);
|
||||
|
||||
size = H5O_SIZEOF_HDR(f);
|
||||
|
||||
for (u = 0; u < oh->nchunks; u++)
|
||||
{
|
||||
size += oh->chunk[u].size;
|
||||
}
|
||||
|
||||
HDassert(size >= H5O_SIZEOF_HDR(f));
|
||||
|
||||
*size_ptr = size;
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
|
||||
} /* H5O_compute_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_reset
|
||||
|
@ -883,7 +883,8 @@ H5Pget_filter_by_id(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/,
|
||||
name);
|
||||
|
||||
/* Check args */
|
||||
if (cd_nelmts || cd_values) {
|
||||
if (cd_nelmts || cd_values)
|
||||
{
|
||||
if (cd_nelmts && *cd_nelmts>256)
|
||||
/*
|
||||
* It's likely that users forget to initialize this on input, so
|
||||
|
@ -107,6 +107,7 @@ MINOR, RESOURCE, H5E_ALREADYEXISTS, Object already exists
|
||||
MINOR, RESOURCE, H5E_CANTLOCK, Unable to lock object
|
||||
MINOR, RESOURCE, H5E_CANTUNLOCK, Unable to unlock object
|
||||
MINOR, RESOURCE, H5E_CANTGC, Unable to garbage collect
|
||||
MINOR, RESOURCE, H5E_CANTGETSIZE, Unable to compute size
|
||||
|
||||
# File accessability errors
|
||||
MINOR, FILEACC, H5E_FILEEXISTS, File already exists
|
||||
@ -146,6 +147,11 @@ MINOR, CACHE, H5E_CANTSERIALIZE, Unable to serialize data from cache
|
||||
MINOR, CACHE, H5E_CANTLOAD, Unable to load metadata into cache
|
||||
MINOR, CACHE, H5E_PROTECT, Protected metadata error
|
||||
MINOR, CACHE, H5E_NOTCACHED, Metadata not currently cached
|
||||
MINOR, CACHE, H5E_SYSTEM, Internal error detected
|
||||
MINOR, CACHE, H5E_CANTINS, Unable to insert metadata into cache
|
||||
MINOR, CACHE, H5E_CANTRENAME, Unable to rename metadata
|
||||
MINOR, CACHE, H5E_CANTPROTECT, Unable to protect metadata
|
||||
MINOR, CACHE, H5E_CANTUNPROTECT, Unable to unprotect metadata
|
||||
|
||||
# B-tree related errors
|
||||
MINOR, BTREE, H5E_NOTFOUND, Object not found
|
||||
|
@ -30,7 +30,7 @@ LIB=libhdf5.la
|
||||
DISTCLEAN=libhdf5.settings
|
||||
|
||||
## Source and object files for the library (lexicographically)...
|
||||
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5Dcontig.c H5Dcompact.c H5Dio.c \
|
||||
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dcontig.c H5Dcompact.c H5Dio.c \
|
||||
H5Distore.c H5Dseq.c H5Dtest.c H5E.c H5F.c H5Fdbg.c H5FD.c \
|
||||
H5FDcore.c H5FDfamily.c H5FDfphdf5.c H5FDgass.c H5FDlog.c H5FDmpi.c \
|
||||
H5FDmpio.c H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDsrb.c \
|
||||
@ -54,23 +54,25 @@ LIB_OBJ=$(LIB_SRC:.c=.lo)
|
||||
MOSTLYCLEAN=H5detect.o H5detect.lo H5detect H5Tinit.o H5Tinit.lo H5Tinit.c
|
||||
|
||||
## Public header files (to be installed)...
|
||||
PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \
|
||||
H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h \
|
||||
H5FDfamily.h H5FDfphdf5.h H5FDgass.h H5FDlog.h H5FDmpi.h H5FDmpio.h \
|
||||
H5FDmpiposix.h H5FDmulti.h H5FDsec2.h H5FDsrb.h H5FDstdio.h \
|
||||
H5FDstream.h H5FPpublic.h H5Gpublic.h H5HGpublic.h H5HLpublic.h \
|
||||
H5Ipublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h \
|
||||
H5Spublic.h H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h H5api_adpt.h
|
||||
PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Cpublic.h \
|
||||
H5Dpublic.h H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h \
|
||||
H5FDcore.h H5FDfamily.h H5FDfphdf5.h H5FDgass.h H5FDlog.h H5FDmpi.h \
|
||||
H5FDmpio.h H5FDmpiposix.h H5FDmulti.h H5FDsec2.h H5FDsrb.h \
|
||||
H5FDstdio.h H5FDstream.h H5FPpublic.h H5Gpublic.h H5HGpublic.h \
|
||||
H5HLpublic.h H5Ipublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h \
|
||||
H5Rpublic.h H5Spublic.h H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h \
|
||||
H5api_adpt.h
|
||||
|
||||
## Other header files (not to be installed)...
|
||||
PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
|
||||
H5Dprivate.h H5Edefin.h H5Einit.h H5Eprivate.h H5Eterm.h H5Fprivate.h \
|
||||
H5FDprivate.h H5FLprivate.h H5FOprivate.h H5FPprivate.h H5FSprivate.h \
|
||||
H5Gprivate.h H5Gpkg.h H5HGprivate.h H5HGpkg.h H5HLprivate.h H5HLpkg.h \
|
||||
H5HPprivate.h H5Iprivate.h H5MFprivate.h H5MMprivate.h H5Oprivate.h \
|
||||
H5Opkg.h H5Pprivate.h H5Ppkg.h H5Rprivate.h H5RSprivate.h \
|
||||
H5Sprivate.h H5STprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h \
|
||||
H5TSprivate.h H5Vprivate.h H5Zprivate.h H5Zpkg.h H5config.h
|
||||
H5Cprivate.h H5Dprivate.h H5Edefin.h H5Einit.h H5Eprivate.h H5Eterm.h \
|
||||
H5Fprivate.h H5FDprivate.h H5FLprivate.h H5FOprivate.h H5FPprivate.h \
|
||||
H5FSprivate.h H5Gprivate.h H5Gpkg.h H5HGprivate.h H5HGpkg.h \
|
||||
H5HLprivate.h H5HLpkg.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \
|
||||
H5MMprivate.h H5Oprivate.h H5Opkg.h H5Pprivate.h H5Ppkg.h \
|
||||
H5Rprivate.h H5RSprivate.h H5Sprivate.h H5STprivate.h H5Tprivate.h \
|
||||
H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h H5Zprivate.h \
|
||||
H5Zpkg.h H5config.h
|
||||
|
||||
## Error header generation
|
||||
##
|
||||
|
@ -27,15 +27,16 @@ TEST_SCRIPTS=$(srcdir)/testerror.sh
|
||||
|
||||
## These are our main targets. They should be listed in the order to be
|
||||
## executed, generally most specific tests to least specific tests.
|
||||
TEST_PROGS=testhdf5 lheap ohdr stab gheap hyperslab istore bittests dtypes \
|
||||
dsets cmpd_dset extend external links unlink big mtime fillval mount \
|
||||
flush1 flush2 enum gass_write gass_read gass_append set_extent \
|
||||
srb_write srb_append srb_read ttsafe stream_test getname file_handle \
|
||||
ntypes dangle dtransform filename
|
||||
TEST_PROGS=testhdf5 lheap ohdr stab gheap cache hyperslab istore bittests \
|
||||
dtypes dsets cmpd_dset extend external links unlink big mtime \
|
||||
fillval mount flush1 flush2 enum gass_write gass_read gass_append \
|
||||
set_extent srb_write srb_append srb_read ttsafe stream_test \
|
||||
getname file_handle ntypes dangle dtransform filename
|
||||
|
||||
## Test programs for Error API. Only compile them but let testerror.sh run
|
||||
## them to compare the output error messages with standard ones. 'make check'
|
||||
## doesn't run them directly.
|
||||
|
||||
ERR_PROGS=error_test err_compat
|
||||
|
||||
PROGS=$(ERR_PROGS) $(TEST_PROGS)
|
||||
@ -77,7 +78,7 @@ CLEAN=$(TIMINGS)
|
||||
## other source lists are for the individual tests, the files of which may
|
||||
## overlap with other tests.
|
||||
|
||||
TEST_SRC=big.c bittests.c cmpd_dset.c dsets.c dtypes.c extend.c \
|
||||
TEST_SRC=big.c bittests.c cache.c cmpd_dset.c dsets.c dtypes.c extend.c \
|
||||
external.c fillval.c flush1.c flush2.c gheap.c h5test.c hyperslab.c \
|
||||
istore.c lheap.c links.c mount.c mtime.c ohdr.c stab.c tarray.c \
|
||||
tattr.c tconfig.c testhdf5.c testmeta.c tfile.c \
|
||||
@ -127,6 +128,9 @@ testhdf5: $(TESTHDF5_OBJ)
|
||||
lheap: lheap.lo
|
||||
@$(LT_LINK_EXE) $(CFLAGS) -o $@ lheap.lo $(LIB) $(LIBHDF5) $(LDFLAGS) $(LIBS)
|
||||
|
||||
cache: cache.lo
|
||||
@$(LT_LINK_EXE) $(CFLAGS) -o $@ cache.lo $(LIB) $(LIBHDF5) $(LDFLAGS) $(LIBS)
|
||||
|
||||
ohdr: ohdr.lo
|
||||
@$(LT_LINK_EXE) $(CFLAGS) -o $@ ohdr.lo $(LIB) $(LIBHDF5) $(LDFLAGS) $(LIBS)
|
||||
|
||||
|
4067
test/cache.c
Normal file
4067
test/cache.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user