/** * Calculate distance between two iterators. */ int _hashtable_iterator_distance(_hashtable_iterator_t it_first, _hashtable_iterator_t it_second) { _hashtable_iterator_t it_iter; int n_distance = 0; if(_hashtable_iterator_before(it_first, it_second)) { for(it_iter = it_first; !_hashtable_iterator_equal(it_iter, it_second); it_iter = _hashtable_iterator_next(it_iter)) { n_distance++; } return n_distance; } else if(_hashtable_iterator_before(it_second, it_first)) { for(it_iter = it_second; !_hashtable_iterator_equal(it_iter, it_first); it_iter = _hashtable_iterator_next(it_iter)) { n_distance++; } return -n_distance; } else { return 0; } }
/* * 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); } } }
/** * 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 first iterator is before the second. */ bool_t _hashtable_iterator_before(_hashtable_iterator_t it_first, _hashtable_iterator_t it_second) { _hashtable_iterator_t it_iter; _hashtable_t* pt_hashtable = NULL; assert(_hashtable_iterator_belong_to_hashtable(_HASHTABLE_ITERATOR_HASHTABLE(it_first), it_first)); assert(_hashtable_iterator_belong_to_hashtable(_HASHTABLE_ITERATOR_HASHTABLE(it_second), it_second)); assert(_HASHTABLE_ITERATOR_HASHTABLE(it_first) == _HASHTABLE_ITERATOR_HASHTABLE(it_second)); if(_HASHTABLE_ITERATOR_COREPOS(it_first) == _HASHTABLE_ITERATOR_COREPOS(it_second)) { return false; } pt_hashtable = _HASHTABLE_ITERATOR_HASHTABLE(it_first); for(it_iter = it_first; !_hashtable_iterator_equal(it_iter, _hashtable_end(pt_hashtable)); it_iter = _hashtable_iterator_next(it_iter)) { if(_hashtable_iterator_equal(it_iter, it_second)) { return true; } } if(_hashtable_iterator_equal(it_second, _hashtable_end(pt_hashtable))) { return true; } else { return false; } }
/** * Return iterator reference next element. */ hash_set_iterator_t _hash_set_iterator_next(hash_set_iterator_t it_iter) { assert(_GET_HASH_SET_CONTAINER_TYPE(it_iter) == _HASH_SET_CONTAINER); assert(_GET_HASH_SET_ITERATOR_TYPE(it_iter) == _BIDIRECTIONAL_ITERATOR); return _hashtable_iterator_next(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; }
/** * 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) { _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)); } }
/** * 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)); } }