Last active
March 31, 2017 21:28
-
-
Save emmiegit/fdd91dfa3e6a9f15d86d31aa9ee6980e to your computer and use it in GitHub Desktop.
Helium garbage generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _XOPEN_SOURCE 500 | |
| #include <inttypes.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <time.h> | |
| #include <pthread.h> | |
| #include <he.h> | |
| #define DEFAULT_URL "he://.//mnt/nvme/he" | |
| #define DATASTORE_NAME "gc" | |
| #define THREADS 64 | |
| struct thread_data { | |
| he_t he; | |
| unsigned int thread; | |
| unsigned int seed; | |
| }; | |
| static void * | |
| _stats_(void *arg) | |
| { | |
| struct timespec ts; | |
| struct he_stats stats; | |
| he_t he; | |
| he = arg; | |
| ts.tv_sec = 30; | |
| ts.tv_nsec = 0; | |
| for (;;) { | |
| if (he_stats(he, &stats)) { | |
| he_perror("he_stats"); | |
| break; | |
| } | |
| printf("---------------------------\n" | |
| "Valid / Deleted: %" PRIu64 ", %" PRIu64 "\n" | |
| "Utilized / Capacity: %" PRIu64 ", %" PRIu64 "\n" | |
| "GC rounds: %" PRIu64 "\n", | |
| stats.valid_items, | |
| stats.deleted_items, | |
| stats.utilized, | |
| stats.capacity, | |
| stats.auto_cleans); | |
| if (nanosleep(&ts, NULL)) { | |
| perror("nanosleep"); | |
| break; | |
| } | |
| } | |
| return NULL; | |
| } | |
| static void * | |
| _worker_(void *arg) | |
| { | |
| struct thread_data *data; | |
| struct he_item item; | |
| char key[32], val[16]; | |
| unsigned long i; | |
| data = arg; | |
| item.key = key; | |
| item.val = val; | |
| printf("Starting thread %u...\n", data->thread); | |
| for (i = 1; i != 0; i++) { | |
| item.key_len = snprintf(key, sizeof(key), | |
| "%03d_%u", | |
| rand_r(&data->seed) % 1000, | |
| rand_r(&data->seed)); | |
| item.val_len = snprintf(val, sizeof(val), | |
| "%lu_%d", | |
| i, | |
| rand_r(&data->seed)); | |
| if (he_update(data->he, &item)) { | |
| he_perror("he_update"); | |
| break; | |
| } | |
| /* 2/3 chance of deletion */ | |
| if ((rand_r(&data->seed) % 3) < 2) { | |
| if (he_delete(data->he, &item)) { | |
| he_perror("he_delete"); | |
| break; | |
| } | |
| } | |
| } | |
| return NULL; | |
| } | |
| int | |
| main(int argc, const char *argv[]) | |
| { | |
| struct he_env env; | |
| he_t he; | |
| const char *url; | |
| pthread_t stat_thrd; | |
| struct worker { | |
| pthread_t thrd; | |
| struct thread_data dat; | |
| } workers[THREADS]; | |
| unsigned int i; | |
| if (argc == 1) | |
| url = DEFAULT_URL; | |
| else | |
| url = argv[1]; | |
| memset(&env, 0, sizeof(struct he_env)); | |
| env.clean_dirty_pct = 2; | |
| he = he_open(url, | |
| DATASTORE_NAME, | |
| HE_O_CREATE | HE_O_VOLUME_CREATE | HE_O_VOLUME_TRUNCATE, | |
| &env); | |
| if (!he) { | |
| he_perror("he_open"); | |
| return -1; | |
| } | |
| srand(time(NULL)); | |
| for (i = 0; i < THREADS; i++) { | |
| struct worker *wrk; | |
| wrk = &workers[i]; | |
| wrk->dat.he = he; | |
| wrk->dat.thread = i; | |
| wrk->dat.seed = rand() + 1; | |
| if (pthread_create(&wrk->thrd, NULL, _worker_, &wrk->dat)) { | |
| perror("pthread_create"); | |
| return -1; | |
| } | |
| } | |
| if (pthread_create(&stat_thrd, NULL, _stats_, he)) { | |
| perror("pthread_create"); | |
| return -1; | |
| } | |
| for (i = 0; i < THREADS; i++) { | |
| struct worker *wrk; | |
| wrk = &workers[i]; | |
| if (pthread_join(wrk->thrd, NULL)) { | |
| perror("pthread_join"); | |
| return -1; | |
| } | |
| } | |
| if (pthread_join(stat_thrd, NULL)) { | |
| perror("pthread_join"); | |
| return -1; | |
| } | |
| if (he_close(he)) { | |
| he_perror("he_open"); | |
| return -1; | |
| } | |
| return 0; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This program spins up 64 threads and has them spamming a datastore with items, deleting 2/3s of them. This way the datastore fills up with garbage. I then have another thread print gc statistics every 30 seconds. By inspecting the output, I was able to determine that the new gc metric for helium directories is working correctly, and garbage is being collected. I set "clean_util_pct" to 2%.