diff --git a/src/h5core/h5_core_private.h b/src/h5core/h5_core_private.h index b750fbb..2f171c1 100644 --- a/src/h5core/h5_core_private.h +++ b/src/h5core/h5_core_private.h @@ -7,10 +7,14 @@ #define H5_CORE_API_RETURN(retval) \ \ - goto exit; \ - exit: \ + goto done; \ +done: \ return (retval); \ +#define H5_GOTO_DONE( ret_val) \ + ret_value = ret_val; \ + goto done; \ + /* WARNING! Changing these values will alter the data model and introduce * file incompatibilities with previous versions. */ #define H5_DATANAME_LEN 64 diff --git a/src/h5core/h5_hsearch.c b/src/h5core/h5_hsearch.c index 2ee5554..9de693e 100644 --- a/src/h5core/h5_hsearch.c +++ b/src/h5core/h5_hsearch.c @@ -65,11 +65,15 @@ h5priv_hcreate ( size_t nel, h5_hashtable_t* htab, int (*compare)(const void*, const void*), - unsigned int (*compute_hash)(const void*) + unsigned int (*compute_hash)(const void*), + h5_err_t (*free_entry)(h5_file_t* const f, const void*) ) { + H5_CORE_API_ENTER; + h5_err_t h5err = H5_SUCCESS; + /* Test for correct arguments. */ if (htab == NULL || htab->table != NULL) { - return h5_error_internal (f, __FILE__, __func__, __LINE__); + TRY2( h5_error_internal (f, __FILE__, __func__, __LINE__) ); } /* Change nel to the first prime number not smaller as nel. */ nel |= 1; /* make odd */ @@ -80,13 +84,14 @@ h5priv_hcreate ( htab->filled = 0; htab->compare = compare; htab->compute_hash = compute_hash; + htab->free_entry = free_entry; /* allocate memory and zero out */ - TRY( (htab->table = (_ENTRY *) h5_calloc ( + TRY2( (htab->table = (_ENTRY *) h5_calloc ( f, htab->size + 1, sizeof (_ENTRY))) ); /* everything went alright */ - return H5_SUCCESS; + H5_CORE_API_RETURN (h5err); } /* @@ -98,8 +103,10 @@ h5priv_hresize ( size_t nel, // number of entries to grow h5_hashtable_t* htab // hash table to resize ) { + H5_CORE_API_ENTER; + h5_err_t h5err = H5_SUCCESS; if (htab == NULL || htab->table == NULL) { - return h5_error_internal (f, __FILE__, __func__, __LINE__); + TRY2( h5_error_internal (f, __FILE__, __func__, __LINE__) ); } // create new hash table h5_hashtable_t __htab; @@ -107,28 +114,47 @@ h5priv_hresize ( nel += htab->size; h5_debug (f, "Resize hash table from %u to %lu elements.", htab->size, nel); - TRY( h5priv_hcreate ( - f, nel, &__htab, htab->compare, htab->compute_hash) ); + TRY2( h5priv_hcreate (f, nel, &__htab, htab->compare, + htab->compute_hash, htab->free_entry) ); // add all entries to new hash table unsigned int idx; for (idx = 1; idx <= htab->size; idx++) { if (htab->table[idx].used) { void* ventry; - h5priv_hsearch ( + TRY2( h5priv_hsearch ( f, htab->table[idx].entry, H5_ENTER, &ventry, - &__htab); + &__htab) ); } } - // destroy old hash table - TRY (h5priv_hdestroy (f, htab) ); + /* Free used memory. */ + TRY2( h5_free (f, htab->table) ); + + /* the sign for an existing table is an value != NULL in htable */ + htab->table = NULL; *htab = __htab; + H5_CORE_API_RETURN (h5err); +} + +static inline h5_err_t +hwalk ( + h5_file_t* const f, + struct hsearch_data* htab, + h5_err_t (*visit)(h5_file_t*const f, const void *item) + ) { + unsigned int idx = 1; + for (idx = 1; idx < htab->size; idx++) { + if (htab->table[idx].used) { + TRY( (*visit)(f, &htab->table[idx].entry) ); + } + } return H5_SUCCESS; } + /* After using the hash table it has to be destroyed. The used memory can be freed and the local static variable can be marked as not used. */ h5_err_t @@ -136,17 +162,21 @@ h5priv_hdestroy ( h5_file_t* const f, struct hsearch_data* htab ) { + H5_CORE_API_ENTER; + h5_err_t ret_value = H5_SUCCESS; /* Test for correct arguments. */ if (htab == NULL) { - return h5_error_internal (f, __FILE__, __func__, __LINE__); + TRY2( h5_error_internal (f, __FILE__, __func__, __LINE__) ); } + TRY2( hwalk (f, htab, htab->free_entry) ); + /* Free used memory. */ - TRY( h5_free (f, htab->table) ); + TRY2( h5_free (f, htab->table) ); /* the sign for an existing table is an value != NULL in htable */ htab->table = NULL; - return H5_SUCCESS; + H5_CORE_API_RETURN (ret_value); } @@ -172,6 +202,8 @@ h5priv_hsearch ( void** retval, struct hsearch_data* htab ) { + H5_CORE_API_ENTER; + h5_err_t ret_value = H5_SUCCESS; unsigned int hval; unsigned int idx; @@ -189,7 +221,7 @@ h5priv_hsearch ( if (retval) { *retval = htab->table[idx].entry; } - return H5_SUCCESS; + H5_GOTO_DONE (H5_SUCCESS); } /* Second hash function, as suggested in [Knuth] */ @@ -216,7 +248,7 @@ h5priv_hsearch ( if (retval) { *retval = htab->table[idx].entry; } - return H5_SUCCESS; + H5_GOTO_DONE (H5_SUCCESS); } } while (htab->table[idx].used); } @@ -230,7 +262,7 @@ h5priv_hsearch ( if (retval) { *retval = NULL; } - return H5_ERR; + H5_GOTO_DONE (H5_ERR); } htab->table[idx].used = hval; @@ -241,30 +273,16 @@ h5priv_hsearch ( if (retval) { *retval = htab->table[idx].entry; } - return H5_SUCCESS; + H5_GOTO_DONE (H5_SUCCESS); } else if (action == H5_REMOVE) { htab->table[idx].used = 0; /* mark as unused, but */ *retval = htab->table[idx].entry; /* return ptr to entry */ - return H5_SUCCESS; + H5_GOTO_DONE (H5_SUCCESS); } - *retval = NULL; + if (retval) *retval = NULL; h5_debug (f, "Key not found in hash table."); - return H5_NOK; -} - -h5_err_t -h5priv_hwalk ( - h5_file_t* const f, - struct hsearch_data* htab, - h5_err_t (*visit)(h5_file_t*const f, const void *item) - ) { - unsigned int idx = 1; - for (idx = 1; idx < htab->size; idx++) { - if (htab->table[idx].used) { - TRY( (*visit)(f, &htab->table[idx].entry) ); - } - } - return H5_SUCCESS; + ret_value = H5_NOK; + H5_CORE_API_RETURN (ret_value); } typedef struct { @@ -272,7 +290,7 @@ typedef struct { } h5_hitem_string_keyed_t; static int -_hcmp_string_keyed ( +cmp_string_keyed ( const void* __a, const void* __b ) { @@ -282,38 +300,55 @@ _hcmp_string_keyed ( } static unsigned int -_hcompute_string_keyed ( - const void* __item +compute_string_keyed ( + const void* __entry ) { - h5_hitem_string_keyed_t* item = (h5_hitem_string_keyed_t*) __item; - unsigned int len = strlen (item->key); + h5_hitem_string_keyed_t* entry = (h5_hitem_string_keyed_t*) __entry; + unsigned int len = strlen (entry->key); unsigned int hval = len; unsigned int count = len; while (count-- > 0) { hval <<= 4; - hval += item->key[count]; + hval += entry->key[count]; } return hval; } +static h5_err_t +free_string_keyed ( + h5_file_t* const f, + const void* __entry + ) { + h5_hitem_string_keyed_t* entry = (h5_hitem_string_keyed_t*) __entry; + TRY( h5_free (f, entry->key) ); + TRY( h5_free (f, entry) ); + return H5_SUCCESS; +} + h5_err_t h5priv_hcreate_string_keyed ( h5_file_t* const f, size_t nel, - h5_hashtable_t* htab + h5_hashtable_t* htab, + h5_err_t (*free_entry)(h5_file_t* const f, const void*) ) { - return h5priv_hcreate (f, nel, htab, - _hcmp_string_keyed, _hcompute_string_keyed); -} - -static int -hcmp_loc_id_keyed ( - const void* __a, - const void* __b - ) { - return memcmp (__a, __b, sizeof(h5_loc_id_t)); + H5_CORE_API_ENTER; + h5_err_t ret_value = H5_SUCCESS; + if (free_entry == NULL) { + TRY2( ret_value = h5priv_hcreate (f, nel, htab, + cmp_string_keyed, + compute_string_keyed, + free_string_keyed) ); + } else { + TRY2( ret_value = h5priv_hcreate (f, nel, htab, + cmp_string_keyed, + compute_string_keyed, + free_entry) ); + } + H5_CORE_API_RETURN (ret_value); } +#if 0 static unsigned int hcompute_loc_id_keyed ( const void*__item @@ -330,13 +365,4 @@ hcompute_loc_id_keyed ( } return hval; } - -h5_err_t -h5priv_hcreate_loc_id_keyed ( - h5_file_t* const f, - size_t nel, - h5_hashtable_t* htab - ) { - return h5priv_hcreate (f, nel, htab, - hcmp_loc_id_keyed, hcompute_loc_id_keyed); -} +#endif diff --git a/src/h5core/h5_hsearch_private.h b/src/h5core/h5_hsearch_private.h index f0b333a..d779b5f 100644 --- a/src/h5core/h5_hsearch_private.h +++ b/src/h5core/h5_hsearch_private.h @@ -7,6 +7,7 @@ typedef struct hsearch_data { unsigned int filled; int (*compare)(const void*, const void*); unsigned int (*compute_hash)(const void*); + h5_err_t (*free_entry)(h5_file_t* const f, const void*); } h5_hashtable_t; /* Action which shall be performed in the call to hsearch. */ @@ -37,7 +38,8 @@ h5priv_hcreate ( size_t __nel, h5_hashtable_t* __htab, int (*compare)(const void*, const void*), - unsigned int (*compute_hash)(const void*) + unsigned int (*compute_hash)(const void*), + h5_err_t (*free_entry)(h5_file_t* const f, const void*) ); extern h5_err_t @@ -53,25 +55,12 @@ h5priv_hdestroy ( h5_hashtable_t* __htab ); -extern h5_err_t -h5priv_hwalk ( - h5_file_t* f, - h5_hashtable_t* __htab, - h5_err_t (*visit)(h5_file_t* const f, const void* __item) - ); - extern h5_err_t h5priv_hcreate_string_keyed ( h5_file_t* const f, size_t nel, - h5_hashtable_t* htab - ); - -h5_err_t -h5priv_hcreate_loc_id_keyed ( - h5_file_t* const f, - size_t nel, - h5_hashtable_t* htab + h5_hashtable_t* htab, + h5_err_t (*free_entry)(h5_file_t* const f, const void*) ); #endif diff --git a/src/h5core/h5_maps.c b/src/h5core/h5_maps.c index ac967c0..47394ba 100644 --- a/src/h5core/h5_maps.c +++ b/src/h5core/h5_maps.c @@ -39,10 +39,11 @@ static inline h5_err_t grow_idlist ( h5_file_t* const f, h5_idlist_t** list, - size_t num_items + size_t new_size ) { - size_t size = sizeof (**list) + (num_items-1)*sizeof((*list)->items[0]); - TRY( *list = h5_alloc (f, *list, size) ); + size_t bytes_to_allocate = sizeof (**list) + (new_size-1)*sizeof((*list)->items[0]); + TRY( *list = h5_alloc (f, *list, bytes_to_allocate) ); + (*list)->size = new_size; return H5_SUCCESS; } diff --git a/src/h5core/h5t_access_tetm.c b/src/h5core/h5t_access_tetm.c index fad1662..7f0b68c 100644 --- a/src/h5core/h5t_access_tetm.c +++ b/src/h5core/h5t_access_tetm.c @@ -7,7 +7,8 @@ get_loc_elem ( h5_file_t* const f, const h5_loc_idx_t elem_idx ) { - return (h5_generic_loc_elem_t*)&f->t->loc_elems.tets[elem_idx]; + h5_loc_tet_t* elem = &f->t->loc_elems.tets[elem_idx]; + return (h5_generic_loc_elem_t*)elem; } static h5_loc_idx_t diff --git a/src/h5core/h5t_adjacencies_tetm.c b/src/h5core/h5t_adjacencies_tetm.c index 04157c8..7a36f37 100644 --- a/src/h5core/h5t_adjacencies_tetm.c +++ b/src/h5core/h5t_adjacencies_tetm.c @@ -20,14 +20,18 @@ static inline h5_err_t alloc_tv ( - h5_file_t* const f + h5_file_t* const f, + const h5t_lvl_idx_t from_lvl ) { h5t_fdata_t* t = f->t; h5_loc_idx_t num_vertices = t->num_vertices[t->num_leaf_levels-1]; h5t_adjacencies_t* adj = &t->adjacencies; - // allocate one ID list per vertex - TRY( adj->tv.v = h5_calloc (f, num_vertices, sizeof(*adj->tv.v)) ); + // allocate ptr to ID-list per vertex + TRY( adj->tv.v = h5_alloc (f, adj->tv.v, num_vertices*sizeof(*adj->tv.v)) ); + + size_t i = from_lvl <= 0 ? 0 : t->num_vertices[from_lvl-1]; + bzero (adj->tv.v+i, (num_vertices-i)*sizeof(*adj->tv.v)); return H5_SUCCESS; } @@ -59,7 +63,7 @@ compute_elems_of_vertices ( const h5t_lvl_idx_t from_lvl ) { /* expand structure */ - TRY( alloc_tv (f) ); + TRY( alloc_tv (f, from_lvl) ); /* loop over all elements in current level */ h5t_fdata_t* t = f->t; @@ -81,24 +85,6 @@ compute_elems_of_vertices ( return H5_SUCCESS; } -static h5_err_t -free_idlist ( - h5_file_t * const f, - const void* __list - ) { - h5_idlist_t* list = *(h5_idlist_t**)__list; - TRY( h5priv_free_idlist (f, &list) ); - return H5_SUCCESS; -} - -static inline h5_err_t -release_te ( - h5_file_t* const f - ) { - TRY( h5priv_hwalk (f, &f->t->adjacencies.te_hash, free_idlist) ); - return H5_SUCCESS; -} - /* Compute T(E) from current level up to highest levels. */ @@ -123,14 +109,6 @@ compute_elems_of_edges ( return H5_SUCCESS; } -static inline h5_err_t -release_td ( - h5_file_t* const f - ) { - TRY( h5priv_hwalk (f, &f->t->adjacencies.te_hash, free_idlist) ); - return H5_SUCCESS; -} - static inline h5_err_t compute_elems_of_triangles ( h5_file_t* const f, @@ -878,8 +856,8 @@ release_internal_structs ( ) { h5t_fdata_t* t = f->t; TRY( release_tv (f) ); - TRY( release_te (f) ); - TRY( release_td (f) ); + TRY( h5priv_hdestroy (f, &t->adjacencies.te_hash) ); + TRY( h5priv_hdestroy (f, &t->adjacencies.td_hash) ); bzero (&t->adjacencies, sizeof (t->adjacencies)); return H5_SUCCESS; } diff --git a/src/h5core/h5t_adjacencies_trim.c b/src/h5core/h5t_adjacencies_trim.c index 246db3a..627828e 100644 --- a/src/h5core/h5t_adjacencies_trim.c +++ b/src/h5core/h5t_adjacencies_trim.c @@ -19,14 +19,18 @@ static inline h5_err_t alloc_tv ( - h5_file_t* const f + h5_file_t* const f, + const h5t_lvl_idx_t from_lvl ) { h5t_fdata_t* t = f->t; h5_loc_idx_t num_vertices = t->num_vertices[t->num_leaf_levels-1]; h5t_adjacencies_t* adj = &t->adjacencies; - // allocate one ID list per vertex - TRY( adj->tv.v = h5_calloc (f, num_vertices, sizeof(*adj->tv.v)) ); + // allocate ptr to ID-list per vertex + TRY( adj->tv.v = h5_alloc (f, adj->tv.v, num_vertices*sizeof(*adj->tv.v)) ); + + size_t i = from_lvl <= 0 ? 0 : t->num_vertices[from_lvl-1]; + bzero (adj->tv.v+i, (num_vertices-i)*sizeof(*adj->tv.v)); return H5_SUCCESS; } @@ -57,9 +61,8 @@ compute_elems_of_vertices ( h5_file_t* const f, const h5t_lvl_idx_t from_lvl ) { - h5_debug (f, "%s (%lld)", __func__, (long long)from_lvl); /* expand structure */ - TRY( alloc_tv (f) ); + TRY( alloc_tv (f, from_lvl) ); /* loop over all elements in current level */ h5t_fdata_t *t = f->t; @@ -74,29 +77,10 @@ compute_elems_of_vertices ( TRY( h5priv_insert_idlist ( f, &t->adjacencies.tv.v[vidx], - h5tpriv_build_vertex_id ( - face_idx, idx), -1) ); + h5tpriv_build_vertex_id (face_idx, idx), + -1) ); } } - h5_debug (f, "%s (%lld): done", __func__, (long long)from_lvl); - return H5_SUCCESS; -} - -static h5_err_t -free_idlist ( - h5_file_t * const f, - const void* __list - ) { - h5_idlist_t* list = *(h5_idlist_t**)__list; - TRY( h5priv_free_idlist (f, &list) ); - return H5_SUCCESS; -} - -static inline h5_err_t -release_te ( - h5_file_t* const f - ) { - TRY( h5priv_hwalk (f, &f->t->adjacencies.te_hash, free_idlist) ); return H5_SUCCESS; } @@ -535,7 +519,7 @@ release_internal_structs ( ) { h5t_fdata_t *t = f->t; TRY( release_tv (f) ); - TRY( release_te (f) ); + TRY( h5priv_hdestroy (f, &t->adjacencies.te_hash) ); bzero (&t->adjacencies, sizeof (t->adjacencies)); return H5_SUCCESS; } diff --git a/src/h5core/h5t_hsearch.c b/src/h5core/h5t_hsearch.c index 8e92109..3696232 100644 --- a/src/h5core/h5t_hsearch.c +++ b/src/h5core/h5t_hsearch.c @@ -30,18 +30,16 @@ compute_te_hashval ( return hval; } -h5_err_t -h5tpriv_create_te_htab ( - h5_file_t* const f, - size_t nel +static h5_err_t +release_te_entry ( + h5_file_t * const f, + const void* __entry ) { - h5t_adjacencies_t* a = &f->t->adjacencies; - return h5priv_hcreate ( - f, - nel, - &a->te_hash, - cmp_te_entries, - compute_te_hashval); + struct h5_te_entry* entry = *(struct h5_te_entry**)__entry; + h5_idlist_t* list = entry->value; + TRY( h5priv_free_idlist (f, &list) ); + TRY( h5_free (f, entry) ); + return H5_SUCCESS; } h5_err_t @@ -51,7 +49,13 @@ h5tpriv_resize_te_htab ( ) { h5t_adjacencies_t* a = &f->t->adjacencies; if ( a->te_hash.size == 0 ) { - TRY( h5tpriv_create_te_htab (f, nel) ); + TRY( h5priv_hcreate ( + f, + nel, + &a->te_hash, + cmp_te_entries, + compute_te_hashval, + release_te_entry) ); } else if (a->te_hash.size < nel) { TRY( h5priv_hresize (f, nel, &a->te_hash) ); } @@ -190,20 +194,19 @@ compute_td_hashval ( return hval; } -h5_err_t -h5tpriv_create_td_htab ( - h5_file_t* const f, - size_t nel +static h5_err_t +release_td_entry ( + h5_file_t * const f, + const void* __entry ) { - h5t_adjacencies_t* a = &f->t->adjacencies; - return h5priv_hcreate ( - f, - nel, - &a->td_hash, - cmp_td_entries, - compute_td_hashval); + struct h5_td_entry* entry = *(struct h5_td_entry**)__entry; + h5_idlist_t* list = entry->value; + TRY( h5priv_free_idlist (f, &list) ); + TRY( h5_free (f, entry) ); + return H5_SUCCESS; } + h5_err_t h5tpriv_resize_td_htab ( h5_file_t* const f, @@ -211,7 +214,13 @@ h5tpriv_resize_td_htab ( ) { h5t_adjacencies_t* a = &f->t->adjacencies; if (a->td_hash.size == 0) { - TRY( h5tpriv_create_td_htab (f, nel) ); + TRY( h5priv_hcreate ( + f, + nel, + &a->td_hash, + cmp_td_entries, + compute_td_hashval, + release_td_entry) ); } else if (a->td_hash.size < nel) { TRY( h5priv_hresize (f, nel, &a->td_hash) ); } diff --git a/src/h5core/h5t_hsearch_private.h b/src/h5core/h5t_hsearch_private.h index a74de82..d9636c7 100644 --- a/src/h5core/h5t_hsearch_private.h +++ b/src/h5core/h5t_hsearch_private.h @@ -32,12 +32,6 @@ typedef struct h5t_idlisthash_entry { h5t_idlisthash_key_t key; } h5t_idlisthash_entry_t; -h5_err_t -h5tpriv_create_te_htab ( - h5_file_t * const f, - size_t nel - ); - h5_err_t h5tpriv_resize_te_htab ( h5_file_t * const f, @@ -67,13 +61,6 @@ h5tpriv_find_te2 ( h5_idlist_t **retval ); - -h5_err_t -h5tpriv_create_td_htab ( - h5_file_t * const f, - size_t nel - ); - h5_err_t h5tpriv_resize_td_htab ( h5_file_t * const f, diff --git a/src/h5core/h5t_tags.c b/src/h5core/h5t_tags.c index 98cac5e..65b0b7f 100644 --- a/src/h5core/h5t_tags.c +++ b/src/h5core/h5t_tags.c @@ -5,28 +5,16 @@ #include "h5_core_private.h" /* - To discuss: + TODO: - read tagsets on demand */ -/* - Initialize a tag container - */ -static h5_err_t -init_container ( - h5_file_t* const f, - const size_t ntags, - h5t_tagcontainer_t* ctn - ) { - ctn->names = h5_calloc (f, ntags, sizeof(char*)); - TRY( h5priv_hcreate_string_keyed (f, ntags, &ctn->sets)); - return H5_SUCCESS; -} + /* Release a tag-set */ -static h5_err_t +static inline h5_err_t release_tagset ( h5_file_t* const f, h5t_tagset_t* tagset @@ -57,6 +45,22 @@ release_tagset2 ( return release_tagset (f, tagset); } + +/* + Initialize a tag container + */ +static inline h5_err_t +init_container ( + h5_file_t* const f, + const size_t ntags, + h5t_tagcontainer_t* ctn + ) { + ctn->names = h5_calloc (f, ntags, sizeof(char*)); + TRY( h5priv_hcreate_string_keyed (f, ntags, &ctn->sets, + release_tagset2) ); + return H5_SUCCESS; +} + /* Release all sets in given container */ @@ -66,7 +70,7 @@ release_container ( h5t_tagcontainer_t* ctn ) { if (ctn->num_sets == 0) return H5_SUCCESS; - TRY( h5priv_hwalk (f, &ctn->sets, release_tagset2) ); + TRY( h5priv_hdestroy (f, &ctn->sets) ); TRY( h5_free (f, ctn->names) ); memset (ctn, 0, sizeof (*ctn)); return H5_SUCCESS; diff --git a/src/h5core/h5t_types_private.h b/src/h5core/h5t_types_private.h index 78c71be..593a998 100644 --- a/src/h5core/h5t_types_private.h +++ b/src/h5core/h5t_types_private.h @@ -40,7 +40,7 @@ typedef struct h5_glb_tetrahedron { typedef h5_glb_tetrahedron_t h5_glb_tet_t; typedef struct h5_loc_tetrahedron { - h5_loc_idx_t glb_idx; + h5_glb_idx_t glb_idx; h5_loc_idx_t parent_idx; h5_loc_idx_t child_idx; h5t_lvl_idx_t level_idx; @@ -62,7 +62,7 @@ typedef struct h5_generic_loc_elem { h5_glb_idx_t glb_idx; h5_loc_idx_t parent_idx; h5_loc_idx_t child_idx; - h5_int32_t level_idx; + h5t_lvl_idx_t level_idx; h5t_lvl_idx_t refinement_level; h5t_elem_flags_t flags; h5_loc_idx_t indices[1];