diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | src/H5HG.c | 496 | ||||
-rwxr-xr-x | src/H5HGcache.c | 437 | ||||
-rw-r--r-- | src/H5HGdbg.c | 6 | ||||
-rw-r--r-- | src/H5HGpkg.h | 86 | ||||
-rwxr-xr-x | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 7 |
8 files changed, 619 insertions, 418 deletions
@@ -589,6 +589,7 @@ ./src/H5HFtest.c ./src/H5HFtiny.c ./src/H5HG.c +./src/H5HGcache.c ./src/H5HGdbg.c ./src/H5HGpkg.h ./src/H5HGprivate.h @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Id: configure.in 15564 2008-08-31 09:28:03Z acheng . +# From configure.in Id: configure.in 15569 2008-09-01 06:34:44Z acheng . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for HDF5 1.9.8-MDJ_a2. # @@ -42,7 +42,6 @@ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free lists */ @@ -52,69 +51,6 @@ /* Private macros */ -/* - * Global heap collection version. - */ -#define H5HG_VERSION 1 - -/* - * All global heap collections are at least this big. This allows us to read - * most collections with a single read() since we don't have to read a few - * bytes of header to figure out the size. If the heap is larger than this - * then a second read gets the rest after we've decoded the header. - */ -#define H5HG_MINSIZE 4096 - -/* - * Limit global heap collections to the some reasonable size. This is - * fairly arbitrary, but needs to be small enough that no more than H5HG_MAXIDX - * objects will be allocated from a single heap. - */ -#define H5HG_MAXSIZE 65536 - -/* - * Maximum length of the CWFS list, the list of remembered collections that - * have free space. - */ -#define H5HG_NCWFS 16 - -/* - * The maximum number of links allowed to a global heap object. - */ -#define H5HG_MAXLINK 65535 - -/* - * The maximum number of indices allowed in a global heap object. - */ -#define H5HG_MAXIDX 65535 - -/* - * The size of the collection header, always a multiple of the alignment so - * that the stuff that follows the header is aligned. - */ -#define H5HG_SIZEOF_HDR(f) \ - H5HG_ALIGN(4 + /*magic number */ \ - 1 + /*version number */ \ - 3 + /*reserved */ \ - H5F_SIZEOF_SIZE(f)) /*collection size */ - -/* - * The initial guess for the number of messages in a collection. We assume - * that all objects in that collection are zero length, giving the maximum - * possible number of objects in the collection. The collection itself has - * some overhead and each message has some overhead. The `+2' accounts for - * rounding and for the free space object. - */ -#define H5HG_NOBJS(f,z) (int)((((z)-H5HG_SIZEOF_HDR(f))/ \ - H5HG_SIZEOF_OBJHDR(f)+2)) - -/* - * Makes a global heap object pointer undefined, or checks whether one is - * defined. - */ -#define H5HG_undef(HGP) ((HGP)->idx=0) -#define H5HG_defined(HGP) ((HGP)->idx!=0) - /* Private typedefs */ /* PRIVATE PROTOTYPES */ @@ -123,35 +59,14 @@ static haddr_t H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size); static void *H5HG_peek(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj); #endif /* NOT_YET */ -/* Metadata cache callbacks */ -static H5HG_heap_t *H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, - void *udata2); -static herr_t H5HG_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, - H5HG_heap_t *heap, unsigned UNUSED * flags_ptr); -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(const H5F_t *f, const H5HG_heap_t *heap, size_t *size_ptr); - -/* - * H5HG inherits cache-like properties from H5AC - */ -const H5AC_class_t H5AC_GHEAP[1] = {{ - H5AC_GHEAP_ID, - (H5AC_load_func_t)H5HG_load, - (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 */ -H5FL_DEFINE_STATIC(H5HG_heap_t); +H5FL_DEFINE(H5HG_heap_t); /* Declare a free list to manage sequences of H5HG_obj_t's */ -H5FL_SEQ_DEFINE_STATIC(H5HG_obj_t); +H5FL_SEQ_DEFINE(H5HG_obj_t); /* Declare a PQ free list to manage heap chunks */ -H5FL_BLK_DEFINE_STATIC(heap_chunk); +H5FL_BLK_DEFINE(heap_chunk); /*------------------------------------------------------------------------- @@ -177,16 +92,16 @@ H5FL_BLK_DEFINE_STATIC(heap_chunk); * 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 + * H5AC2_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(). + * list to just before the call to H5AC2_set(). * * John Mainzer 6/8/05 * Removed code setting the is_dirty field of the cache info. * This is no longer pemitted, as the cache code is now * manageing this field. Since this function uses a call to - * H5AC_set() (which marks the entry dirty automaticly), no + * H5AC2_set() (which marks the entry dirty automaticly), no * other change is required. * *------------------------------------------------------------------------- @@ -199,6 +114,7 @@ H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size) uint8_t *p = NULL; haddr_t addr; size_t n; + int i; FUNC_ENTER_NOAPI_NOINIT(H5HG_create) @@ -219,6 +135,7 @@ H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size) "memory allocation failed"); heap->addr = addr; heap->size = size; + heap->shared = f->shared; if (NULL==(heap->chunk = H5FL_BLK_MALLOC (heap_chunk,size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \ @@ -283,7 +200,7 @@ HDmemset(heap->chunk, 0, size); } /* Add the heap to the cache */ - if (H5AC_set (f, dxpl_id, H5AC_GHEAP, addr, heap, H5AC__NO_FLAGS_SET)<0) + if (H5AC2_set (f, dxpl_id, H5AC2_GHEAP, addr, (size_t)size, heap, H5AC2__NO_FLAGS_SET)<0) HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, \ "unable to cache global heap collection"); @@ -291,7 +208,7 @@ HDmemset(heap->chunk, 0, size); done: if ( ! ( H5F_addr_defined(addr) ) && heap) { - if ( H5HG_dest(f,heap) < 0 ) + if ( H5HG_dest(heap) < 0 ) HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, HADDR_UNDEF, \ "unable to destroy global heap collection"); } @@ -301,294 +218,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5HG_load - * - * Purpose: Loads a global heap collection from disk. - * - * Return: Success: Ptr to a global heap collection. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Friday, March 27, 1998 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * Quincey Koziol, 2002-7-180 - * Added dxpl parameter to allow more control over I/O from metadata - * cache. - *------------------------------------------------------------------------- - */ -static H5HG_heap_t * -H5HG_load (H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, - void UNUSED * udata2) -{ - H5HG_heap_t *heap = NULL; - uint8_t *p = NULL; - int i; - size_t nalloc, need; - size_t max_idx=0; /* The maximum index seen */ - H5HG_heap_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_NOAPI(H5HG_load, NULL); - - /* check arguments */ - assert (f); - assert (H5F_addr_defined (addr)); - assert (!udata1); - assert (!udata2); - - /* Read the initial 4k page */ - if(NULL == (heap = H5FL_CALLOC (H5HG_heap_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - heap->addr = addr; - if(NULL == (heap->chunk = H5FL_BLK_MALLOC(heap_chunk, (size_t)H5HG_MINSIZE))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if(H5F_block_read(f, H5FD_MEM_GHEAP, addr, (size_t)H5HG_MINSIZE, dxpl_id, heap->chunk)<0) - HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection"); - - /* Magic number */ - if(HDmemcmp(heap->chunk, H5HG_MAGIC, (size_t)H5HG_SIZEOF_MAGIC)) - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "bad global heap collection signature"); - p = heap->chunk + H5HG_SIZEOF_MAGIC; - - /* Version */ - if (H5HG_VERSION!=*p++) - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap"); - - /* Reserved */ - p += 3; - - /* Size */ - H5F_DECODE_LENGTH (f, p, heap->size); - assert (heap->size>=H5HG_MINSIZE); - - /* - * If we didn't read enough in the first try, then read the rest of the - * collection now. - */ - if (heap->size > H5HG_MINSIZE) { - haddr_t next_addr = addr + (hsize_t)H5HG_MINSIZE; - if (NULL==(heap->chunk = H5FL_BLK_REALLOC (heap_chunk, heap->chunk, heap->size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if (H5F_block_read (f, H5FD_MEM_GHEAP, next_addr, (heap->size-H5HG_MINSIZE), dxpl_id, heap->chunk+H5HG_MINSIZE)<0) - HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection"); - } - - /* Decode each object */ - p = heap->chunk + H5HG_SIZEOF_HDR (f); - nalloc = H5HG_NOBJS (f, heap->size); - if (NULL==(heap->obj = H5FL_SEQ_MALLOC (H5HG_obj_t,nalloc))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - heap->obj[0].size=heap->obj[0].nrefs=0; - heap->obj[0].begin=NULL; - - heap->nalloc = nalloc; - while (p<heap->chunk+heap->size) { - if (p+H5HG_SIZEOF_OBJHDR(f)>heap->chunk+heap->size) { - /* - * The last bit of space is too tiny for an object header, so we - * assume that it's free space. - */ - assert (NULL==heap->obj[0].begin); - heap->obj[0].size = (heap->chunk+heap->size) - p; - heap->obj[0].begin = p; - p += heap->obj[0].size; - } else { - unsigned idx; - uint8_t *begin = p; - - UINT16DECODE (p, idx); - - /* Check if we need more room to store heap objects */ - if(idx>=heap->nalloc) { - size_t new_alloc; /* New allocation number */ - H5HG_obj_t *new_obj; /* New array of object descriptions */ - - /* Determine the new number of objects to index */ - new_alloc=MAX(heap->nalloc*2,(idx+1)); - - /* Reallocate array of objects */ - if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - - /* Update heap information */ - heap->nalloc=new_alloc; - heap->obj=new_obj; - } /* end if */ - - UINT16DECODE (p, heap->obj[idx].nrefs); - p += 4; /*reserved*/ - H5F_DECODE_LENGTH (f, p, heap->obj[idx].size); - heap->obj[idx].begin = begin; - /* - * The total storage size includes the size of the object header - * and is zero padded so the next object header is properly - * aligned. The last bit of space is the free space object whose - * size is never padded and already includes the object header. - */ - if (idx>0) { - need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(heap->obj[idx].size); - - /* Check for "gap" in index numbers (caused by deletions) and fill in heap object values */ - if(idx>(max_idx+1)) - HDmemset(&heap->obj[max_idx+1],0,sizeof(H5HG_obj_t)*(idx-(max_idx+1))); - max_idx=idx; - } else { - need = heap->obj[idx].size; - } - p = begin + need; - } - } - assert(p==heap->chunk+heap->size); - assert(H5HG_ISALIGNED(heap->obj[0].size)); - - /* Set the next index value to use */ - if(max_idx>0) - heap->nused=max_idx+1; - else - heap->nused=1; - - /* - * Add the new heap to the CWFS list, removing some other entry if - * necessary to make room. We remove the right-most entry that has less - * free space than this heap. - */ - if (!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"); - f->shared->ncwfs = 1; - f->shared->cwfs[0] = heap; - } else if (H5HG_NCWFS==f->shared->ncwfs) { - for (i=H5HG_NCWFS-1; i>=0; --i) { - if (f->shared->cwfs[i]->obj[0].size < heap->obj[0].size) { - HDmemmove (f->shared->cwfs+1, f->shared->cwfs, i * sizeof(H5HG_heap_t*)); - f->shared->cwfs[0] = heap; - break; - } - } - } else { - HDmemmove (f->shared->cwfs+1, f->shared->cwfs, f->shared->ncwfs*sizeof(H5HG_heap_t*)); - f->shared->ncwfs += 1; - f->shared->cwfs[0] = heap; - } - - ret_value = heap; - -done: - if (!ret_value && heap) { - if(H5HG_dest(f,heap)<0) - HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy global heap collection"); - } - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5HG_flush - * - * Purpose: Flushes a global heap collection from memory to disk if it's - * dirty. Optionally deletes teh heap from memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, March 27, 1998 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * Quincey Koziol, 2002-7-180 - * Added dxpl parameter to allow more control over I/O from metadata - * cache. - * - * JRM -- 8/21/06 - * Added the flags_ptr parameter. This parameter exists to - * allow the flush routine to report to the cache if the - * entry is resized or renamed as a result of the flush. - * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HG_flush (H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap, unsigned UNUSED * flags_ptr) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5HG_flush, FAIL); - - /* Check arguments */ - assert (f); - assert (H5F_addr_defined (addr)); - assert (H5F_addr_eq (addr, heap->addr)); - assert (heap); - - if (heap->cache_info.is_dirty) { - if (H5F_block_write (f, H5FD_MEM_GHEAP, addr, heap->size, dxpl_id, heap->chunk)<0) - HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write global heap collection to file"); - heap->cache_info.is_dirty = FALSE; - } - - if (destroy) { - if(H5HG_dest(f,heap)<0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection"); - } - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5HG_dest - * - * Purpose: Destroys a global heap collection in memory - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, January 15, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HG_dest (H5F_t *f, H5HG_heap_t *heap) -{ - int i; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_dest); - - /* Check arguments */ - assert (heap); - - /* Verify that node is clean */ - assert (heap->cache_info.is_dirty==FALSE); - - for (i=0; i<f->shared->ncwfs; i++) { - if (f->shared->cwfs[i]==heap) { - f->shared->ncwfs -= 1; - HDmemmove (f->shared->cwfs+i, f->shared->cwfs+i+1, (f->shared->ncwfs-i) * sizeof(H5HG_heap_t*)); - break; - } - } - - if(heap->chunk) - heap->chunk = H5FL_BLK_FREE(heap_chunk,heap->chunk); - if(heap->obj) - heap->obj = H5FL_SEQ_FREE(H5HG_obj_t,heap->obj); - H5FL_FREE (H5HG_heap_t,heap); - - FUNC_LEAVE_NOAPI(SUCCEED); -} /* H5HG_dest() */ - - -/*------------------------------------------------------------------------- * Function: H5HG_clear * * Purpose: Mark a global heap in memory as non-dirty. @@ -616,7 +245,7 @@ H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy) heap->cache_info.is_dirty = FALSE; if (destroy) - if (H5HG_dest(f, heap) < 0) + if (H5HG_dest(heap) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection"); done: @@ -675,7 +304,7 @@ H5HG_compute_size(const H5F_t UNUSED *f, const H5HG_heap_t *heap, size_t *size_p * * John Mainzer, 6/8/05 * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty + * of H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * * In this case, that required adding the new heap_dirtied_ptr @@ -772,7 +401,7 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr) } /* Mark the heap as dirty */ - *heap_flags_ptr |= H5AC__DIRTIED_FLAG; + *heap_flags_ptr |= H5AC2__DIRTIED_FLAG; /* Set the return value */ ret_value=idx; @@ -801,7 +430,7 @@ done: * * John Mainzer, 6/8/05 * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty + * of H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * * In this case, that required adding the new heap_dirtied_ptr @@ -875,7 +504,7 @@ HDmemset(new_chunk + heap->size, 0, need); assert(H5HG_ISALIGNED(heap->obj[0].size)); /* Mark the heap as dirty */ - *heap_flags_ptr |= H5AC__DIRTIED_FLAG; + *heap_flags_ptr |= H5AC2__DIRTIED_FLAG; done: FUNC_LEAVE_NOAPI(ret_value); @@ -918,12 +547,12 @@ done: * 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 + * entry inserted in it via H5AC2_set(). I then modified * this function to account for the change in H5HG_create(). * * John Mainzer - 6/8/05 * Modified function to use the dirtied parameter of - * H5AC_unprotect() instead of modifying the is_dirty + * H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * *------------------------------------------------------------------------- @@ -936,7 +565,7 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out* size_t idx; haddr_t addr = HADDR_UNDEF; H5HG_heap_t *heap = NULL; - unsigned heap_flags = H5AC__NO_FLAGS_SET; + unsigned heap_flags = H5AC2__NO_FLAGS_SET; hbool_t found=0; /* Flag to indicate a heap with enough space was found */ herr_t ret_value=SUCCEED; /* Return value */ @@ -1035,9 +664,10 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out* } /* end else */ HDassert(H5F_addr_defined(addr)); - - if ( NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, NULL, NULL, H5AC_WRITE)) ) + if ( NULL == (heap = H5AC2_protect(f, dxpl_id, H5AC2_GHEAP, addr, (size_t)H5HG_SPEC_READ_SIZE, f, H5AC2_WRITE)) ) HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap"); + + HDassert(heap->obj[0].size); /* Split the free space to make room for the new object */ idx = H5HG_alloc (f, heap, size, &heap_flags); @@ -1051,14 +681,14 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out* need-(H5HG_SIZEOF_OBJHDR(f)+size)); #endif /* OLD_WAY */ } /* end if */ - heap_flags |= H5AC__DIRTIED_FLAG; + heap_flags |= H5AC2__DIRTIED_FLAG; /* Return value */ hobj->addr = heap->addr; hobj->idx = idx; done: - if ( heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, heap->addr, heap, heap_flags) < 0 ) + if ( heap && H5AC2_unprotect(f, dxpl_id, H5AC2_GHEAP, heap->addr, (size_t)0, heap, heap_flags) < 0 ) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to unprotect heap."); FUNC_LEAVE_NOAPI(ret_value); @@ -1084,7 +714,7 @@ done: * * John Mainzer, 6/8/05 * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty + * of H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * *------------------------------------------------------------------------- @@ -1105,7 +735,7 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/, HDassert(hobj); /* Load the heap */ - if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_READ))) + if(NULL == (heap = H5AC2_protect(f, dxpl_id, H5AC2_GHEAP, hobj->addr, (size_t)H5HG_SPEC_READ_SIZE, f, H5AC2_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap") HDassert(hobj->idx < heap->nused); @@ -1119,7 +749,7 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/, /* * Advance the heap in the CWFS list. We might have done this already - * with the H5AC_protect(), but it won't hurt to do it twice. + * with the H5AC2_protect(), but it won't hurt to do it twice. */ if(heap->obj[0].begin) { int i; @@ -1142,7 +772,7 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/, ret_value = object; done: - if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, H5AC__NO_FLAGS_SET)<0) + if(heap && H5AC2_unprotect(f, dxpl_id, H5AC2_GHEAP, hobj->addr, (size_t)0, heap, H5AC2__NO_FLAGS_SET)<0) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) @@ -1169,7 +799,7 @@ done: * * John Mainzer - 6/8/05 * Modified function to use the dirtied parameter of - * H5AC_unprotect() instead of modifying the is_dirty + * H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * *------------------------------------------------------------------------- @@ -1178,7 +808,7 @@ int H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust) { H5HG_heap_t *heap = NULL; - unsigned heap_flags = H5AC__NO_FLAGS_SET; + unsigned heap_flags = H5AC2__NO_FLAGS_SET; int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5HG_link, FAIL); @@ -1190,8 +820,9 @@ H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust) HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file"); if(adjust!=0) { + /* Load the heap */ - if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_WRITE))) + if (NULL == (heap = H5AC2_protect(f, dxpl_id, H5AC2_GHEAP, hobj->addr, (size_t)H5HG_SPEC_READ_SIZE, f, H5AC2_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap"); assert (hobj->idx<heap->nused); @@ -1201,14 +832,14 @@ H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust) if (heap->obj[hobj->idx].nrefs+adjust>H5HG_MAXLINK) HGOTO_ERROR (H5E_HEAP, H5E_BADVALUE, FAIL, "new link count would be out of range"); heap->obj[hobj->idx].nrefs += adjust; - heap_flags |= H5AC__DIRTIED_FLAG; + heap_flags |= H5AC2__DIRTIED_FLAG; } /* end if */ /* Set return value */ ret_value=heap->obj[hobj->idx].nrefs; done: - if (heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, heap_flags)<0) + if (heap && H5AC2_unprotect(f, dxpl_id, H5AC2_GHEAP, hobj->addr, (size_t)0, heap, heap_flags)<0) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); FUNC_LEAVE_NOAPI(ret_value); @@ -1229,7 +860,7 @@ done: * * John Mainzer - 6/8/05 * Modified function to use the dirtied parameter of - * H5AC_unprotect() instead of modifying the is_dirty + * H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * *------------------------------------------------------------------------- @@ -1242,7 +873,7 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) size_t need; int i; unsigned u; - unsigned flags=H5AC__NO_FLAGS_SET;/* Whether the heap gets deleted */ + unsigned flags=H5AC2__NO_FLAGS_SET;/* Whether the heap gets deleted */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HG_remove, FAIL); @@ -1254,7 +885,7 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file"); /* Load the heap */ - if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_WRITE))) + if (NULL == (heap = H5AC2_protect(f, dxpl_id, H5AC2_GHEAP, hobj->addr, (size_t)H5HG_SPEC_READ_SIZE, f, H5AC2_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap"); assert (hobj->idx<heap->nused); @@ -1275,8 +906,10 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) } else { heap->obj[0].size += need; } + HDmemmove (obj_start, obj_start+need, heap->size-((obj_start+need)-heap->chunk)); + if (heap->obj[0].size>=H5HG_SIZEOF_OBJHDR (f)) { p = heap->obj[0].begin; UINT16ENCODE(p, 0); /*id*/ @@ -1285,7 +918,7 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) H5F_ENCODE_LENGTH (f, p, heap->obj[0].size); } HDmemset (heap->obj+hobj->idx, 0, sizeof(H5HG_obj_t)); - flags |= H5AC__DIRTIED_FLAG; + flags |= H5AC2__DIRTIED_FLAG; if (heap->obj[0].size+H5HG_SIZEOF_HDR(f)==heap->size) { /* @@ -1298,7 +931,7 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) } else { /* * If the heap is in the CWFS list then advance it one position. The - * H5AC_protect() might have done that too, but that's okay. If the + * H5AC2_protect() might have done that too, but that's okay. If the * heap isn't on the CWFS list then add it to the end. */ for (i=0; i<f->shared->ncwfs; i++) { @@ -1317,8 +950,55 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) } done: - if (heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, flags) != SUCCEED) + if (heap && H5AC2_unprotect(f, dxpl_id, H5AC2_GHEAP, hobj->addr, (size_t)0, heap, flags) != SUCCEED) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); FUNC_LEAVE_NOAPI(ret_value); } + + +/*------------------------------------------------------------------------- + * Function: H5HG_dest + * + * Purpose: Destroys a global heap collection in memory + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, January 15, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5HG_dest (H5HG_heap_t *heap) +{ + int i; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_dest); + + /* Check arguments */ + assert (heap); + + /* Verify that node is clean */ + assert (heap->cache_info.is_dirty==FALSE); + + + /* Remove the heap from the CWFS list */ + for (i=0; i<heap->shared->ncwfs; i++) { + if (heap->shared->cwfs[i]==heap) { + heap->shared->ncwfs -= 1; + HDmemmove (heap->shared->cwfs+i, heap->shared->cwfs+i+1, (heap->shared->ncwfs-i) * sizeof(H5HG_heap_t*)); + break; + } + } + + if(heap->chunk) + heap->chunk = H5FL_BLK_FREE(heap_chunk,heap->chunk); + if(heap->obj) + heap->obj = H5FL_SEQ_FREE(H5HG_obj_t,heap->obj); + H5FL_FREE (H5HG_heap_t,heap); + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5HG_dest() */ diff --git a/src/H5HGcache.c b/src/H5HGcache.c new file mode 100755 index 0000000..6f4cf45 --- /dev/null +++ b/src/H5HGcache.c @@ -0,0 +1,437 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5HGcache.c + * October 6, 2008 + * Mike McGreevy <mamcgree@hdfgroup.org> + * + * Purpose: Implement gloabl heap metadata cache methods. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5HG_PACKAGE /*suppress error about including H5HGpkg */ + +/***********/ +/* Headers */ +/***********/ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5HGpkg.h" /* Global heaps */ +#include "H5MMprivate.h" /* Memory management */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Metadata cache callbacks */ +static void *H5HG_deserialize(haddr_t addr, size_t len, const void *image, + const void *udata, hbool_t *dirty); +static herr_t H5HG_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, + void *image, void *thing, unsigned *flags, haddr_t *new_addr, + size_t *new_len, void **new_image); +static herr_t H5HG_free_icr(haddr_t addr, size_t len, void *thing); +static herr_t H5HG_image_len(const void *thing, size_t *image_len_ptr); + +/*********************/ +/* Package Variables */ +/*********************/ + +/* + * H5HG inherits cache-like properties from H5AC2 + */ +const H5AC2_class_t H5AC2_GHEAP[1] = {{ + H5AC2_GHEAP_ID, + "global heap", + H5FD_MEM_GHEAP, + H5HG_deserialize, + H5HG_image_len, + H5HG_serialize, + H5HG_free_icr, + NULL, +}}; + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + + +/*------------------------------------------------------------------------- + * Function: H5HG_deserialize + * + * Purpose: Deserialize the data structure from disk. + * + * Return: Success: SUCCESS + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, March 27, 1998 + * + * Modifications: + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + * + * Quincey Koziol, 2002-7-180 + * Added dxpl parameter to allow more control over I/O from metadata + * cache. + * + * Mike McGreevy + * mcgreevy@hdfgroup.org + * July 28, 2008 + * Converted from H5HG_load + * + *------------------------------------------------------------------------- + */ +static void * +H5HG_deserialize(haddr_t addr, size_t UNUSED len, const void *image, + const void *_udata, hbool_t UNUSED *dirty) +{ + + H5HG_heap_t *heap = NULL; + uint8_t *p = NULL; + int i; + size_t nalloc, need; + size_t max_idx=0; /* The maximum index seen */ + H5HG_heap_t *ret_value = NULL; /* Return value */ + H5F_t *f = (H5F_t *)_udata; + + FUNC_ENTER_NOAPI(H5HG_deserialize, NULL); + + /* check arguments */ + HDassert(image); + + /* Allocate space for heap */ + if(NULL == (heap = H5FL_CALLOC (H5HG_heap_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + heap->addr = addr; + heap->shared = f->shared; + + p = image; + + /* Magic number */ + if(HDmemcmp(p, H5HG_MAGIC, (size_t)H5HG_SIZEOF_MAGIC)) + HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "bad global heap collection signature"); + p += H5HG_SIZEOF_MAGIC; + + /* Version */ + if (H5HG_VERSION!=*p++) + HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap"); + + /* Reserved */ + p += 3; + + /* Size */ + H5F_DECODE_LENGTH (f, p, heap->size); + assert (heap->size>=H5HG_MINSIZE); + + /* if heap->size is more than the allocated image size, then we need to do nothing and wait for correctly sized image to come in */ + if (heap->size <= len) { + + /* Allocate space for the heap->chunk */ + if(NULL == (heap->chunk = H5FL_BLK_MALLOC(heap_chunk, (size_t)heap->size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Copy image into chunk */ + HDmemcpy(heap->chunk, image, heap->size); + + /* Decode each object */ + p = heap->chunk + H5HG_SIZEOF_HDR(f); + nalloc = H5HG_NOBJS (f, heap->size); + if (NULL==(heap->obj = H5FL_SEQ_MALLOC (H5HG_obj_t,nalloc))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + heap->obj[0].size=heap->obj[0].nrefs=0; + heap->obj[0].begin=NULL; + heap->nalloc = nalloc; + while (p<heap->chunk+heap->size) { + if (p+H5HG_SIZEOF_OBJHDR(f)>heap->chunk+heap->size) { + /* + * The last bit of space is too tiny for an object header, so we + * assume that it's free space. + */ + assert (NULL==heap->obj[0].begin); + heap->obj[0].size = ((const uint8_t *)heap->chunk+heap->size) - p; + heap->obj[0].begin = p; + p += heap->obj[0].size; + } else { + unsigned idx; + uint8_t *begin = p; + + UINT16DECODE (p, idx); + + /* Check if we need more room to store heap objects */ + if(idx>=heap->nalloc) { + size_t new_alloc; /* New allocation number */ + H5HG_obj_t *new_obj; /* New array of object descriptions */ + + /* Determine the new number of objects to index */ + new_alloc=MAX(heap->nalloc*2,(idx+1)); + + /* Reallocate array of objects */ + if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Update heap information */ + heap->nalloc=new_alloc; + heap->obj=new_obj; + } /* end if */ + + UINT16DECODE (p, heap->obj[idx].nrefs); + p += 4; /*reserved*/ + H5F_DECODE_LENGTH (f, p, heap->obj[idx].size); + heap->obj[idx].begin = begin; + /* + * The total storage size includes the size of the object header + * and is zero padded so the next object header is properly + * aligned. The last bit of space is the free space object whose + * size is never padded and already includes the object header. + */ + if (idx>0) { + need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(heap->obj[idx].size); + + /* Check for "gap" in index numbers (caused by deletions) and fill in heap object values */ + if(idx>(max_idx+1)) + HDmemset(&heap->obj[max_idx+1],0,sizeof(H5HG_obj_t)*(idx-(max_idx+1))); + max_idx=idx; + } else { + need = heap->obj[idx].size; + } + p = begin + need; + } + } + assert(p==heap->chunk+heap->size); + assert(H5HG_ISALIGNED(heap->obj[0].size)); + + + /* Set the next index value to use */ + if(max_idx>0) + heap->nused=max_idx+1; + else + heap->nused=1; + + /* + * Add the new heap to the CWFS list, removing some other entry if + * necessary to make room. We remove the right-most entry that has less + * free space than this heap. + */ + if (!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"); + f->shared->ncwfs = 1; + f->shared->cwfs[0] = heap; + } else if (H5HG_NCWFS==f->shared->ncwfs) { + for (i=H5HG_NCWFS-1; i>=0; --i) { + if (f->shared->cwfs[i]->obj[0].size < heap->obj[0].size) { + HDmemmove (f->shared->cwfs+1, f->shared->cwfs, i * sizeof(H5HG_heap_t*)); + f->shared->cwfs[0] = heap; + break; + } + } + } else { + HDmemmove (f->shared->cwfs+1, f->shared->cwfs, f->shared->ncwfs*sizeof(H5HG_heap_t*)); + f->shared->ncwfs += 1; + f->shared->cwfs[0] = heap; + } + + /* Sanity check */ + HDassert((size_t)((const uint8_t *)p - (const uint8_t *)heap->chunk) <= len); + + } /* end if heap->size <= len */ + + ret_value = heap; + +done: + if (!ret_value && heap) { + if(H5HG_dest(heap)<0) + HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy global heap collection"); + } + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5HG_serialize + * + * Purpose: Serialize the data structure for writing to disk. + * + * Return: Success: SUCCESS + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, March 27, 1998 + * + * Modifications: + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + * + * Quincey Koziol, 2002-7-180 + * Added dxpl parameter to allow more control over I/O from metadata + * cache. + * + * JRM -- 8/21/06 + * Added the flags_ptr parameter. This parameter exists to + * allow the flush routine to report to the cache if the + * entry is resized or renamed as a result of the flush. + * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. + * + * Mike McGreevy + * mcgreevy@hdfgroup.org + * July 28, 2008 + * Converted from H5HG_flush + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HG_serialize (const H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, size_t UNUSED len, + void *image, void *_thing, unsigned *flags, haddr_t UNUSED *new_addr, + size_t UNUSED *new_len, void UNUSED **new_image) +{ + herr_t ret_value=SUCCEED; /* Return value */ + H5HG_heap_t *heap = (H5HG_heap_t *)_thing; + + FUNC_ENTER_NOAPI(H5HG_serialize, FAIL); + + /* Check arguments */ + assert (f); + assert (H5F_addr_defined (addr)); + assert (H5F_addr_eq (addr, heap->addr)); + assert (heap); + + + /* Need to increase image size if we need to copy a bigger thing into it */ + if (heap->size > len) { + /* free old image buffer */ + H5MM_free(image); + + /* allocate new image buffer */ + *new_image = H5MM_malloc(heap->size); + if (*new_image == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "new image null after H5MM_realloc()\n"); + + /* copy the heap->chunk into the new image buffer */ + HDmemcpy(*new_image, heap->chunk, heap->size); + + /* set new length of image */ + *new_len = heap->size; + + /* specify in flags that image has been resized */ + *flags = H5C2__SERIALIZE_RESIZED_FLAG; + + } else { + + /* copy the heap->chunk into the image buffer */ + HDmemcpy(image, heap->chunk, heap->size); + + /* Reset the cache flags for this operation */ + *flags = 0; + + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5HG_image_len + * + * Purpose: Tell the metadata cache about the actual size + * of the global heap + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 28, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HG_image_len(const void *thing, size_t *image_len_ptr) +{ + + const H5HG_heap_t *heap = (const H5HG_heap_t *)thing; /* Global heap */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_image_len) + + /* Check arguments */ + HDassert(heap); + HDassert(image_len_ptr); + + /* Report the global heap's total size */ + *image_len_ptr = heap->size; + + FUNC_LEAVE_NOAPI(SUCCEED) + +} /* end H5HG_image_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5HG_free_icr + * + * Purpose: Destroy/release an "in core representation" of a data structure + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 28, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HG_free_icr(haddr_t UNUSED addr, size_t UNUSED len, void *thing) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_free_icr) + + /* Check arguments */ + HDassert(thing); + + /* Destroy B-tree node */ + H5HG_dest(thing); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HG_free_icr() */ + + + + diff --git a/src/H5HGdbg.c b/src/H5HGdbg.c index 0e5aff8..d21e1f4 100644 --- a/src/H5HGdbg.c +++ b/src/H5HGdbg.c @@ -48,7 +48,7 @@ * * John Mainzer, 6/17/05 * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty + * of H5AC2_unprotect() instead of modifying the is_dirty * field of the cache info. * *------------------------------------------------------------------------- @@ -73,7 +73,7 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, assert(indent >= 0); assert(fwidth >= 0); - if (NULL == (h = H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, NULL, NULL, H5AC_READ))) + if (NULL == (h = H5AC2_protect(f, dxpl_id, H5AC2_GHEAP, addr, fwidth, f, H5AC2_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load global heap collection"); fprintf(stream, "%*sGlobal Heap Collection...\n", indent, ""); @@ -132,7 +132,7 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, } done: - if (h && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, addr, h, H5AC__NO_FLAGS_SET) != SUCCEED) + if (h && H5AC2_unprotect(f, dxpl_id, H5AC2_GHEAP, addr, (size_t)0, h, H5AC2__NO_FLAGS_SET) != SUCCEED) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); FUNC_LEAVE_NOAPI(ret_value); diff --git a/src/H5HGpkg.h b/src/H5HGpkg.h index e814367..f526d00 100644 --- a/src/H5HGpkg.h +++ b/src/H5HGpkg.h @@ -32,13 +32,17 @@ #include "H5HGprivate.h" /* Other private headers needed by this file */ +#include "H5AC2private.h" /* Metadata cache */ + +#define H5F_PACKAGE +#include "H5Fpkg.h" /*****************************/ /* Package Private Variables */ /*****************************/ /* The cache subclass */ -H5_DLLVAR const H5AC_class_t H5AC_GHEAP[1]; +H5_DLLVAR const H5AC2_class_t H5AC2_GHEAP[1]; /**************************/ /* Package Private Macros */ @@ -65,6 +69,71 @@ H5_DLLVAR const H5AC_class_t H5AC_GHEAP[1]; 4 + /*reserved */ \ H5F_SIZEOF_SIZE(f)) /*object data size */ +/* + * Global heap collection version. + */ +#define H5HG_VERSION 1 + +/* + * All global heap collections are at least this big. This allows us to read + * most collections with a single read() since we don't have to read a few + * bytes of header to figure out the size. If the heap is larger than this + * then a second read gets the rest after we've decoded the header. + */ +#define H5HG_MINSIZE 4096 + +/* + * Limit global heap collections to the some reasonable size. This is + * fairly arbitrary, but needs to be small enough that no more than H5HG_MAXIDX + * objects will be allocated from a single heap. + */ +#define H5HG_MAXSIZE 65536 + +/* + * Maximum length of the CWFS list, the list of remembered collections that + * have free space. + */ +#define H5HG_NCWFS 16 + +/* + * The maximum number of links allowed to a global heap object. + */ +#define H5HG_MAXLINK 65535 + +/* + * The maximum number of indices allowed in a global heap object. + */ +#define H5HG_MAXIDX 65535 + +/* + * The size of the collection header, always a multiple of the alignment so + * that the stuff that follows the header is aligned. + */ +#define H5HG_SIZEOF_HDR(f) \ + H5HG_ALIGN(4 + /*magic number */ \ + 1 + /*version number */ \ + 3 + /*reserved */ \ + H5F_SIZEOF_SIZE(f)) /*collection size */ + +/* + * The initial guess for the number of messages in a collection. We assume + * that all objects in that collection are zero length, giving the maximum + * possible number of objects in the collection. The collection itself has + * some overhead and each message has some overhead. The `+2' accounts for + * rounding and for the free space object. + */ +#define H5HG_NOBJS(f,z) (int)((((z)-H5HG_SIZEOF_HDR(f))/ \ + H5HG_SIZEOF_OBJHDR(f)+2)) + +/* + * Makes a global heap object pointer undefined, or checks whether one is + * defined. + */ +#define H5HG_undef(HGP) ((HGP)->idx=0) +#define H5HG_defined(HGP) ((HGP)->idx!=0) + +#define H5HG_SPEC_READ_SIZE 4096 + /****************************/ /* Package Private Typedefs */ /****************************/ @@ -76,7 +145,7 @@ typedef struct H5HG_obj_t { } H5HG_obj_t; struct H5HG_heap_t { - H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ + H5AC2_info_t cache_info; /* Information for H5AC2 cache functions, _must_ be */ /* first field in structure */ haddr_t addr; /*collection address */ size_t size; /*total size of collection */ @@ -86,6 +155,7 @@ struct H5HG_heap_t { /* If this value is >65535 then all indices */ /* have been used at some time and the */ /* correct new index should be searched for */ + H5F_file_t *shared; /* shared file */ H5HG_obj_t *obj; /*array of object descriptions */ }; @@ -93,5 +163,17 @@ struct H5HG_heap_t { /* Package Private Prototypes */ /******************************/ +H5_DLL herr_t H5HG_dest(H5HG_heap_t *heap); + +/* Declare a free list to manage the H5HG_t struct */ +H5FL_EXTERN(H5HG_heap_t); + +/* Declare a free list to manage sequences of H5HG_obj_t's */ +H5FL_SEQ_EXTERN(H5HG_obj_t); + +/* Declare a PQ free list to manage heap chunks */ +H5FL_BLK_EXTERN(heap_chunk); + + #endif diff --git a/src/Makefile.am b/src/Makefile.am index a010cb3..8a77070 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -63,7 +63,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ - H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5L.c H5Lexternal.c \ + H5HG.c H5HGcache.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5L.c H5Lexternal.c \ H5MF.c H5MM.c H5MP.c H5MPtest.c \ H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ochunk.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 51417eb..cf79748 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -98,8 +98,8 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5HFcache.lo H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo \ H5HFhuge.lo H5HFiblock.lo H5HFiter.lo H5HFman.lo \ H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \ - H5HFtiny.lo H5HG.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo \ - H5I.lo H5L.lo H5Lexternal.lo H5MF.lo H5MM.lo H5MP.lo \ + H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo \ + H5HP.lo H5I.lo H5L.lo H5Lexternal.lo H5MF.lo H5MM.lo H5MP.lo \ H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo \ @@ -442,7 +442,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ - H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5L.c H5Lexternal.c \ + H5HG.c H5HGcache.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5L.c H5Lexternal.c \ H5MF.c H5MM.c H5MP.c H5MPtest.c \ H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ochunk.c \ @@ -702,6 +702,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFtiny.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HG.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HGcache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HGdbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HL.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HLdbg.Plo@am__quote@ |