// Add a <key, value> pair to the cache. // If key already exists, it will overwrite the old value. // If maxmem capacity is exceeded, sufficient values will be removed // from the cache to accomodate the new value. void cache_set(cache_t cache, key_type key, val_type val, uint32_t val_size){ item_t item_to_set = hash_table_find_item(cache->hash_table, key); // If key already exists, it will overwrite the old value. if (item_to_set!=NULL){ item_to_set->val = val; return; } //If maxmem capacity is exceeded, sufficient values will be removed if (cache_space_used(cache)+val_size >= cache->maxmem){ cache_evict(cache); } //printf("\ncurrent_size:%u,hash_table_buckets_num:%u\n",cache->hash_table->current_size+1,(uint32_t) ((double) cache->hash_table->buckets_num*LOAD_FACTOR)); //Check if we need to resize hash table if (cache->hash_table->current_size+1 > (uint32_t) ((double) cache->hash_table->buckets_num*LOAD_FACTOR)){ resize_hash_table(cache->hash_table); } item_t item = hash_table_set(cache->hash_table, key, val, val_size); node_t node = linked_list_set(cache->linked_list); // //connect the item in hash_table with its corresponding node in linked list connect_node_and_item(item,node); }
//Add a <key,value> pair to the cache //If key already exists, overwrite the old value //If maxmem capacity is exceeded, values will be removed void cache_set(cache_t cache, _key_t key, val_t val, uint32_t val_size) { cache_real_obj *c = cache->cache; //Delete the value if it's already in the cache. meta_t old = get_key_loc(cache,key); if (old != NULL) cache_delete(cache, key); uint64_t available_memory = cache->cache->size - cache_space_used(cache); printf("Trying to add a value of size %"PRIu32", with available memory %"PRIu64"\n",val_size,available_memory); if (available_memory < val_size) { printf(" Increasing size.\n"); defrag(cache, 1); //This doubles the cache size (defragmenting at the same time). } bucket_timer_up(cache); //Create a new meta object and pair it to a slab address, and copy the value over meta_t next_meta = create_meta(cache,key,val_size); next_meta->address = get_address(c->slab_manager,val_size); //enact eviction policy if we need space if (next_meta->address == NULL){ uint32_t val_slab_class = get_slab_class(c->slab_manager, val_size); cache_evict(cache, val_slab_class); next_meta->address = get_address(c->slab_manager,val_size); if (next_meta->address == NULL){ uint32_t slab_class = get_slab_class(c->slab_manager, val_size); printf("Couldn't add a %u-%u byte value because there are no slabs of that range, and no free slabs to be allocated\n",slab_class>>1, slab_class); free(next_meta); return; }
static void do_server_request(struct server *sv, int connfd) { int ret; struct request *rq; struct file_data *data; data = file_data_init(); rq = request_init(connfd, data); if (!rq) { file_data_free(data); return; } if(cache_active ==1){ pthread_mutex_lock( &conditionMutex); struct hash_node *cache_stored; cache_stored= cache_lookup(data->file_name); if(cache_stored!=NULL){ // check if it populated in the cache{ data->file_buf = Malloc(cache_stored->data->file_size); strncpy(data->file_buf, cache_stored->data->file_buf, cache_stored->data->file_size); data->file_size =cache_stored->data->file_size; } else{ /* reads file, * fills data->file_buf with the file contents, * data->file_size with file size. */ pthread_mutex_unlock( &conditionMutex ); ret = request_readfile(rq); pthread_mutex_lock( &conditionMutex ); // need to renew the cache if(data->file_size<max_cache){ if(data->file_size <=(max_cache-cache_current_size) ){ cache_insert(data); } else{ cache_evict(data->file_size); cache_insert(data); } } } pthread_mutex_unlock( &conditionMutex ); } else{ ret = request_readfile(rq); if (!ret) goto out; } /* sends file to client */ request_sendfile(rq); out: request_destroy(rq); file_data_free(data); }
// Create a new cache struct cache_block * cache_new() { struct cache_block *cb; if (list_size(&cache_list) < CACHE_SIZE) { cb = malloc(sizeof(struct cache_block)); if(!cb) PANIC ("No enough memory for cache!"); list_push_back(&cache_list, &cb->elem); } else { cb = cache_evict(); } return cb; }
/* adds a block to cache */ static size_t cache_add (block_sector_t bid) { /* lock the cache */ lock_acquire(&cache_globallock); //bool hellYeah = bid == (unsigned) 163; /* lock for a free_cache_block cache block */ size_t free_cache_block = bitmap_scan (cache_table, 0, 1, false); //if(DEBUG || hellYeah) printf("bitscan complete bla\n"); /* if no free cache block is found, evict one and * search again */ if (free_cache_block == BITMAP_ERROR) { //if(DEBUG || hellYeah) printf("evict some\n"); cache_evict(); free_cache_block = bitmap_scan (cache_table, 0, 1, false); } ASSERT(free_cache_block != BITMAP_ERROR); //if(DEBUG || hellYeah) printf("add cache block %d\n",bid); /* copy block to cache */ block_read (fs_device, bid, cache[free_cache_block]->kpage); /* setup cache entry */ cache[free_cache_block]->dirty = false; cache[free_cache_block]->accessed = false; cache[free_cache_block]->bid = bid; /* set used bit of the cache table for this entry */ bitmap_set (cache_table, free_cache_block, true); /* release the lock for the cache table */ lock_release(&cache_globallock); if(CACHE_DEBUG) printf("added cache block %u for sector %u\n", (unsigned int) free_cache_block, (unsigned int) bid); return free_cache_block; }
static void do_server_request(struct server *sv, int connfd) { //printf("Starting cache_size:%d\n",cache_size); int ret; struct request *rq; struct file_data *data; data = file_data_init(); /* fills data->file_name with name of the file being requested */ rq = request_init(connfd, data); if (!rq) { file_data_free(data); return; } cache* temp; int hash_index = hash(data->file_name); pthread_mutex_lock(&lock2); temp = cache_lookup(data->file_name, hash_index); pthread_mutex_unlock(&lock2); if (temp != NULL) { request_set_data(rq, temp->data); } else { ret = request_readfile(rq); //printf("Request file size is %d\n", data->file_size); if ((data->file_size)>(sv->max_cache_size)) { request_sendfile(rq); goto out; } pthread_mutex_lock(&lock2); if (cache_lookup(data->file_name, hash_index)==NULL) // if it won the race, then cache { if (((sv->max_cache_size)-cache_size) < (data->file_size)) // check available cache size { //printf("Evicting for file size(minimum) of : %d\n",data->file_size); int amount = (data->file_size)-((sv->max_cache_size)-cache_size); cache_evict(amount); } cache_insert(data, hash_index); } pthread_mutex_unlock(&lock2); } if (!ret) goto out; /* sends file to client */ request_sendfile(rq); out: //printf("cache_size:%d\n",cache_size); //printf("END OF REQUEST----------------\n"); request_destroy(rq); //file_data_free(data); }