Example #1
0
// 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);
    
}
Example #2
0
//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);
}
Example #4
0
// 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;
}
Example #5
0
/* 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);
}