static indigo_error_t router_ip_delete(void *table_priv, void *entry_priv, of_list_bsn_tlv_t *key) { struct router_ip_entry *entry = entry_priv; bighash_remove(router_ip_entries, &entry->hash_entry); entry->ip = INVALID_IP; return INDIGO_ERROR_NONE; }
int bighash_entries_move(bighash_table_t *dst, bighash_table_t *src) { bighash_iter_t iter; bighash_entry_t *e; for(e = bighash_iter_start(src, &iter); e; e = bighash_iter_next(&iter)) { bighash_remove(src, e); bighash_insert(dst, e, e->hash); } return 0; }
static indigo_error_t router_ip_modify(void *table_priv, void *entry_priv, of_list_bsn_tlv_t *key, of_list_bsn_tlv_t *value) { indigo_error_t rv; uint32_t ip; struct router_ip_entry *entry = entry_priv; of_mac_addr_t mac; rv = router_ip_parse_value(value, &ip, &mac); if (rv < 0) { return rv; } bighash_remove(router_ip_entries, &entry->hash_entry); entry->ip = ip; entry->mac = mac; router_ip_entries_hashtable_insert(router_ip_entries, entry); return INDIGO_ERROR_NONE; }
int main(int argc, char *argv[]) { biglist_t *entries = NULL; /** Basic Hashing -- statically allocated table */ bighash_table_init_static(&static_table); insert__(&static_table, 10000, &entries); test_table_data__(&static_table, &entries); bighash_table_destroy(&static_table, NULL); /** Basic hashing -- dynamically allocated table */ { bighash_table_t *dtable; dtable = bighash_table_create(64); insert__(dtable, 10000, &entries); test_table_data__(dtable, &entries); bighash_table_destroy(dtable, NULL); } /** Count and removal while iterating */ { bighash_table_t *table; bighash_iter_t iter; bighash_entry_t *e; test_entry_t *te; int ecount=100; int count = 0; table = bighash_table_create(64); insert__(table, ecount, NULL); if(bighash_entry_count(table) != ecount) { AIM_DIE("Entry count mismatch: expected %d, got %d", ecount, bighash_entry_count(table)); } /* Iterate once, just counting */ for(te = (test_entry_t*)bighash_iter_start(table, &iter); te; te = (test_entry_t*)bighash_iter_next(&iter)) { count++; } if(count != ecount) { AIM_DIE("Iteration count incorrect (%d)", count); } /* Iterate again, removing elements. Tests both iteration restart * and remove-while-iterating. */ for(e = bighash_iter_start(table, &iter); e; e = bighash_iter_next(&iter)) { test_entry_t *te = container_of(e, hash_entry, test_entry_t); bighash_remove(table, &te->hash_entry); /* Clear the list links on this element to make sure the * removal was done properly. */ memset(te, 0, sizeof(*te)); aim_free(te); } if(bighash_entry_count(table) != 0) { AIM_DIE("Count is not zero after iterated removal (count=%d)", bighash_entry_count(table)); } bighash_table_destroy(table, NULL); } /** Migrating between tables */ { bighash_table_t *src; bighash_table_t *dst; src = bighash_table_create(64); dst = bighash_table_create(128); insert__(src, 1000, &entries); bighash_entries_move(dst, src); if(bighash_entry_count(src) != 0) { AIM_DIE("Source table is not empty."); } bighash_table_destroy(src, NULL); test_table_data__(dst, &entries); bighash_table_destroy(dst, NULL); } /** Check utilization and automatic element destruction */ bighash_table_init_static(&static_table); insert__(&static_table, 100000, 0); bighash_table_utilization_show(&static_table, &aim_pvs_stdout); bighash_table_destroy(&static_table, free_test_entry); test_template(); return 0; }
int test_table_data__(bighash_table_t *table, biglist_t** entry_list) { /* Make sure we can find all entries in the entry list */ { biglist_t *ble; test_entry_t *te; BIGLIST_FOREACH_DATA(ble, *entry_list, test_entry_t*, te) { test_entry_t *fe = find_by_id(table, te->id); if(fe == NULL) { AIM_DIE("inserted entry (id=%d) was not found after filling table", te->id); } else if(fe != te) { AIM_DIE("Retreived pointer does not match. (te=%p (%d), fe=%p (%d)", te, te->id, fe, fe->id); } } } /* Make sure all elements in the list are enumerated */ { bighash_iter_t iter; bighash_entry_t *e; int count = 0; for(e = bighash_iter_start(table, &iter); e; e = bighash_iter_next(&iter)) { test_entry_t *te = container_of(e, hash_entry, test_entry_t); if(te->found) { AIM_DIE("Entry %p:%d was already enumerated.", te, te->id); } te->found++; if(biglist_find(*entry_list, te) == NULL) { AIM_DIE("Entry %p:%d is not in the entry list.", te, te->id); } count++; } if(count != biglist_length(*entry_list)) { AIM_DIE("Enumeration error: count=%d, length=%d", count, biglist_length(*entry_list)); } } /* Remove from table */ { biglist_t *ble; test_entry_t *te; int count = 1; BIGLIST_FOREACH_DATA(ble, *entry_list, test_entry_t*, te) { bighash_remove(table, &te->hash_entry); if(find_by_id(table, te->id) != NULL) { AIM_DIE("Removed entry was not removed."); } if(bighash_entry_count(table) != biglist_length(*entry_list)-count) { AIM_DIE("Entry count mismatch: hashcount=%d, listcount=%d", bighash_entry_count(table), biglist_length(*entry_list)-count); } count++; } } /* Free entry list */ biglist_free_all(*entry_list, aim_free); *entry_list = NULL; return 0; }