diff options
Diffstat (limited to 'src/H5Gcache.c')
-rw-r--r-- | src/H5Gcache.c | 400 |
1 files changed, 179 insertions, 221 deletions
diff --git a/src/H5Gcache.c b/src/H5Gcache.c index bedceb6..8dfecb1 100644 --- a/src/H5Gcache.c +++ b/src/H5Gcache.c @@ -46,7 +46,6 @@ /****************/ #define H5G_NODE_VERS 1 /* Symbol table node version number */ -#define H5G_NODE_BUF_SIZE 512 /* Size of stack buffer for serialized nodes */ /******************/ @@ -64,12 +63,14 @@ /********************/ /* Metadata cache (H5AC) callbacks */ -static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata); -static herr_t H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, - H5G_node_t *sym, unsigned *flags_ptr); -static herr_t H5G_node_dest(H5F_t *f, H5G_node_t *sym); -static herr_t H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy); -static herr_t H5G_node_size(const H5F_t *f, const H5G_node_t *sym, size_t *size_ptr); +static herr_t H5G__cache_node_get_load_size(const void *udata, size_t *image_len); +static void *H5G__cache_node_deserialize(const void *image, size_t len, + void *udata, hbool_t *dirty); +static herr_t H5G__cache_node_image_len(const void *thing, size_t *image_len, + hbool_t *compressed_ptr, size_t *compressed_image_len_ptr); +static herr_t H5G__cache_node_serialize(const H5F_t *f, void *image, + size_t len, void *thing); +static herr_t H5G__cache_node_free_icr(void *thing); /*********************/ @@ -88,13 +89,19 @@ static herr_t H5G_node_size(const H5F_t *f, const H5G_node_t *sym, size_t *size_ /* Symbol table nodes inherit cache-like properties from H5AC */ const H5AC_class_t H5AC_SNODE[1] = {{ - H5AC_SNODE_ID, - (H5AC_load_func_t)H5G_node_load, - (H5AC_flush_func_t)H5G_node_flush, - (H5AC_dest_func_t)H5G_node_dest, - (H5AC_clear_func_t)H5G_node_clear, - (H5AC_notify_func_t)NULL, - (H5AC_size_func_t)H5G_node_size, + H5AC_SNODE_ID, /* Metadata client ID */ + "Symbol table node", /* Metadata client name (for debugging) */ + H5FD_MEM_BTREE, /* File space memory type for client */ + H5AC__CLASS_NO_FLAGS_SET, /* Client class behavior flags */ + H5G__cache_node_get_load_size, /* 'get_load_size' callback */ + H5G__cache_node_deserialize, /* 'deserialize' callback */ + H5G__cache_node_image_len, /* 'image_len' callback */ + NULL, /* 'pre_serialize' callback */ + H5G__cache_node_serialize, /* 'serialize' callback */ + NULL, /* 'notify' callback */ + H5G__cache_node_free_icr, /* 'free_icr' callback */ + NULL, /* 'clear' callback */ + NULL, /* 'fsf_size' callback */ }}; @@ -106,42 +113,80 @@ H5FL_SEQ_EXTERN(H5G_entry_t); /*------------------------------------------------------------------------- - * Function: H5G_node_load + * Function: H5G__cache_node_get_load_size() * - * Purpose: Loads a symbol table node from the file. + * Purpose: Determine the size of the on disk image of the node, and + * return this value in *image_len. * - * Return: Success: Ptr to the new table. + * Note that this computation requires access to the file pointer, + * which is not provided in the parameter list for this callback. + * Finesse this issue by passing in the file pointer twice to the + * H5AC_protect() call -- once as the file pointer proper, and + * again as the user data. + * + * Return: Success: SUCCEED + * Failure: FAIL * - * Failure: NULL - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: John Mainzer + * 7/21/14 * *------------------------------------------------------------------------- */ -static H5G_node_t * -H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata) +static herr_t +H5G__cache_node_get_load_size(const void *_udata, size_t *image_len) { - H5G_node_t *sym = NULL; - H5WB_t *wb = NULL; /* Wrapped buffer for node data */ - uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */ - uint8_t *node; /* Pointer to node buffer */ - const uint8_t *p; - H5G_node_t *ret_value; /*for error handling */ - - FUNC_ENTER_NOAPI_NOINIT - - /* - * Check arguments. - */ + const H5F_t *f = (const H5F_t *)_udata; /* User data for callback */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ HDassert(f); - HDassert(H5F_addr_defined(addr)); - HDassert(udata); + HDassert(image_len); + + /* report image length */ + *image_len = (size_t)(H5G_NODE_SIZE(f)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G__cache_node_get_load_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5G__cache_node_deserialize + * + * Purpose: Given a buffer containing the on disk image of a symbol table + * node, allocate an instance of H5G_node_t, load the contence of the + * image into it, and return a pointer to the instance. + * + * Note that deserializing the image requires access to the file + * pointer, which is not included in the parameter list for this + * callback. Finesse this issue by passing in the file pointer + * twice to the H5AC_protect() call -- once as the file pointer + * proper, and again as the user data + * + * Return: Success: Pointer to in core representation + * Failure: NULL + * + * Programmer: John Mainzer + * 6/21/14 + * + *------------------------------------------------------------------------- + */ +static void * +H5G__cache_node_deserialize(const void *_image, size_t len, void *_udata, + hbool_t H5_ATTR_UNUSED *dirty) +{ + H5F_t *f = (H5F_t *)_udata; /* User data for callback */ + H5G_node_t *sym = NULL; /* Symbol table node created */ + const uint8_t *image = (const uint8_t *)_image; /* Pointer to image to deserialize */ + void * ret_value; /* Return value */ - /* - * Initialize variables. - */ + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(image); + HDassert(len > 0); + HDassert(f); + HDassert(dirty); /* Allocate symbol table data structures */ if(NULL == (sym = H5FL_CALLOC(H5G_node_t))) @@ -150,262 +195,175 @@ H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata) if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f))))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Wrap the local buffer for serialized node info */ - if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf)))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't wrap buffer") - - /* Get a pointer to a buffer that's large enough for node */ - if(NULL == (node = (uint8_t *)H5WB_actual(wb, sym->node_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't get actual buffer") - - /* Read the serialized symbol table node. */ - if(H5F_block_read(f, H5FD_MEM_BTREE, addr, sym->node_size, dxpl_id, node) < 0) - HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node") - - /* Get temporary pointer to serialized node */ - p = node; - /* magic */ - if(HDmemcmp(p, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature") - p += H5_SIZEOF_MAGIC; + if(HDmemcmp(image, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "bad symbol table node signature") + image += H5_SIZEOF_MAGIC; /* version */ - if(H5G_NODE_VERS != *p++) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version") + if(H5G_NODE_VERS != *image++) + HGOTO_ERROR(H5E_SYM, H5E_VERSION, NULL, "bad symbol table node version") /* reserved */ - p++; + image++; /* number of symbols */ - UINT16DECODE(p, sym->nsyms); + UINT16DECODE(image, sym->nsyms); /* entries */ - if(H5G__ent_decode_vec(f, &p, sym->entry, sym->nsyms) < 0) + if(H5G__ent_decode_vec(f, &image, sym->entry, sym->nsyms) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries") /* Set return value */ ret_value = sym; done: - /* Release resources */ - if(wb && H5WB_unwrap(wb) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value) if(sym && H5G__node_free(sym) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_node_load() */ +} /* end H5G__cache_node_deserialize() */ /*------------------------------------------------------------------------- - * Function: H5G_node_flush + * Function: H5G__cache_node_image_len * - * Purpose: Flush a symbol table node to disk. + * Purpose: Compute the size of the data structure on disk and return + * it in *image_len. * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: John Mainzer + * 6/21/14 * *------------------------------------------------------------------------- */ static herr_t -H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_t *sym, unsigned H5_ATTR_UNUSED * flags_ptr) +H5G__cache_node_image_len(const void *_thing, size_t *image_len, + hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr) { - H5WB_t *wb = NULL; /* Wrapped buffer for node data */ - uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5G_node_t *sym = (const H5G_node_t *)_thing; /* Pointer to object */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC_NOERR - /* - * Check arguments. - */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); + /* Sanity checks */ HDassert(sym); + HDassert(sym->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + HDassert(sym->cache_info.type == H5AC_SNODE); + HDassert(image_len); - /* - * Write the symbol node to disk. - */ - if(sym->cache_info.is_dirty) { - uint8_t *node; /* Pointer to node buffer */ - uint8_t *p; /* Pointer into raw data buffer */ - - /* Wrap the local buffer for serialized node info */ - if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf)))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer") - - /* Get a pointer to a buffer that's large enough for node */ - if(NULL == (node = (uint8_t *)H5WB_actual(wb, sym->node_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer") - - /* Get temporary pointer to serialized symbol table node */ - p = node; - - /* magic number */ - HDmemcpy(p, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC); - p += H5_SIZEOF_MAGIC; - - /* version number */ - *p++ = H5G_NODE_VERS; - - /* reserved */ - *p++ = 0; - - /* number of symbols */ - UINT16ENCODE(p, sym->nsyms); - - /* entries */ - if(H5G__ent_encode_vec(f, &p, sym->entry, sym->nsyms) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't serialize") - HDmemset(p, 0, sym->node_size - (size_t)(p - node)); - - /* Write the serialized symbol table node. */ - if(H5F_block_write(f, H5FD_MEM_BTREE, addr, sym->node_size, dxpl_id, node) < 0) - HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file") - - /* Reset the node's dirty flag */ - sym->cache_info.is_dirty = FALSE; - } /* end if */ + *image_len = sym->node_size; - /* - * Destroy the symbol node? This might happen if the node is being - * preempted from the cache. - */ - if(destroy) - if(H5G_node_dest(f, sym) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node") + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G__cache_node_image_len() */ -done: - /* Release resources */ - if(wb && H5WB_unwrap(wb) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer") - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_node_flush() */ +/*************************************/ +/* no H5G__cache_node_pre_serialize() */ +/*************************************/ /*------------------------------------------------------------------------- - * Function: H5G_node_dest + * Function: H5G__cache_node_serialize * - * Purpose: Destroy a symbol table node in memory. + * Purpose: Given a correctly sized buffer and an instace of H5G_node_t, + * serialize the contents of the instance of H5G_node_t, and write + * this data into the supplied buffer. This buffer will be written + * to disk. * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jan 15 2003 + * Programmer: John Mainzer + * 7/21/14 * *------------------------------------------------------------------------- */ static herr_t -H5G_node_dest(H5F_t *f, H5G_node_t *sym) +H5G__cache_node_serialize(const H5F_t *f, void *_image, size_t len, + void *_thing) { - herr_t ret_value = SUCCEED; /* Return value */ + H5G_node_t *sym = (H5G_node_t *)_thing; /* Pointer to object */ + uint8_t *image = (uint8_t *)_image; /* Pointer into raw data buffer */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* - * Check arguments. - */ + /* Sanity checks */ HDassert(f); + HDassert(image); HDassert(sym); + HDassert(sym->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + HDassert(sym->cache_info.type == H5AC_SNODE); + HDassert(len == sym->node_size); - /* Verify that node is clean */ - HDassert(sym->cache_info.is_dirty == FALSE); + /* magic number */ + HDmemcpy(image, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC); + image += H5_SIZEOF_MAGIC; - /* If we're going to free the space on disk, the address must be valid */ - HDassert(!sym->cache_info.free_file_space_on_destroy || H5F_addr_defined(sym->cache_info.addr)); + /* version number */ + *image++ = H5G_NODE_VERS; - /* Check for freeing file space for symbol table node */ - if(sym->cache_info.free_file_space_on_destroy) { - /* Release the space on disk */ - /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, sym->cache_info.addr, (hsize_t)sym->node_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to free symbol table node") - } /* end if */ + /* reserved */ + *image++ = 0; - /* Destroy symbol table node */ - if(H5G__node_free(sym) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node") + /* number of symbols */ + UINT16ENCODE(image, sym->nsyms); + + /* entries */ + if(H5G__ent_encode_vec(f, &image, sym->entry, sym->nsyms) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't serialize") + + /* Clear rest of symbol table node */ + HDmemset(image, 0, sym->node_size - (size_t)(image - (uint8_t *)_image)); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_node_dest() */ +} /* end H5G__cache_node_serialize() */ + + +/***************************************/ +/* no H5G__cache_node_notify() function */ +/***************************************/ /*------------------------------------------------------------------------- - * Function: H5G_node_clear + * Function: H5G__cache_node_free_icr * - * Purpose: Mark a symbol table node in memory as non-dirty. + * Purpose: Destroys a symbol table node in memory. * - * Return: Non-negative on success/Negative on failure + * Note: The metadata cache sets the object's cache_info.magic to + * H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC before calling a free_icr + * callback (checked in assert). * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 20 2003 + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: John Mainzer + * 6/21/14 * *------------------------------------------------------------------------- */ static herr_t -H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy) +H5G__cache_node_free_icr(void *_thing) { - herr_t ret_value = SUCCEED; + H5G_node_t *sym = (H5G_node_t *)_thing; /* Pointer to the object */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* - * Check arguments. - */ + /* Sanity checks */ HDassert(sym); + HDassert(sym->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC); + HDassert(sym->cache_info.type == H5AC_SNODE); - /* Reset the node's dirty flag */ - sym->cache_info.is_dirty = FALSE; - - /* - * Destroy the symbol node? This might happen if the node is being - * preempted from the cache. - */ - if(destroy) - if(H5G_node_dest(f, sym) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node") + /* Destroy symbol table node */ + if(H5G__node_free(sym) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_node_clear() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_node_size - * - * Purpose: Compute the size in bytes of the specified instance of - * H5G_node_t on disk, and return it in *size_ptr. On failure - * the value of size_ptr is undefined. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 5/13/04 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_node_size(const H5F_t H5_ATTR_UNUSED *f, const H5G_node_t *sym, size_t *size_ptr) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* - * Check arguments. - */ - HDassert(f); - HDassert(size_ptr); - - *size_ptr = sym->node_size; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5G_node_size() */ +} /* end H5G__cache_node_free_icr() */ |