static void resize(struct hmap *hmap, size_t new_mask) { struct hmap tmp; size_t i; assert(!(new_mask & (new_mask + 1))); assert(new_mask != SIZE_MAX); hmap_init(&tmp); if (new_mask) { tmp.buckets = xmalloc(sizeof *tmp.buckets * (new_mask + 1)); tmp.mask = new_mask; for (i = 0; i <= tmp.mask; i++) { tmp.buckets[i] = NULL; } } for (i = 0; i <= hmap->mask; i++) { struct hmap_node *node, *next; for (node = hmap->buckets[i]; node; node = next) { next = node->next; hmap_insert_fast(&tmp, node, node->hash); } } hmap_swap(hmap, &tmp); hmap_destroy(&tmp); }
/* Handles group_mod messages with MODIFY command. */ static ofl_err group_table_modify(struct group_table *table, struct ofl_msg_group_mod *mod) { struct group_entry *entry, *new_entry; entry = group_table_find(table, mod->group_id); if (entry == NULL) { return ofl_error(OFPET_GROUP_MOD_FAILED, OFPGMFC_UNKNOWN_GROUP); } if (table->buckets_num - entry->desc->buckets_num + mod->buckets_num > GROUP_TABLE_MAX_BUCKETS) { return ofl_error(OFPET_GROUP_MOD_FAILED, OFPGMFC_OUT_OF_BUCKETS); } if (!is_loop_free(table, entry)) { return ofl_error(OFPET_GROUP_MOD_FAILED, OFPGMFC_LOOP); } new_entry = group_entry_create(table->dp, table, mod); hmap_remove(&table->entries, &entry->node); hmap_insert_fast(&table->entries, &new_entry->node, mod->group_id); table->buckets_num = table->buckets_num - entry->desc->buckets_num + new_entry->desc->buckets_num; group_entry_destroy(entry); ofl_msg_free_group_mod(mod, false, table->dp->exp); return 0; }
/* Handles meter_mod messages with MODIFY command. */ static ofl_err meter_table_modify(struct meter_table *table, struct ofl_msg_meter_mod *mod) { struct meter_entry *entry, *new_entry; entry = meter_table_find(table, mod->meter_id); if (entry == NULL) { return ofl_error(OFPET_METER_MOD_FAILED, OFPMMFC_UNKNOWN_METER); } if (table->bands_num - entry->config->meter_bands_num + mod->meter_bands_num > METER_TABLE_MAX_BANDS) { return ofl_error(OFPET_METER_MOD_FAILED, OFPMMFC_OUT_OF_BANDS); } new_entry = meter_entry_create(table->dp, table, mod); hmap_remove(&table->meter_entries, &entry->node); hmap_insert_fast(&table->meter_entries, &new_entry->node, mod->meter_id); table->bands_num = table->bands_num - entry->config->meter_bands_num + new_entry->stats->meter_bands_num; /* keep flow references from old meter entry */ list_replace(&new_entry->flow_refs, &entry->flow_refs); list_init(&entry->flow_refs); meter_entry_destroy(entry); ofl_msg_free_meter_mod(mod, false); return 0; }
int main(int argc, char **argv) { struct hmap *map = malloc(sizeof(*map)); hmap_init(map); struct hmap_node node2 = {1, NULL}; hmap_insert_fast(map, &nodes[0].node, strlen(nodes[0].key)); hmap_insert_fast(map, &nodes[1].node, strlen(nodes[1].key)); struct nd *q; //HMAP_FOR_EACH(q, node, map) { // printf("key= %s",q->key); //} printf("map size %lu, capacity %lu\n", hmap_count(map), hmap_capacity(map)); hmap_destroy(map); }
static void resize(struct hmap *hmap, size_t new_mask, const char *where) { struct hmap tmp; size_t i; ovs_assert(is_pow2(new_mask + 1)); hmap_init(&tmp); if (new_mask) { tmp.buckets = xmalloc(sizeof *tmp.buckets * (new_mask + 1)); tmp.mask = new_mask; for (i = 0; i <= tmp.mask; i++) { tmp.buckets[i] = NULL; } } for (i = 0; i <= hmap->mask; i++) { struct hmap_node *node, *next; int count = 0; for (node = hmap->buckets[i]; node; node = next) { next = node->next; hmap_insert_fast(&tmp, node, node->hash); count++; } if (count > 5) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10); COVERAGE_INC(hmap_pathological); VLOG_DBG_RL(&rl, "%s: %d nodes in bucket (%"PRIuSIZE" nodes, %"PRIuSIZE" buckets)", where, count, hmap->n, hmap->mask + 1); } } hmap_swap(hmap, &tmp); hmap_destroy(&tmp); }
/* Moves NODE around in MAP to compensate for its hash value having changed to NEW_HASH. This function does not verify that MAP does not already contain a data item that duplicates NODE's new value. If duplicates should be disallowed (which is the usual case), then the client must check for duplicates before changing NODE's value. */ void hmap_changed (struct hmap *map, struct hmap_node *node, size_t new_hash) { if ((new_hash ^ node->hash) & map->mask) { hmap_delete (map, node); hmap_insert_fast (map, node, new_hash); } else node->hash = new_hash; }
void ofl_structs_match_convert_pktf2oflm(struct hmap * hmap_packet_fields, struct hmap * hmap_ofl_match) /* * Used to convert between a hmap of "struct packet_fields" to "struct ofl_match" */ { struct packet_fields *iter; HMAP_FOR_EACH(iter,struct packet_fields, hmap_node, hmap_packet_fields) { struct ofl_match_tlv * new_entry = (struct ofl_match_tlv *) malloc(sizeof(struct ofl_match_tlv)); new_entry->header = iter->header; new_entry->value = (uint8_t *) malloc(OXM_LENGTH(new_entry->header)); memcpy(new_entry->value, iter->value,OXM_LENGTH(new_entry->header)); hmap_insert_fast(hmap_ofl_match, &new_entry->hmap_node, hash_int(new_entry->header, 0)); } }