void test_basics() { cache_t cache = create_cache(65536, NULL); uint32_t val_size = 0; const uint8_t *key1 = (uint8_t*)"One key", *key2 = (uint8_t*)"Two key", *key3 = (uint8_t*)"Red key"; uint8_t *value1 = (uint8_t*) "First value"; uint64_t value2 = 20039; int32_t value3 = -12; cache_set(cache, key1, value1, strlen((char *)value1) + 1); cache_set(cache, key2, &value2, sizeof(value2)); cache_set(cache, key3, &value3, sizeof(value3)); uint8_t *result1 = (uint8_t *)cache_get(cache, key1, &val_size); uint64_t *result2 = (uint64_t *)cache_get(cache, key2, &val_size); int32_t *result3 = (int32_t *)cache_get(cache, key3, &val_size); bool results_not_null = result1 != NULL && result2 != NULL && result3 != NULL; bool string_result_correct = strcmp((const char*)value1, (const char*)result1) == 0; bool uint64_result_correct = *result2 == value2; bool int32_result_correct = *result3 == value3; test(results_not_null, "Get returns non null pointers when retrieving valid entries."); test(string_result_correct, "Cache can store and retrieve strings"); test(uint64_result_correct, "Cache can store and retrieve uint64_t integers correctly."); test(int32_result_correct, "Cache can store and retrieve int32_t integers correctly."); test(val_size == sizeof(value3), "cache_get sets val_size pointer to value size."); destroy_cache(cache); }
void test_gets(uint8_t* keys, uint32_t* values, uint64_t numpairs) { cache_t cache = create_cache(numpairs*10); char **keystrings = calloc(numpairs,sizeof(char*)); char **valstrings = calloc(numpairs,sizeof(char*)); for(int i = 0; i < numpairs; ++i) { keystrings[i] = calloc(keys[i],1); valstrings[i] = calloc(values[i],1); memset(keystrings[i],'K',keys[i]); memset(valstrings[i],'V',values[i]); keystrings[i][keys[i] - 1] = '\0'; valstrings[i][values[i] - 1] = '\0'; cache_set(cache,keystrings[i],valstrings[i],values[i]); free(valstrings[i]); } free(valstrings); uint32_t val_size = 0; // Get the timebase info // mach_timebase_info_data_t info; // mach_timebase_info(&info); uint64_t errors = 0; const uint64_t requests = numpairs; const double nsToSec = 1000000000; const uint32_t nsToms = 1000000; // uint64_t start = mach_absolute_time(); struct timespec start, end; clock_gettime(CLOCK_MONOTONIC,&start); for(int i = 0; i < requests; ++i) { if( cache_get(cache,keystrings[i],&val_size) == -1) ++errors; //if( val_size == 0) ++errors; //val_size = 0; } // uint64_t end = mach_absolute_time(); clock_gettime(CLOCK_MONOTONIC,&end); // uint64_t duration = end - start; uint64_t duration = (end.tv_sec * nsToSec + end.tv_nsec) - (start.tv_sec * nsToSec + start.tv_nsec); // Convert to nanoseconds // duration *= info.numer; // duration /= info.denom; uint64_t ns = duration; double time_elapsed_sec = (double) duration / nsToSec; double requests_per_second = (double) requests / time_elapsed_sec; double ms = (double) ns / (requests * nsToms); printf("Time per Get: %f milliseconds\n",ms); printf("Requests per second: %f requests\n",requests_per_second); printf("Percent of Requests that failed: %f,%d,%d\n",((double)errors/requests),errors,requests); destroy_cache(cache); }
static void __exit aufs_exit(void) { unregister_filesystem(&aufs_fs_type); destroy_cache(); au_sysrq_fin(); au_inotify_fin(); au_wkq_fin(); sysaufs_fin(); }
//Checks if a custom hash at least doesn't crash the cache (since some didn't have this customization) //Sets a value with the custome hash and gets it to see if it was set properly void custom_hash() { uint8_t key[2] = {'a', '\0'}; uint8_t value[6] = "12345"; uint32_t val_size = 0; cache_t cache = create_cache(100 * sizeof(value)); cache_set(cache, key, value, sizeof(value)); uint8_t *ret = (uint8_t*)cache_get(cache, key, &val_size); test(!strcmp(key,"12345"), "cache_get works when given a custom hash (doesn't have to use custom hash)"); destroy_cache(cache); }
//Tests if cache returns val_size from cache //sets a value and checks if the val_size from get is equal to the set value size void test_get_valsize() { uint8_t key[2] = {'a', '\0'}; uint8_t *value = "size me"; uint32_t val_size = 0; cache_t cache = create_cache(100 * sizeof(value)); cache_set(cache, key, value, strlen(value) + 1); cache_get(cache, key, &val_size); test(val_size == 8, "cache_get sets val_size pointer"); destroy_cache(cache); }
void release_fsvol(ext2_fs_t *fs) { if(!fs) return; ll_remove_entry(fslist, fs); kfree(fs->sb); fs->m_node->pid=-1; fs->m_block->pid=-1; mutex_destroy(fs->m_node); mutex_destroy(fs->m_block); mutex_destroy(&fs->ac_lock); mutex_destroy(&fs->bg_lock); mutex_destroy(&fs->fs_lock); destroy_cache(fs->cache); kfree(fs); }
/** * progress_buffer_finalize() * * Equivalent of destructor. */ static void progress_buffer_finalize (GObject *object) { ProgressBuffer *element = PROGRESS_BUFFER(object); if (element->pending_src_event) gst_event_unref(element->pending_src_event); // INLINE - gst_event_unref() if (element->cache) destroy_cache(element->cache); g_mutex_clear(&element->lock); g_cond_clear(&element->add_cond); g_timer_destroy(element->bandwidth_timer); G_OBJECT_CLASS (parent_class)->finalize (object); }
/** * hls_progress_buffer_finalize() * * Equivalent of destructor. */ static void hls_progress_buffer_finalize (GObject *object) { HLSProgressBuffer *element = HLS_PROGRESS_BUFFER(object); int i = 0; for (i = 0; i < NUM_OF_CACHED_SEGMENTS; i++) { if (element->cache[i]) destroy_cache(element->cache[i]); } g_mutex_free(element->lock); g_cond_free(element->add_cond); g_cond_free(element->del_cond); G_OBJECT_CLASS (parent_class)->finalize (object); }
void test_get_nonexistant() { cache_t cache = create_cache(65536, NULL); uint32_t val_size = 1; const uint8_t *key = (uint8_t *)"weather"; uint8_t *result = (uint8_t *)cache_get(cache, key, &val_size); bool get_nothing_gives_null = result == NULL; bool nonexistant_val_size_is_zero = val_size == 0; test(get_nothing_gives_null, "Get return NULL when key is missing."); test(nonexistant_val_size_is_zero, "Get sets value size to zero when key is missing."); destroy_cache(cache); }
void test_too_big() { cache_t cache = create_cache(10, NULL); uint32_t val_size = 0; const uint8_t *key = (uint8_t *)"chrome"; uint8_t *value = (uint8_t *)"This is supposed to be too big to fit into this cache"; cache_set(cache, key, value, strlen((char *)value) + 1); uint8_t *result = (uint8_t *)cache_get(cache, key, &val_size); bool large_val_wasnt_saved = result == NULL; test(large_val_wasnt_saved, "Cache does not store large values."); destroy_cache(cache); }
void test_copying_keys() { cache_t cache = create_cache(65536, NULL); uint32_t val_size = 0; uint8_t *key1 = (uint8_t *)"original"; uint8_t *key2 = (uint8_t *)"original"; uint8_t *value = (uint8_t *)"nothing seemed to turn out right"; cache_set(cache, key1, value, strlen((char *)value) + 1); key1 = (uint8_t *)"fake"; uint8_t *result = (uint8_t *)cache_get(cache, key2, &val_size); bool key_still_valid = result != NULL; test(key_still_valid, "Changing original key does not change key in cache"); destroy_cache(cache); }
void test_get_modified() { cache_t cache = create_cache(65536, NULL); uint32_t val_size = 0; const uint8_t *key = (uint8_t *)"weather"; uint8_t *value = (uint8_t *)"sunny"; cache_set(cache, key, value, strlen((char *)value) + 1); value = (uint8_t *)"pouring rain forever"; cache_set(cache, key, value, strlen((char *)value) + 1); uint8_t *result = (uint8_t *)cache_get(cache, key, &val_size); bool value_is_updated = result != NULL && strcmp((const char*)value, (const char*)result) == 0; bool val_size_updated = val_size == strlen((char *)value) + 1; test(value_is_updated, "Setting to same key updates the value."); test(val_size_updated, "Value size from get is updated by cache_set."); destroy_cache(cache); }
//cache evicts keys to make room for new ones (jmcosel has a memsize min of 64) //creates a cache with memsize of 64 and sets 4 values so that the 3rd will //cause an eviction (if they didn't mess with the maxmem) void eviction_couple() { cache_t cache = create_cache(64); key_type key0 = (const uint8_t*) "hello", key1 = (const uint8_t*) "thenumber3", key2 = (const uint8_t*) "goodbye", key3 = (const uint8_t*) "wow"; uint8_t *value0 = "a", *value1 = "b"; uint8_t *chararray = "01234567890123456789012345678901234567890123456789012345678"; uint8_t *value3 = "c"; cache_set(cache,key0,value0,strlen(value0) + 1); cache_set(cache,key1,value1,strlen(value1) + 1); cache_set(cache,key2,chararray,60); cache_set(cache,key3,value3,strlen(value3) + 1); uint32_t val_size = 0; uint8_t *val = (uint8_t*) cache_get(cache,key3,&val_size); test(!strcmp(val,"c"),"keys are evicted to make space for new values"); destroy_cache(cache); }
//sets 4 values, gets the first value set, and sets a new value //big enough to force an eviction, checks if the second key (least recently used) //is removed, the third is removed, and finally if the first value added is still there void evict_after_get() { cache_t cache = create_cache(64); key_type key0 = (const uint8_t*) "hello", key1 = (const uint8_t*) "thenumber3", key2 = (const uint8_t*) "goodbye", key3 = (const uint8_t*) "wow"; uint8_t *value0 = "1", *value1 = "3"; uint8_t value2[60] = "01234567890123456789012345678901234567890123456789012345678"; uint8_t *value3 = "123123124"; cache_set(cache,key0,value0,strlen(value0) + 1); cache_set(cache,key1,value1,strlen(value1) + 1); cache_set(cache,key2,value2,60); uint32_t val_size = 0; uint8_t *val; // access first input val = (uint8_t*) cache_get(cache,key0,&val_size); // Set something that will require an eviction cache_set(cache,key3,value3,strlen(value3) + 1); // now get the last used value uint8_t *val0 = (uint8_t*) cache_get(cache,key0,&val_size); uint8_t *val1 = (uint8_t*) cache_get(cache,key1,&val_size); uint8_t *val2 = (uint8_t*) cache_get(cache,key2,&val_size); uint8_t *val3 = (uint8_t*) cache_get(cache,key3,&val_size); test(!strcmp(val0,"1") && val1 == NULL && val2 == NULL && !strcmp(val3,"123123124"),"Last accessed key is evicted"); destroy_cache(cache); }
//Sets 4 values and then gets all 4, checks if the values were set correctly void set_multiple() { cache_t cache = init(); const uint8_t *key0 = (const uint8_t*) "hello", *key1 = (const uint8_t*) "thenumber3", *key2 = (const uint8_t*) "goodbye", *key3 = (const uint8_t*) "wow"; uint8_t *value0 = "hello", *value1 = "how are you"; uint8_t *value2 = "good thanks"; uint8_t *value3 = "me too"; cache_set(cache,key0,value0,strlen(value0) + 1); cache_set(cache,key1,value1,strlen(value1) + 1); cache_set(cache,key2,value2,strlen(value2) + 1); cache_set(cache,key3,value3,strlen(value3) + 1); uint32_t val_size = 0; uint8_t *val1 = (uint8_t*)cache_get(cache,key0,&val_size), *val2 = (uint8_t*)cache_get(cache,key1,&val_size); uint8_t *val3 = (uint32_t*)cache_get(cache,key2,&val_size); uint8_t *val4 = (uint64_t*)cache_get(cache,key3,&val_size); test(!strcmp(val1,"hello") && !strcmp(val2,"how are you") && !strcmp(val3,"good thanks") && !strcmp(val4,"me too"), "cache_set stores (multiple) values that are accessible"); free(val1); free(val2); free(val3); free(val4); destroy_cache(cache); }
/** * progress_buffer_enqueue_item() * * Add an item in the queue. Must be called in the locked context. Item may be event or data. */ static GstFlowReturn progress_buffer_enqueue_item(ProgressBuffer *element, GstMiniObject *item) { gboolean signal = FALSE; if (GST_IS_BUFFER (item)) { gdouble elapsed; // update sink segment position element->sink_segment.position = GST_BUFFER_OFFSET(GST_BUFFER(item)) + gst_buffer_get_size (GST_BUFFER(item)); if(element->sink_segment.stop < element->sink_segment.position) // This must never happen. return GST_FLOW_ERROR; cache_write_buffer(element->cache, GST_BUFFER(item)); elapsed = g_timer_elapsed(element->bandwidth_timer, NULL); element->subtotal += gst_buffer_get_size (GST_BUFFER(item)); if (elapsed > 1.0) { element->bandwidth = element->subtotal/elapsed; element->subtotal = 0; g_timer_start(element->bandwidth_timer); } // send buffer progress position up (used to track buffer fill, etc.) signal = send_position_message(element, signal); } else if (GST_IS_EVENT (item)) { GstEvent *event = GST_EVENT_CAST (item); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: element->eos_status.eos = TRUE; if (element->sink_segment.position < element->sink_segment.stop) element->sink_segment.stop = element->sink_segment.position; progress_buffer_set_pending_event(element, NULL); signal = send_position_message(element, TRUE); gst_event_unref(event); // INLINE - gst_event_unref() break; case GST_EVENT_SEGMENT: { GstSegment segment; element->unexpected = FALSE; gst_event_copy_segment (event, &segment); if (segment.format != GST_FORMAT_BYTES) { gst_element_message_full(GST_ELEMENT(element), GST_MESSAGE_ERROR, GST_STREAM_ERROR, GST_STREAM_ERROR_FORMAT, g_strdup("GST_FORMAT_BYTES buffers expected."), NULL, ("progressbuffer.c"), ("progress_buffer_enqueue_item"), 0); gst_event_unref(event); // INLINE - gst_event_unref() return GST_FLOW_ERROR; } if (segment.stop - segment.start <= 0) { gst_element_message_full(GST_ELEMENT(element), GST_MESSAGE_ERROR, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE, g_strdup("Only limited content is supported by progressbuffer."), NULL, ("progressbuffer.c"), ("progress_buffer_enqueue_item"), 0); gst_event_unref(event); // INLINE - gst_event_unref() return GST_FLOW_ERROR; } if ((segment.flags & GST_SEGMENT_FLAG_UPDATE) == GST_SEGMENT_FLAG_UPDATE) // Updating segments create new cache. { if (element->cache) destroy_cache(element->cache); element->cache = create_cache(); if (!element->cache) { gst_element_message_full(GST_ELEMENT(element), GST_MESSAGE_ERROR, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ_WRITE, g_strdup("Couldn't create backing cache"), NULL, ("progressbuffer.c"), ("progress_buffer_enqueue_item"), 0); gst_event_unref(event); // INLINE - gst_event_unref() return GST_FLOW_ERROR; } } else { cache_set_write_position(element->cache, 0); cache_set_read_position(element->cache, 0); element->cache_read_offset = segment.start; } gst_segment_copy_into (&segment, &element->sink_segment); progress_buffer_set_pending_event(element, event); element->instant_seek = TRUE; signal = send_position_message(element, TRUE); break; } default: gst_event_unref(event); // INLINE - gst_event_unref() break; } } if (signal) g_cond_signal(&element->add_cond); return GST_FLOW_OK; }
int main (int argc, char **argv) { int res = 0; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); sqlprofile = g_try_new0(struct sqlprofile, 1); g_mutex_init(&cache.m); cache.open_table = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, free_sqlfs_file); if (fuse_opt_parse(&args, sqlprofile, sqlfs_opts, sqlfs_opt_proc) == -1) res = 1; if (!res && !sqlprofile->profile) res = 1; if (!res) { GError *terr = NULL; init_keyfile(sqlprofile->profile, &terr); if (terr != NULL) res = 1; if (!res) { init_cache(&terr); if (terr != NULL) res = 2; } if (!res) { res = sqlfs_fuse_main(&args); fuse_opt_free_args(&args); if (terr != NULL) res = 3; } if (!res || res > 2) destroy_cache(&terr); if (!res || res > 1) close_keyfile(); if (sqlprofile != NULL) { if (sqlprofile->profile != NULL) g_free(sqlprofile->profile); g_free(sqlprofile); } if (terr != NULL) { g_error("Position %d - #%d: %s", res, terr->code, terr->message); g_error_free(terr); } } else { g_error("Position %d - #%d: %s", res, 0, "Invalid arguments"); } g_hash_table_destroy(cache.open_table); g_mutex_clear(&cache.m); return res; }
static int __init aufs_init(void) { int err, i; char *p; au_debug_init(); #ifdef CONFIG_AUFS_INO_T_64 BUILD_BUG_ON(sizeof(ino_t) != sizeof(long long)); #else BUILD_BUG_ON(sizeof(ino_t) != sizeof(int)); #endif p = au_esc_chars; for (i = 1; i <= ' '; i++) *p++ = i; *p++ = '\\'; *p++ = '\x7f'; *p = 0; au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); err = -EINVAL; if (unlikely(aufs_nwkq <= 0)) goto out; err = sysaufs_init(); if (unlikely(err)) goto out; err = au_wkq_init(); if (unlikely(err)) goto out_sysaufs; err = au_inotify_init(); if (unlikely(err)) goto out_wkq; err = au_sysrq_init(); if (unlikely(err)) goto out_inotify; err = create_cache(); if (unlikely(err)) goto out_sysrq; err = register_filesystem(&aufs_fs_type); if (unlikely(err)) goto out_cache; pr_info(AUFS_NAME " " AUFS_VERSION "\n"); return 0; /* success */ out_cache: destroy_cache(); out_sysrq: au_sysrq_fin(); out_inotify: au_inotify_fin(); out_wkq: au_wkq_fin(); out_sysaufs: sysaufs_fin(); out: AuTraceErr(err); return err; }
void throughput_test(const uint32_t time_interval_list[],const uint32_t time_interval_list_len, const uint32_t key_len, const uint32_t value_len, const uint32_t hash, const double get_per, const double set_per){ //printf("\nstart_new_cycle: ti-%u, k-%u, v-%u, h-%u, get-%f, set-%f\n",time_interval,key_len,value_len,hash,get_per,set_per); //Initialize files and associate appropriate file pointers to them FILE * fp_key, * fp_val, * fp_op, * fp_out; Initialize_files(&fp_key,&fp_val,&fp_op,&fp_out, key_len,value_len, hash, get_per, set_per); //Create and fill parameter pools from the input files char key_pool[POOL_SIZE][KEY_MAX] = {0}; char value_pool[POOL_SIZE][VAL_MAX] = {0}; char ops_pool[POOL_SIZE][OPLENGTH] = {0}; if (fp_key!=NULL&&fp_val!=NULL&&fp_op!=NULL){ fill_parameters_pools(fp_key,fp_val,fp_op, key_pool, value_pool, ops_pool); } else{ printf("NULL file descriptors"); } //a flag used to check whether we have passed sustained througput of the current parameters combinations uint32_t limit_attained = 0; //Begin The main loop - increase the number of requests each time for (uint32_t i = 0; i<time_interval_list_len; i++){ uint32_t time_interval = time_interval_list[i]; uint64_t request_num = (uint64_t)(1000000.0/(double)time_interval); double response_time[TESTS_NUM] = {0}; double response_time_median = 0; //Test a bundle several times and take the mean response time for (uint32_t j=0;j<TESTS_NUM;j++){ cache_t cache = create_cache((uint64_t)(POOL_SIZE)*(uint64_t)VAL_MAX); clock_t begin,end; double timeTaken_sec = 0; double sleep_time_sec = 0; double total_sleep_time_sec = 0; double total_time_ms = 0; double time_interval_sec = (double)time_interval*0.0000001; double waiting_time_ms = 0; uint32_t waiting_rounds = 0; //Number of responses that haven't been received uint32_t waiting_responses = 0; //Set up files to be read fd_set readfds; FD_ZERO(&readfds); FD_SET(cache->sockfd, &readfds); FD_SET(cache->sockfd_udp, &readfds); //Set up buffers that store messages char buffer[MAXDATASIZE]; bzero(buffer,MAXDATASIZE); char remaining_message[MAXDATASIZE]; bzero(remaining_message,MAXDATASIZE); char remaining_message_udp[MAXDATASIZE]; bzero(remaining_message_udp,MAXDATASIZE); //Send a certain number of requests for (uint32_t i=1;i<=request_num;i++){ //Initialize a random request char key[KEY_MAX] = {0}; strncpy(key, key_pool[rand_interval(0,POOL_SIZE-1)],KEY_MAX); char value[VAL_MAX] = {0}; strncpy(value,value_pool[rand_interval(0,POOL_SIZE-1)],VAL_MAX); char op[OPLENGTH] = {0}; strcpy(op, ops_pool[rand_interval(0,POOL_SIZE-1)]); bzero(buffer,MAXDATASIZE); generate_a_request(buffer,key,value,op); begin = clock(); if (strncmp(op,"GET",3)==0){ if (send(cache->sockfd_udp,buffer,strlen(buffer), 0) < 0) {error("ERROR sendto to socket");} } else{ if (send(cache->sockfd,buffer,strlen(buffer), 0) < 0) {error("ERROR send to socket");} } waiting_responses++; //Update the number of responses that haven't arrived waiting_responses-=check_response(cache,time_interval,readfds,remaining_message, remaining_message_udp); end = clock(); timeTaken_sec = ((double)(end-begin)+waiting_responses*time_interval)/CLOCKS_PER_SEC; total_time_ms += (timeTaken_sec*1000); //printf("total_time:%fms,timeTaken:%fus\n",total_time_ms,timeTaken_sec*1000000); //sleep if there is time left if (timeTaken_sec<=(time_interval_sec)){ sleep_time_sec = time_interval_sec-timeTaken_sec; sleep(sleep_time_sec); total_sleep_time_sec += sleep_time_sec; } //printf("loop:%u,waiting_responses:%u\n",i,waiting_responses); } //Wait for the remaining responses on the way from the server //printf("begin to wait\n"); begin = clock(); while (waiting_responses>0){ waiting_rounds++; //printf("waiting responses:%u\n",waiting_responses); uint32_t new_responses = check_response(cache,time_interval,readfds,remaining_message,remaining_message_udp); if (new_responses>0){ waiting_rounds = 0; waiting_responses-=new_responses; } //If it waits for more than 10000 rounds, the messages probably will never come if (waiting_rounds>30000){ break; } } end = clock(); waiting_time_ms = ((double)(end-begin)*1000)/CLOCKS_PER_SEC; total_time_ms += waiting_time_ms; response_time[j] = total_time_ms/(double)request_num; //If we have passed sustained througput, break the test for the current combination of the input parameters printf("total_time:%fms,response_time:%fms\n",total_time_ms,response_time[j]); destroy_cache(cache); } response_time_median = median(response_time,TESTS_NUM); fprintf(fp_out,"%"PRIu64",%f\n",request_num,response_time_median); if (response_time_median>1.5){ limit_attained = 1; break; } if (limit_attained==1){ break; } } fclose(fp_key); fclose(fp_val); fclose(fp_op); fclose(fp_out); }
//check if we destroy the cache successfully void test_destroy_cache(cache_t cache){ destroy_cache(cache); //assert(cache_space_used(cache)==0&&"cache fails to be destoryed"); }