static switch_l3_hash_t *switch_l3_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr, switch_handle_t interface) { switch_l3_hash_t *hash_entry = NULL; unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; unsigned int len = 0; uint32_t hash; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); hash_entry = switch_malloc(sizeof(switch_l3_hash_t), 1); if (!hash_entry) { return NULL; } memcpy(hash_entry->key, key, SWITCH_L3_HASH_KEY_SIZE); hash_entry->path_count = 1; if (!switch_l3_host_entry(ip_addr)) { status = switch_l3_insert_into_lpm_trie(vrf, ip_addr, hash_entry); if (status != SWITCH_STATUS_SUCCESS) { switch_free(hash_entry); return NULL; } } tommy_hashtable_insert( &switch_l3_hash_table, &(hash_entry->node), hash_entry, hash); switch_l3_insert_into_vrf_list(hash_entry); return hash_entry; }
static uint16_t switch_dmac_rewrite_insert_hash(switch_device_t device, switch_mac_addr_t *mac) { unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; unsigned int len = 0; uint32_t hash = 0; uint16_t mac_index = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_dmac_rewrite_t *dmac_rewrite = NULL; dmac_rewrite = switch_dmac_rewrite_search_hash(mac); if (dmac_rewrite) { mac_index = dmac_rewrite->index; dmac_rewrite->ref_count++; } else { switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); dmac_rewrite = switch_malloc(sizeof(switch_dmac_rewrite_t), 1); if (!dmac_rewrite) { return mac_index; } mac_index = switch_api_id_allocator_allocate(dmac_rewrite_index_allocator); memcpy(&dmac_rewrite->mac, mac, sizeof(switch_mac_addr_t)); dmac_rewrite->index = mac_index; dmac_rewrite->ref_count = 1; status = switch_pd_tunnel_dmac_rewrite_table_add_entry( device, mac_index, mac, &dmac_rewrite->rewrite_entry); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR( "%s:%d: unable to add tunnel dmac entry!", __FUNCTION__, __LINE__); return mac_index; } tommy_hashtable_insert( &switch_dmac_rewrite_table, &(dmac_rewrite->node), dmac_rewrite, hash); } return mac_index; }
/* 0: inserted 1: not enough space in cache */ int tcam_cache_insert(tcam_cache_t *cache, uint8_t *key, void *data) { pthread_mutex_lock(&cache->lock); if(cache->nb_entries == cache->size) { pthread_mutex_unlock(&cache->lock); return 1; } int i; cache_entry_t *entry = NULL; int trailing_ones; for(i = 0; i < cache->bitmap_size; i++) { trailing_ones = __builtin_ctzl(~cache->bitmap_used[i]); if(trailing_ones != sizeof(unsigned long)) { entry = &cache->entries[sizeof(unsigned long) * i + trailing_ones]; cache->bitmap_used[i] |= (1 << trailing_ones); break; } } entry->last_access = time(NULL); entry->key = key; entry->key_size = cache->key_size; entry->data = data; uint32_t hash = hashlittle(key, cache->key_size, 0); tommy_hashtable_insert(&cache->hashtable, &entry->node, entry, hash); cache->nb_entries++; pthread_mutex_unlock(&cache->lock); return 0; }
static void switch_smac_rewrite_hash_insert(switch_smac_entry_t *smac_entry) { unsigned char key[ETH_LEN]; unsigned int len = 0; uint32_t hash; switch_smac_rewrite_hash_key_init(key, &smac_entry->mac, &len, &hash); tommy_hashtable_insert(&smac_rewrite_table, &(smac_entry->node), smac_entry, hash); }
static switch_status_t switch_nhop_insert_hash(switch_spath_info_t *spath_info, switch_nhop_key_t *nhop_key, switch_handle_t nhop_handle) { switch_nhop_key_t *temp_nhop_key = NULL; unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; uint32_t len = 0; uint32_t hash = 0; temp_nhop_key = &spath_info->nhop_key; memset(temp_nhop_key, 0, sizeof(switch_nhop_key_t)); memcpy(temp_nhop_key, nhop_key, sizeof(switch_nhop_key_t)); spath_info->nhop_handle = nhop_handle; switch_nhop_hash_key_init(key, temp_nhop_key, &len, &hash); tommy_hashtable_insert(&switch_nhop_hash_table, &(spath_info->node), spath_info, hash); return SWITCH_STATUS_SUCCESS; }
void pcore_hash_insert(phash_pool pool, const puint32 value, void* const data) { if (!pool) { plog_error("%s(): Нет phash_pool!", __PRETTY_FUNCTION__); return; } plog_dbg("%s(): Вставка ресурсов со значением '%d'", __PRETTY_FUNCTION__, value); phash_object object = pcore_hash_newObject(value, data); tommy_list_insert_tail(pool->list, &object->list_node, object); switch (pool->type) { case PHASH_FAST_SEARCH: tommy_hashdyn_insert((tommy_hashdyn *)pool->hash_struct, &object->hash_node, object, tommy_inthash_u32(object->value)); break; case PHASH_FAST_INSERT: default: tommy_hashtable_insert((tommy_hashtable *)pool->hash_struct, &object->hash_node, object, tommy_inthash_u32(object->value)); break; } }
static switch_status_t switch_neighbor_dmac_insert_hash( switch_device_t device, switch_handle_t bd_handle, switch_mac_addr_t *mac, switch_handle_t neighbor_handle) { unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; unsigned int len = 0; uint32_t hash = 0; uint16_t mac_index = 0; switch_neighbor_dmac_t *neighbor_dmac = NULL; switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash); neighbor_dmac = switch_malloc(sizeof(switch_neighbor_dmac_t), 1); if (!neighbor_dmac) { return mac_index; } memcpy(&neighbor_dmac->mac, mac, sizeof(switch_mac_addr_t)); neighbor_dmac->handle = bd_handle; neighbor_dmac->neighbor_handle = neighbor_handle; tommy_hashtable_insert( &switch_neighbor_dmac_table, &(neighbor_dmac->node), neighbor_dmac, hash); return SWITCH_STATUS_SUCCESS; }
void test_hashtable(void) { tommy_list list; tommy_hashtable hashtable; struct object_hash* HASH; unsigned i, n; tommy_node* p; unsigned limit; unsigned count; HASH = malloc(MAX * sizeof(struct object_hash)); for(i=0;i<MAX;++i) { HASH[i].value = i; } START("hashtable stack"); limit = 10 * sqrt(MAX); for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashtable_init(&hashtable, limit / 2); /* insert */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashtable_insert(&hashtable, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashtable_foreach_arg(&hashtable, count_arg, &count); if (count != n) abort(); /* remove */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashtable_remove_existing(&hashtable, &obj->hashnode); } tommy_hashtable_done(&hashtable); } STOP(); START("hashtable queue"); limit = sqrt(MAX) / 8; for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashtable_init(&hashtable, limit / 2); /* insert first run */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashtable_insert(&hashtable, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashtable_foreach_arg(&hashtable, count_arg, &count); if (count != n) abort(); /* insert all the others */ for(;i<MAX;++i) { struct object_hash* obj; /* insert one */ tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashtable_insert(&hashtable, &HASH[i].hashnode, &HASH[i], HASH[i].value); /* remove one */ p = tommy_list_head(&list); obj = p->data; tommy_list_remove_existing(&list, p); tommy_hashtable_remove_existing(&hashtable, &obj->hashnode); } /* remove remaining */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashtable_remove_existing(&hashtable, &obj->hashnode); } tommy_hashtable_done(&hashtable); } STOP(); }