summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rwxr-xr-xconfigure2
-rw-r--r--src/H5HG.c496
-rwxr-xr-xsrc/H5HGcache.c437
-rw-r--r--src/H5HGdbg.c6
-rw-r--r--src/H5HGpkg.h86
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in7
8 files changed, 619 insertions, 418 deletions
diff --git a/MANIFEST b/MANIFEST
index 590fd2b..e5e53ca 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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
diff --git a/configure b/configure
index a47df09..a659d59 100755
--- a/configure
+++ b/configure
@@ -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.
#
diff --git a/src/H5HG.c b/src/H5HG.c
index 4ee63d1..c741b91 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -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@