/** * Resize bucket count of hash map. */ void hash_multimap_resize(hash_multimap_t* phmmap_map, size_t t_resize) { assert(phmmap_map != NULL); assert(_pair_is_inited(&phmmap_map->_pair_temp)); _hashtable_resize(&phmmap_map->_t_hashtable, t_resize); }
void hashtable_put( HashTable * h_table, void * key, size_t key_len, void * value, size_t value_len, bool thr_safe) { pthread_mutex_t* ht_mutex = NULL; if(thr_safe){ //slog(DEBUG,LOG_UTIL,"Before mutex lock in put"); ht_mutex = h_table->ht_mutex; //try to replace existing key's value if possible pthread_mutex_lock(ht_mutex); } int res = _hashtable_replace(h_table, key, key_len, value, value_len); if (res == 0) { // resize if needed. double load = ((double) h_table->count) / ((double) h_table->size); if (load > h_table->max_load) { _hashtable_resize(h_table); } //code to add key and value in O(1) time. uint32_t hash_val = h_table->hash(key, key_len); uint32_t index = hash_val % h_table->size; HNode * prev_head = h_table->table[index]; HNode * new_head = hnode_new( key, key_len, value, value_len, h_table->deleteKey, h_table->deleteValue ); new_head->next = prev_head; h_table->table[index] = new_head; h_table->count = h_table->count + 1; } if(thr_safe){ pthread_mutex_unlock(ht_mutex); //slog(DEBUG,LOG_UTIL,"After mutex unlock in put"); } }
/** * Resize. */ void hash_set_resize(hash_set_t* phset_set, size_t t_resize) { assert(phset_set != NULL); _hashtable_resize(&phset_set->_t_hashtable, t_resize); }
/** * 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; }