static mtev_hash_table * get_dedupe_hash(uint64_t whence) { struct hash_and_time *hash_with_time; mtev_hash_table *hash; if (mtev_hash_retrieve(&dedupe_hashes, (const char *)&whence, sizeof(whence), (void **)&hash_with_time) == 1) { hash = &hash_with_time->hash; } else { hash_with_time = calloc(1, sizeof(struct hash_and_time)); mtev_hash_init_locks(&hash_with_time->hash, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); uint64_t *stored_ts = calloc(1, sizeof(uint64_t)); *stored_ts = whence; if (mtev_hash_store(&dedupe_hashes, (const char *)stored_ts, sizeof(*stored_ts), hash_with_time) == 0) { /* ugh, someone beat us */ free(stored_ts); mtev_hash_destroy(&hash_with_time->hash, NULL, NULL); free(hash_with_time); if (mtev_hash_retrieve(&dedupe_hashes, (const char *)&whence, sizeof(whence), (void **)&hash_with_time) == 0) { return NULL; } } hash = &hash_with_time->hash; } hash_with_time->last_touched_s = mtev_gethrtime() / 1000000000; return hash; }
static int do_test(mtev_hash_lock_mode_t lock_mode) { mtev_hash_table hash; mtev_hash_init_locks(&hash, 400, lock_mode); pthread_t threads[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; i++) { pthread_create(&threads[i], NULL, thread_func, &hash); } for (int i = 0; i < THREAD_COUNT; i++) { pthread_join(threads[i], NULL); } mtev_hash_iter iter = MTEV_HASH_ITER_ZERO; const char *k; int klen; void *data; while(mtev_hash_next(&hash, &iter, &k, &klen, &data)) { printf("%s\n", k); } mtev_hash_destroy(&hash, free, NULL); return 0; }
void noit_adjust_metric_interest(uuid_t id, const char *metric, short cnt) { int thread_id, icnt; void *vhash, *vinterests; mtev_hash_table *level2; caql_cnt_t *interests; thread_id = get_my_lane(); /* Get us our UUID->HASH(METRICS) mapping */ if(!mtev_hash_retrieve(&id_level, (const char *)id, UUID_SIZE, &vhash)) { int found; uuid_t *copy = malloc(UUID_SIZE); level2 = calloc(1,sizeof(*level2)); mtev_hash_init_locks(level2, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); uuid_copy(*copy, id); if(!mtev_hash_store(&id_level, (const char *)copy, UUID_SIZE, level2)) { free(copy); free(level2); } found = mtev_hash_retrieve(&id_level, (const char *)id, UUID_SIZE, &vhash); mtevAssert(found); } level2 = vhash; if(!mtev_hash_retrieve(level2, metric, strlen(metric), &vinterests)) { int found; char *metric_copy; metric_copy = strdup(metric); vinterests = calloc(nthreads, sizeof(*interests)); if(!mtev_hash_store(level2, metric_copy, strlen(metric_copy), vinterests)) { free(metric_copy); free(vinterests); } found = mtev_hash_retrieve(level2, metric, strlen(metric), &vinterests); mtevAssert(found); } interests = vinterests; /* This is fine because thread_id is only ours */ icnt = interests[thread_id]; icnt += cnt; if(icnt < 0) icnt = 0; mtevAssert(icnt <= 0xffff); interests[thread_id] = icnt; }
void noit_metric_director_init_globals(void) { mtev_hash_init_locks(&id_level, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); mtev_hash_init_locks(&dedupe_hashes, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); }
void mtev_dso_init_globals(void) { mtev_hash_init_locks(&loaders, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); mtev_hash_init_locks(&generics, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); }
void mtev_hash_init_size(mtev_hash_table *h, int size) { mtev_hash_init_locks(h, size, MTEV_HASH_LOCK_MODE_NONE); }
void mtev_capabilities_init_globals() { mtev_hash_init_locks(&features, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX); }