/** * 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; }
/** * Test the type that saved in the hashtable container is same. */ bool_t _hashtable_same_type(const _hashtable_t* cpt_first, const _hashtable_t* cpt_second) { assert(cpt_first != NULL); assert(cpt_second != NULL); assert(_hashtable_is_inited(cpt_first) || _hashtable_is_created(cpt_first)); assert(_hashtable_is_inited(cpt_second) || _hashtable_is_created(cpt_second)); if (cpt_first == cpt_second) { return true; } return (cpt_first->_t_typeinfo._pt_type == cpt_second->_t_typeinfo._pt_type) && (cpt_first->_t_typeinfo._t_style == cpt_second->_t_typeinfo._t_style) && _type_is_same(_GET_HASHTABLE_TYPE_NAME(cpt_first), _GET_HASHTABLE_TYPE_NAME(cpt_second)); }
/** * Get the bucket count of elements int the hashtable. */ size_t _hashtable_bucket_count(const _hashtable_t* cpt_hashtable) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); return vector_size(&cpt_hashtable->_vec_bucket); }
/** * Get the maximum number of elements int the hashtable. */ size_t _hashtable_max_size(const _hashtable_t* cpt_hashtable) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); return (size_t)(-1) / _GET_HASHTABLE_TYPE_SIZE(cpt_hashtable); }
/** * Test if an hashtable is empty. */ bool_t _hashtable_empty(const _hashtable_t* cpt_hashtable) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); return cpt_hashtable->_t_nodecount == 0 ? true : false; }
/** * Get the number of elements int the hashtable. */ size_t _hashtable_size(const _hashtable_t* cpt_hashtable) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); return cpt_hashtable->_t_nodecount; }
/** * Assign hashtable container. */ void _hashtable_assign(_hashtable_t* pt_dest, const _hashtable_t* cpt_src) { assert(pt_dest != NULL); assert(cpt_src != NULL); assert(_hashtable_is_inited(pt_dest)); assert(_hashtable_is_inited(cpt_src)); assert(_hashtable_same_type_ex(pt_dest, cpt_src)); /* clear all elements */ _hashtable_clear(pt_dest); /* 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)); } }
/* * Erase a range of element in an hashtable. */ void _hashtable_erase_range( _hashtable_t* pt_hashtable, _hashtable_iterator_t it_begin, _hashtable_iterator_t it_end) { _hashtable_iterator_t it_iter; _hashtable_iterator_t it_next; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable)); assert(_hashtable_iterator_belong_to_hashtable(pt_hashtable, it_begin)); assert(_hashtable_iterator_belong_to_hashtable(pt_hashtable, it_end)); assert(_hashtable_iterator_equal(it_begin, it_end) || _hashtable_iterator_before(it_begin, it_end)); it_iter = it_next = it_begin; if(!_hashtable_iterator_equal(it_next, _hashtable_end(pt_hashtable))) { it_next = _hashtable_iterator_next(it_next); } while(!_hashtable_iterator_equal(it_iter, it_end)) { _hashtable_erase_pos(pt_hashtable, it_iter); it_iter = it_next; if(!_hashtable_iterator_equal(it_next, _hashtable_end(pt_hashtable))) { it_next = _hashtable_iterator_next(it_next); } } }
/** * Return the compare function of key. */ binary_function_t _hashtable_key_comp(const _hashtable_t* cpt_hashtable) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); return cpt_hashtable->_bfun_compare; }
/** * Erases all the elements of an hashtable. */ void _hashtable_clear(_hashtable_t* pt_hashtable) { size_t t_bucketcount = 0; size_t i = 0; _hashnode_t* pt_node = NULL; _hashnode_t* pt_deletion = NULL; bool_t b_result = false; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable) || _hashtable_is_created(pt_hashtable)); t_bucketcount = vector_size(&pt_hashtable->_vec_bucket); /* iterator all bucket node */ for(i = 0; i < t_bucketcount; ++i) { /* iterator all element list for one bucket node */ pt_node = *(_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, i); *(_hashnode_t**)vector_at(&pt_hashtable->_vec_bucket, i) = NULL; while(pt_node != NULL) { /* delete each element */ pt_deletion = pt_node; pt_node = pt_node->_pt_next; /* destroy element */ b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_DESTROY_FUNCTION(pt_hashtable)(pt_deletion->_pby_data, &b_result); assert(b_result); _alloc_deallocate(&pt_hashtable->_t_allocator, pt_deletion, _HASHTABLE_NODE_SIZE(_GET_HASHTABLE_TYPE_SIZE(pt_hashtable)), 1); } } pt_hashtable->_t_nodecount = 0; }
/** * Inserts an unique element into a hashtable. */ _hashtable_iterator_t _hashtable_insert_unique(_hashtable_t* pt_hashtable, const void* cpv_value) { _hashtable_iterator_t it_iter; assert(pt_hashtable != NULL); assert(cpv_value != NULL); assert(_hashtable_is_inited(pt_hashtable)); if(_hashtable_empty(pt_hashtable)) { return _hashtable_insert_equal(pt_hashtable, cpv_value); } else { it_iter = _hashtable_find(pt_hashtable, cpv_value); if(!_hashtable_iterator_equal(it_iter, _hashtable_end(pt_hashtable))) { return _hashtable_end(pt_hashtable); } else { return _hashtable_insert_equal(pt_hashtable, cpv_value); } } }
/** * Return the hash function. */ unary_function_t _hashtable_hash(const _hashtable_t* cpt_hashtable) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); return cpt_hashtable->_ufun_hash; }
/** * Return an iterator that addresses the first element in the hashtable. */ _hashtable_iterator_t _hashtable_begin(const _hashtable_t* cpt_hashtable) { vector_iterator_t it_bucket; _hashtable_iterator_t it_iter = _create_hashtable_iterator(); assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); for(it_bucket = vector_begin(&cpt_hashtable->_vec_bucket); !iterator_equal(it_bucket, vector_end(&cpt_hashtable->_vec_bucket)); it_bucket = iterator_next(it_bucket)) { _GET_HASHTABLE_BUCKETPOS(it_iter) = _GET_VECTOR_COREPOS(it_bucket); if(*(_hashnode_t**)_GET_HASHTABLE_BUCKETPOS(it_iter) != NULL) { _GET_HASHTABLE_COREPOS(it_iter) = (_byte_t*)*(_hashnode_t**)_GET_HASHTABLE_BUCKETPOS(it_iter); break; } } if(iterator_equal(it_bucket, vector_end(&cpt_hashtable->_vec_bucket))) { assert(_GET_HASHTABLE_COREPOS(it_iter) == NULL); _GET_HASHTABLE_BUCKETPOS(it_iter) = _GET_VECTOR_COREPOS(it_bucket); } _GET_HASHTABLE_POINTER(it_iter) = (_hashtable_t*)cpt_hashtable; return it_iter; }
/** * Test the type that saved in the hashtable container and referenced by it_iter are same. */ bool_t _hashtable_same_iterator_type(const _hashtable_t* cpt_hashtable, iterator_t it_iter) { assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable) || _hashtable_is_created(cpt_hashtable)); assert(_iterator_is_valid(it_iter)); return _type_is_same_ex(&cpt_hashtable->_t_typeinfo, _iterator_get_typeinfo(it_iter)); }
/** * Tests if the first rb tree is less than the second rb tree. */ bool_t _hashtable_less(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)); assert(_hashtable_same_type_ex(cpt_first, cpt_second)); /* check vector bucket count */ if(vector_size(&cpt_first->_vec_bucket) == vector_size(&cpt_second->_vec_bucket)) { /* 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 = _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); if(b_less) { return true; } b_greater = _GET_HASHTABLE_TYPE_SIZE(cpt_first); _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_greater) { return false; } } } return _hashtable_size(cpt_first) < _hashtable_size(cpt_second) ? true : false; }
/** * Swap the datas of first hashtable and second hashtable. */ void _hashtable_swap(_hashtable_t* pt_first, _hashtable_t* pt_second) { _hashtable_t t_swap; assert(pt_first != NULL); assert(pt_second != NULL); assert(_hashtable_is_inited(pt_first)); assert(_hashtable_is_inited(pt_second)); assert(_hashtable_same_type_ex(pt_first, pt_second)); if (_hashtable_equal(pt_first, pt_second)) { return; } t_swap = *pt_first; *pt_first = *pt_second; *pt_second = t_swap; }
/** * Test the type and compare function that saved in the hashtable container is same. */ bool_t _hashtable_same_type_ex(const _hashtable_t* cpt_first, const _hashtable_t* cpt_second) { assert(cpt_first != NULL); assert(cpt_second != NULL); assert(_hashtable_is_inited(cpt_first) || _hashtable_is_created(cpt_first)); assert(_hashtable_is_inited(cpt_second) || _hashtable_is_created(cpt_second)); if (cpt_first == cpt_second) { return true; } return (cpt_first->_t_typeinfo._pt_type == cpt_second->_t_typeinfo._pt_type) && (cpt_first->_t_typeinfo._t_style == cpt_second->_t_typeinfo._t_style) && (cpt_first->_ufun_hash == cpt_second->_ufun_hash) && (cpt_first->_bfun_compare == cpt_second->_bfun_compare) && vector_size(&cpt_first->_vec_bucket) == vector_size(&cpt_second->_vec_bucket) && _type_is_same(_GET_HASHTABLE_TYPE_NAME(cpt_first), _GET_HASHTABLE_TYPE_NAME(cpt_second)); }
/** * Assign hashtable container. */ void _hashtable_assign(_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_inited(pt_dest)); assert(_hashtable_is_inited(cpt_src)); assert(_hashtable_same_type_ex(pt_dest, cpt_src)); /* clear all elements */ _hashtable_clear(pt_dest); /* 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)); } }
/** * hash auxiliary */ void _hashtable_hash_auxiliary(const _hashtable_t* cpt_hashtable, const void* cpv_input, void* pv_output) { assert(cpt_hashtable != NULL); assert(cpv_input != NULL); assert(pv_output != NULL); assert(_hashtable_is_inited(cpt_hashtable)); if (strncmp(_GET_HASHTABLE_TYPE_NAME(cpt_hashtable), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { *(size_t*)pv_output = strlen(string_c_str((string_t*)cpv_input)); cpt_hashtable->_ufun_hash(string_c_str((string_t*)cpv_input), pv_output); } else { cpt_hashtable->_ufun_hash(cpv_input, pv_output); } }
/** * Inserts an range of unique element into a hashtable. */ void _hashtable_insert_unique_range(_hashtable_t* pt_hashtable, iterator_t it_begin, iterator_t it_end) { iterator_t it_iter; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable)); assert(_hashtable_same_iterator_type(pt_hashtable, it_begin)); assert(_hashtable_same_iterator_type(pt_hashtable, it_end)); assert(iterator_equal(it_begin, it_end) || _iterator_before(it_begin, it_end)); for (it_iter = it_begin; !iterator_equal(it_iter, it_end); it_iter = iterator_next(it_iter)) { _hashtable_insert_unique(pt_hashtable, _iterator_get_pointer_ignore_cstr(it_iter)); } }
/** * 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; } }
/** * Return an iterator that addresses the location succeeding the last element in the hashtable. */ _hashtable_iterator_t _hashtable_end(const _hashtable_t* cpt_hashtable) { vector_iterator_t it_bucket; _hashtable_iterator_t it_iter = _create_hashtable_iterator(); assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); it_bucket = vector_end(&cpt_hashtable->_vec_bucket); _GET_HASHTABLE_BUCKETPOS(it_iter) = _GET_VECTOR_COREPOS(it_bucket); _GET_HASHTABLE_COREPOS(it_iter) = NULL; _GET_HASHTABLE_POINTER(it_iter) = (_hashtable_t*)cpt_hashtable; return it_iter; }
/** * Element compare function auxiliary */ void _hashtable_elem_compare_auxiliary( const _hashtable_t* cpt_hashtable, const void* cpv_first, const void* cpv_second, void* pv_output) { assert(cpt_hashtable != NULL); assert(cpv_first != NULL); assert(cpv_second != NULL); assert(pv_output != NULL); assert(_hashtable_is_inited(cpt_hashtable)); if (strncmp(_GET_HASHTABLE_TYPE_NAME(cpt_hashtable), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0 && cpt_hashtable->_bfun_compare != _GET_HASHTABLE_TYPE_LESS_FUNCTION(cpt_hashtable)) { cpt_hashtable->_bfun_compare(string_c_str((string_t*)cpv_first), string_c_str((string_t*)cpv_second), pv_output); } else { cpt_hashtable->_bfun_compare(cpv_first, cpv_second, pv_output); } }
/** * Inserts an range of unique element into a hashtable. */ void _hashtable_insert_unique_range( _hashtable_t* pt_hashtable, _hashtable_iterator_t it_begin, _hashtable_iterator_t it_end) { _hashtable_iterator_t it_iter; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable)); assert(_hashtable_same_hashtable_iterator_type(pt_hashtable, it_begin)); assert(_hashtable_same_hashtable_iterator_type(pt_hashtable, it_end)); assert(_hashtable_iterator_equal(it_begin, it_end) || _hashtable_iterator_before(it_begin, it_end)); for(it_iter = it_begin; !_hashtable_iterator_equal(it_iter, it_end); it_iter = _hashtable_iterator_next(it_iter)) { _hashtable_insert_unique(pt_hashtable, ((_hashnode_t*)_GET_HASHTABLE_COREPOS(it_iter))->_pby_data); } }
/** * 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)); } }
/* * Erase an element in an hashtable from specificed position. */ void _hashtable_erase_pos(_hashtable_t* pt_hashtable, _hashtable_iterator_t it_pos) { _hashnode_t** ppt_bucket = NULL; _hashnode_t* pt_node = NULL; _hashnode_t* pt_deletion = NULL; bool_t b_result = false; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable)); assert(_hashtable_iterator_belong_to_hashtable(pt_hashtable, it_pos)); assert(!_hashtable_iterator_equal(it_pos, _hashtable_end(pt_hashtable))); /* get the previous node */ ppt_bucket = (_hashnode_t**)_GET_HASHTABLE_BUCKETPOS(it_pos); pt_node = *ppt_bucket; pt_deletion = (_hashnode_t*)_GET_HASHTABLE_COREPOS(it_pos); if(pt_node == pt_deletion) { /* the deletion node is the first node of node list */ *ppt_bucket = pt_node->_pt_next; } else { while(pt_node->_pt_next != NULL) { if(pt_node->_pt_next == pt_deletion) { pt_node->_pt_next = pt_deletion->_pt_next; break; } else { pt_node = pt_node->_pt_next; } } } /* delete the node */ b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_DESTROY_FUNCTION(pt_hashtable)(pt_deletion->_pby_data, &b_result); assert(b_result); _alloc_deallocate( &pt_hashtable->_t_allocator, pt_deletion, _HASHTABLE_NODE_SIZE(_GET_HASHTABLE_TYPE_SIZE(pt_hashtable)), 1); /* update the hashtable size */ pt_hashtable->_t_nodecount--; }
/** * Initialize element auxiliary function */ void _hashtable_init_elem_auxiliary(_hashtable_t* pt_hashtable, _hashnode_t* pt_node) { assert(pt_hashtable != NULL); assert(pt_node != NULL); assert(_hashtable_is_inited(pt_hashtable) || _hashtable_is_created(pt_hashtable)); /* initialize new elements */ if (_GET_HASHTABLE_TYPE_STYLE(pt_hashtable) == _TYPE_CSTL_BUILTIN) { /* get element type name */ char s_elemtypename[_TYPE_NAME_SIZE + 1]; _type_get_elem_typename(_GET_HASHTABLE_TYPE_NAME(pt_hashtable), s_elemtypename); _GET_HASHTABLE_TYPE_INIT_FUNCTION(pt_hashtable)(pt_node->_pby_data, s_elemtypename); } else { bool_t b_result = _GET_HASHTABLE_TYPE_SIZE(pt_hashtable); _GET_HASHTABLE_TYPE_INIT_FUNCTION(pt_hashtable)(pt_node->_pby_data, &b_result); assert(b_result); } }
/** * 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)); } }
/** * Test iterator referenced data is within the hashtable. */ bool_t _hashtable_iterator_belong_to_hashtable(const _hashtable_t* cpt_hashtable, _hashtable_iterator_t it_iter) { vector_iterator_t it_bucket; vector_iterator_t it_begin; vector_iterator_t it_end; assert(cpt_hashtable != NULL); assert(_hashtable_is_inited(cpt_hashtable)); assert(_HASHTABLE_ITERATOR_BUCKETPOS(it_iter) != NULL); assert(_HASHTABLE_ITERATOR_HASHTABLE(it_iter) == cpt_hashtable); /* check for the end node */ it_bucket = vector_end(&cpt_hashtable->_vec_bucket); if (_VECTOR_ITERATOR_COREPOS(it_bucket) == _HASHTABLE_ITERATOR_BUCKETPOS(it_iter) && _HASHTABLE_ITERATOR_COREPOS(it_iter) == NULL) { return true; } else { _hashnode_t* pt_node = NULL; it_begin = vector_begin(&cpt_hashtable->_vec_bucket); it_end = vector_end(&cpt_hashtable->_vec_bucket); for (it_bucket = it_begin; !iterator_equal(it_bucket, it_end); it_bucket = iterator_next(it_bucket)) { if (_HASHTABLE_ITERATOR_BUCKETPOS(it_iter) == _VECTOR_ITERATOR_COREPOS(it_bucket)) { pt_node = *(_hashnode_t**)_VECTOR_ITERATOR_COREPOS(it_bucket); while (pt_node != NULL) { if (pt_node == (_hashnode_t*)_HASHTABLE_ITERATOR_COREPOS(it_iter)) { return true; } pt_node = pt_node->_pt_next; } } } return false; } }
/** * Inserts an array of unique element into a hashtable. */ void _hashtable_insert_unique_array(_hashtable_t* pt_hashtable, const void* cpv_array, size_t t_count) { size_t i = 0; assert(pt_hashtable != NULL); assert(_hashtable_is_inited(pt_hashtable)); assert(cpv_array != NULL); /* * Copy the elements from src array to dest hashtable * The array of c builtin and user define or cstl builtin are different, * the elements of c builtin array are element itself, but the elements of * c string, user define or cstl are pointer of element. */ if (strncmp(_GET_HASHTABLE_TYPE_BASENAME(pt_hashtable), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { /* * We need built a string_t for c string element. */ string_t* pstr_elem = create_string(); assert(pstr_elem != NULL); string_init(pstr_elem); for (i = 0; i < t_count; ++i) { string_assign_cstr(pstr_elem, *((const char**)cpv_array + i)); _hashtable_insert_unique(pt_hashtable, pstr_elem); } string_destroy(pstr_elem); } else if (_GET_HASHTABLE_TYPE_STYLE(pt_hashtable) == _TYPE_C_BUILTIN) { for (i = 0; i < t_count; ++i) { _hashtable_insert_unique(pt_hashtable, (unsigned char*)cpv_array + i * _GET_HASHTABLE_TYPE_SIZE(pt_hashtable)); } } else { for (i = 0; i < t_count; ++i) { _hashtable_insert_unique(pt_hashtable, *((void**)cpv_array + i)); } } }