/** * Tests if the two rb tree are equal. */ bool_t _hashtable_equal(const _hashtable_t* cpt_first, const _hashtable_t* cpt_second) { _hashtable_iterator_t it_first; _hashtable_iterator_t it_second; bool_t b_less = false; bool_t b_greater = false; assert(cpt_first != NULL); assert(cpt_second != NULL); assert(_hashtable_is_inited(cpt_first)); assert(_hashtable_is_inited(cpt_second)); if(cpt_first == cpt_second) { return true; } /* check type */ if(!_hashtable_same_type_ex(cpt_first, cpt_second)) { return false; } /* check size or bucket count*/ if(_hashtable_size(cpt_first) != _hashtable_size(cpt_second) || _hashtable_bucket_count(cpt_first) != _hashtable_bucket_count(cpt_second)) { return false; } /* check each element */ for(it_first = _hashtable_begin(cpt_first), it_second = _hashtable_begin(cpt_second); !_hashtable_iterator_equal(it_first, _hashtable_end(cpt_first)) && !_hashtable_iterator_equal(it_second, _hashtable_end(cpt_second)); it_first = _hashtable_iterator_next(it_first), it_second = _hashtable_iterator_next(it_second)) { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(cpt_first); _GET_HASHTABLE_TYPE_LESS_FUNCTION(cpt_first)( ((_hashnode_t*)_GET_HASHTABLE_COREPOS(it_first))->_pby_data, ((_hashnode_t*)_GET_HASHTABLE_COREPOS(it_second))->_pby_data, &b_less); _GET_HASHTABLE_TYPE_LESS_FUNCTION(cpt_first)( ((_hashnode_t*)_GET_HASHTABLE_COREPOS(it_second))->_pby_data, ((_hashnode_t*)_GET_HASHTABLE_COREPOS(it_first))->_pby_data, &b_greater); if(b_less || b_greater) { return false; } } assert(_hashtable_iterator_equal(it_first, _hashtable_end(cpt_first)) && _hashtable_iterator_equal(it_second, _hashtable_end(cpt_second))); return true; }
/** * Get the bucket count of elements int the hash_multimap. */ size_t hash_multimap_bucket_count(const hash_multimap_t* cphmmap_map) { assert(cphmmap_map != NULL); assert(_pair_is_inited(&cphmmap_map->_pair_temp)); return _hashtable_bucket_count(&cphmmap_map->_t_hashtable); }
/** * Resize. */ void _hashtable_resize(_hashtable_t* pt_hashtable, size_t t_resize) { size_t t_tmp = 0; size_t t_pos = 0; size_t i = 0; size_t t_bucketcount = 0; _hashnode_t* pt_node = NULL; _hashnode_t* pt_nodelist = NULL; _hashnode_t** ppt_bucket = NULL; assert(pt_hashtable != NULL); if(t_resize > _hashtable_bucket_count(pt_hashtable)) { /* select all element in hash node list */ for(i = 0; i < vector_size(&pt_hashtable->_vec_bucket); ++i) { ppt_bucket = (_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, i); pt_node = *ppt_bucket; while(pt_node != NULL) { *ppt_bucket = pt_node->_pt_next; pt_node->_pt_next = pt_nodelist; pt_nodelist = pt_node; pt_node = *ppt_bucket; } } /* resize vector bucket */ vector_resize(&pt_hashtable->_vec_bucket, _hashtable_get_prime(t_resize)); t_bucketcount = _hashtable_bucket_count(pt_hashtable); /* rehash */ while(pt_nodelist != NULL) { pt_node = pt_nodelist; pt_nodelist = pt_node->_pt_next; t_tmp = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_hash_auxiliary(pt_hashtable, pt_node->_pby_data, &t_tmp); t_pos = t_tmp % t_bucketcount; ppt_bucket = (_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, t_pos); pt_node->_pt_next = *ppt_bucket; *ppt_bucket = pt_node; } } }
/** * Find specific element. */ _hashtable_iterator_t _hashtable_find(const _hashtable_t* cpt_hashtable, const void* cpv_value) { _hashtable_iterator_t it_iter = _create_hashtable_iterator(); size_t t_bucketcount = 0; _hashnode_t* pt_node = NULL; _hashnode_t** ppt_bucket = NULL; size_t t_tmp = 0; size_t t_pos = 0; bool_t b_less = false; bool_t b_greater = false; assert(cpt_hashtable != NULL); assert(cpv_value != NULL); assert(_hashtable_is_inited(cpt_hashtable)); t_bucketcount = _hashtable_bucket_count(cpt_hashtable); t_tmp = _GET_HASHTABLE_TYPE_SIZE(cpt_hashtable); _hashtable_hash_auxiliary(cpt_hashtable, cpv_value, &t_tmp); t_pos = t_tmp % t_bucketcount; ppt_bucket = (_hashnode_t**)vector_at(&cpt_hashtable->_vec_bucket, t_pos); pt_node = *ppt_bucket; while(pt_node != NULL) { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(cpt_hashtable); _hashtable_elem_compare_auxiliary(cpt_hashtable, pt_node->_pby_data, cpv_value, &b_less); _hashtable_elem_compare_auxiliary(cpt_hashtable, cpv_value, pt_node->_pby_data, &b_greater); if(b_less || b_greater) { pt_node = pt_node->_pt_next; } else { break; } } if(pt_node == NULL) { return _hashtable_end(cpt_hashtable); } else { _GET_HASHTABLE_BUCKETPOS(it_iter) = (_byte_t*)ppt_bucket; _GET_HASHTABLE_COREPOS(it_iter) = (_byte_t*)pt_node; _GET_HASHTABLE_POINTER(it_iter) = (_hashtable_t*)cpt_hashtable; return it_iter; } }
/** * Initialize hashtable container with hashtable. */ void _hashtable_init_copy(_hashtable_t* pt_dest, const _hashtable_t* cpt_src) { assert(pt_dest != NULL); assert(cpt_src != NULL); assert(_hashtable_is_created(pt_dest)); assert(_hashtable_is_inited(cpt_src)); assert(_hashtable_same_type(pt_dest, cpt_src)); /* initialize the dest hashtable with src hashtable attribute */ _hashtable_init(pt_dest, _hashtable_bucket_count(cpt_src), cpt_src->_ufun_hash, cpt_src->_bfun_compare); /* insert node from src to dest */ if(!_hashtable_empty(cpt_src)) { _hashtable_insert_equal_range(pt_dest, _hashtable_begin(cpt_src), _hashtable_end(cpt_src)); } }
/** * Initialize hashtable container with hashtable. */ void _hashtable_init_copy(_hashtable_t* pt_dest, const _hashtable_t* cpt_src) { _hashtable_iterator_t it_iter; assert(pt_dest != NULL); assert(cpt_src != NULL); assert(_hashtable_is_created(pt_dest)); assert(_hashtable_is_inited(cpt_src)); assert(_hashtable_same_type(pt_dest, cpt_src)); /* initialize the dest hashtable with src hashtable attribute */ _hashtable_init(pt_dest, _hashtable_bucket_count(cpt_src), cpt_src->_ufun_hash, cpt_src->_bfun_compare); /* insert node from src to dest */ for (it_iter = _hashtable_begin(cpt_src); !_hashtable_iterator_equal(it_iter, _hashtable_end(cpt_src)); it_iter = _hashtable_iterator_next(it_iter)) { _hashtable_insert_equal(pt_dest, _hashtable_iterator_get_pointer_ignore_cstr(it_iter)); } }
/** * Get the bucket number of elements int the hash_set. */ size_t hash_set_bucket_count(const hash_set_t* cphset_set) { assert(cphset_set != NULL); return _hashtable_bucket_count(&cphset_set->_t_hashtable); }
/** * Return an iterator range that is equal to a specific element. */ range_t _hashtable_equal_range(const _hashtable_t* cpt_hashtable, const void* cpv_value) { range_t r_result; size_t t_bucketcount = 0; _hashnode_t* pt_begin = NULL; _hashnode_t* pt_end = NULL; _hashnode_t** ppt_bucket = NULL; size_t t_tmp = 0; size_t t_pos = 0; bool_t b_less = false; bool_t b_greater = false; size_t i = 0; assert(cpt_hashtable != NULL); assert(cpv_value != NULL); assert(_hashtable_is_inited(cpt_hashtable)); r_result.it_begin = _create_hashtable_iterator(); r_result.it_end = _create_hashtable_iterator(); t_bucketcount = _hashtable_bucket_count(cpt_hashtable); t_tmp = _GET_HASHTABLE_TYPE_SIZE(cpt_hashtable); _hashtable_hash_auxiliary(cpt_hashtable, cpv_value, &t_tmp); t_pos = t_tmp % t_bucketcount; ppt_bucket = (_hashnode_t**)vector_at(&cpt_hashtable->_vec_bucket, t_pos); for(pt_begin = *ppt_bucket; pt_begin != NULL; pt_begin = pt_begin->_pt_next) { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(cpt_hashtable); _hashtable_elem_compare_auxiliary(cpt_hashtable, pt_begin->_pby_data, cpv_value, &b_less); _hashtable_elem_compare_auxiliary(cpt_hashtable, cpv_value, pt_begin->_pby_data, &b_greater); if(!b_less && !b_greater) { for(pt_end = pt_begin->_pt_next; pt_end != NULL; pt_end = pt_end->_pt_next) { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(cpt_hashtable); _hashtable_elem_compare_auxiliary(cpt_hashtable, pt_end->_pby_data, cpv_value, &b_less); _hashtable_elem_compare_auxiliary(cpt_hashtable, cpv_value, pt_end->_pby_data, &b_greater); if(b_less || b_greater) { _GET_HASHTABLE_BUCKETPOS(r_result.it_begin) = (_byte_t*)ppt_bucket; _GET_HASHTABLE_COREPOS(r_result.it_begin) = (_byte_t*)pt_begin; _GET_HASHTABLE_POINTER(r_result.it_begin) = (_hashtable_t*)cpt_hashtable; _GET_HASHTABLE_BUCKETPOS(r_result.it_end) = (_byte_t*)ppt_bucket; _GET_HASHTABLE_COREPOS(r_result.it_end) = (_byte_t*)pt_end; _GET_HASHTABLE_POINTER(r_result.it_end) = (_hashtable_t*)cpt_hashtable; return r_result; } } _GET_HASHTABLE_BUCKETPOS(r_result.it_begin) = (_byte_t*)ppt_bucket; _GET_HASHTABLE_COREPOS(r_result.it_begin) = (_byte_t*)pt_begin; _GET_HASHTABLE_POINTER(r_result.it_begin) = (_hashtable_t*)cpt_hashtable; for(i = t_pos + 1; i < t_bucketcount; ++i) { ppt_bucket = (_hashnode_t**)vector_at(&cpt_hashtable->_vec_bucket, i); pt_end = *ppt_bucket; if(pt_end != NULL) { _GET_HASHTABLE_BUCKETPOS(r_result.it_end) = (_byte_t*)ppt_bucket; _GET_HASHTABLE_COREPOS(r_result.it_end) = (_byte_t*)pt_end; _GET_HASHTABLE_POINTER(r_result.it_end) = (_hashtable_t*)cpt_hashtable; return r_result; } } r_result.it_end = _hashtable_end(cpt_hashtable); return r_result; } } r_result.it_begin = _hashtable_end(cpt_hashtable); r_result.it_end = _hashtable_end(cpt_hashtable); return r_result; }
/** * Inserts an element into a hashtable. */ _hashtable_iterator_t _hashtable_insert_equal(_hashtable_t* pt_hashtable, const void* cpv_value) { size_t t_bucketcount = 0; _hashnode_t* pt_node = NULL; _hashnode_t* pt_cur = NULL; _hashnode_t** ppt_nodelist = NULL; _hashtable_iterator_t it_iter = _create_hashtable_iterator(); bool_t b_result = false; size_t t_tmp = 0; size_t t_pos = 0; bool_t b_less = false; bool_t b_greater = false; assert(pt_hashtable != NULL); assert(cpv_value != NULL); assert(_hashtable_is_inited(pt_hashtable)); /* resize */ _hashtable_resize(pt_hashtable, _hashtable_size(pt_hashtable) + 1); /* allocate node */ pt_node = _alloc_allocate( &pt_hashtable->_t_allocator, _HASHTABLE_NODE_SIZE(_GET_HASHTABLE_TYPE_SIZE(pt_hashtable)), 1); assert(pt_node != NULL); _hashtable_init_elem_auxiliary(pt_hashtable, pt_node); b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_COPY_FUNCTION(pt_hashtable)(pt_node->_pby_data, cpv_value, &b_result); assert(b_result); /* hash */ t_bucketcount = _hashtable_bucket_count(pt_hashtable); t_tmp = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_hash_auxiliary(pt_hashtable, pt_node->_pby_data, &t_tmp); t_pos = t_tmp % t_bucketcount; /* insert node into hashtable, note the node has same value together */ ppt_nodelist = (_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, t_pos); assert(ppt_nodelist != NULL); pt_cur = *ppt_nodelist; if(pt_cur == NULL) { pt_node->_pt_next = pt_cur; *ppt_nodelist = pt_node; } else { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_elem_compare_auxiliary(pt_hashtable, pt_cur->_pby_data, pt_node->_pby_data, &b_less); _hashtable_elem_compare_auxiliary(pt_hashtable, pt_node->_pby_data, pt_cur->_pby_data, &b_greater); if(!b_less && !b_greater) { pt_node->_pt_next = pt_cur; *ppt_nodelist = pt_node; } else { while(pt_cur->_pt_next != NULL) { b_less = b_greater = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _hashtable_elem_compare_auxiliary( pt_hashtable, pt_cur->_pt_next->_pby_data, pt_node->_pby_data, &b_less); _hashtable_elem_compare_auxiliary( pt_hashtable, pt_node->_pby_data, pt_cur->_pt_next->_pby_data, &b_greater); if(b_less || b_greater) { pt_cur = pt_cur->_pt_next; } else { break; } } pt_node->_pt_next = pt_cur->_pt_next; pt_cur->_pt_next = pt_node; } } pt_hashtable->_t_nodecount++; _GET_HASHTABLE_BUCKETPOS(it_iter) = (_byte_t*)ppt_nodelist; _GET_HASHTABLE_COREPOS(it_iter) = (_byte_t*)pt_node; _GET_HASHTABLE_POINTER(it_iter) = pt_hashtable; return it_iter; }