/** * Iterates through all the metrics * @arg m The metrics to iterate through * @arg data Opaque handle passed to the callback * @arg cb A callback function to invoke. Called with a type, name * and value. If the type is KEY_VAL, it is a pointer to a double, * for a counter, it is a pointer to a counter, and for a timer it is * a pointer to a timer. Return non-zero to stop iteration. * @return 0 on success, or the return of the callback */ int metrics_iter(metrics *m, void *data, metric_callback cb) { // Handle the K/V pairs first key_val *current = m->kv_vals; int should_break = 0; while (current && !should_break) { should_break = cb(data, KEY_VAL, current->name, ¤t->val); current = current->next; } if (should_break) return should_break; // Store our data in a small struct struct cb_info info = {COUNTER, data, cb}; // Send the counters should_break = hashmap_iter(m->counters, iter_cb, &info); if (should_break) return should_break; // Send the timers info.type = TIMER; should_break = hashmap_iter(m->timers, iter_cb, &info); if (should_break) return should_break; // Send the gauges info.type = GAUGE; should_break = hashmap_iter(m->gauges, iter_cb, &info); if (should_break) return should_break; // Send the sets info.type = SET; should_break = hashmap_iter(m->sets, iter_cb, &info); return should_break; }
/** * Destroys the metrics * @return 0 on success. */ int destroy_metrics(metrics *m) { // Clear the copied quantiles array free(m->quantiles); // Nuke all the k/v pairs key_val *current = m->kv_vals; key_val *prev = NULL; while (current) { free(current->name); prev = current; current = current->next; free(prev); } // Nuke the counters hashmap_iter(m->counters, counter_delete_cb, NULL); hashmap_destroy(m->counters); // Nuke the timers hashmap_iter(m->timers, timer_delete_cb, NULL); hashmap_destroy(m->timers); // Nuke the timers hashmap_iter(m->sets, set_delete_cb, NULL); hashmap_destroy(m->sets); // Nuke the gauges hashmap_iter(m->gauges, gauge_delete_cb, NULL); hashmap_destroy(m->gauges); return 0; }
END_TEST START_TEST(test_map_put_iter) { bloom_hashmap *map; int res = hashmap_init(0, &map); fail_unless(res == 0); char buf[100]; for (int i=0; i<100;i++) { snprintf((char*)&buf, 100, "test%d", i); fail_unless(hashmap_put(map, (char*)buf, NULL) == 1); } int val = 0; fail_unless(hashmap_iter(map, iter_test, (void*)&val) == 0); fail_unless(val == 100); res = hashmap_destroy(map); fail_unless(res == 0); }
END_TEST START_TEST(test_map_put_grow) { hashmap *map; int res = hashmap_init(32, &map); // Only 32 slots fail_unless(res == 0); char buf[100]; void *out; for (int i=0; i<1000;i++) { snprintf((char*)&buf, 100, "test%d", i); fail_unless(hashmap_put(map, (char*)buf, NULL) == 1); } int val = 0; fail_unless(hashmap_iter(map, iter_test, (void*)&val) == 0); fail_unless(val == 1000); fail_unless(hashmap_size(map) == 1000); res = hashmap_destroy(map); fail_unless(res == 0); }