Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 87 additions & 8 deletions src/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ struct cache_entry *alloc_entry(char *path, char *content_type, void *content, i
///////////////////
// IMPLEMENT ME! //
///////////////////

struct cache_entry *entry = malloc(sizeof(struct cache_entry));

// Use strdup to avoid segmentation fault when setting a string value in a struct's field
entry->path = strdup(path);
// NOTE: Remember to free memory malloc'd by strdup() in free_entry()
entry->content_type = strdup(content_type);
entry->content_length = content_length;
entry->content = malloc(content_length);
memcpy(entry->content, content, content_length);
return entry;
}

/**
Expand All @@ -22,6 +33,12 @@ void free_entry(struct cache_entry *entry)
///////////////////
// IMPLEMENT ME! //
///////////////////

// Free everything that allocated memory in alloc_entry()
free(entry->path);
free(entry->content_type);
free(entry->content);
free(entry);
}

/**
Expand All @@ -30,10 +47,13 @@ void free_entry(struct cache_entry *entry)
void dllist_insert_head(struct cache *cache, struct cache_entry *ce)
{
// Insert at the head of the list
if (cache->head == NULL) {
if (cache->head == NULL)
{
cache->head = cache->tail = ce;
ce->prev = ce->next = NULL;
} else {
}
else
{
cache->head->prev = ce;
ce->next = cache->head;
ce->prev = NULL;
Expand All @@ -46,13 +66,16 @@ void dllist_insert_head(struct cache *cache, struct cache_entry *ce)
*/
void dllist_move_to_head(struct cache *cache, struct cache_entry *ce)
{
if (ce != cache->head) {
if (ce == cache->tail) {
if (ce != cache->head)
{
if (ce == cache->tail)
{
// We're the tail
cache->tail = ce->prev;
cache->tail->next = NULL;

} else {
}
else
{
// We're neither the head nor the tail
ce->prev->next = ce->next;
ce->next->prev = ce->prev;
Expand All @@ -65,7 +88,6 @@ void dllist_move_to_head(struct cache *cache, struct cache_entry *ce)
}
}


/**
* Removes the tail from the list and returns it
*
Expand Down Expand Up @@ -94,6 +116,21 @@ struct cache *cache_create(int max_size, int hashsize)
///////////////////
// IMPLEMENT ME! //
///////////////////

// Allocate memory for the new cache
struct cache *cache = malloc(sizeof(struct cache));
// Doubly-linked list cache.h
cache->head = NULL;
// Doubly-linked list cache.h
cache->tail = NULL;
// cache->index is a struct hashtable
cache->index = hashtable_create(hashsize, NULL);
// Maximum number of entries, cache.h
cache->max_size = max_size;
// current number of entries, cache.h
cache->cur_size = 0;

return cache; // return the cache that's just been created
}

void cache_free(struct cache *cache)
Expand All @@ -102,7 +139,8 @@ void cache_free(struct cache *cache)

hashtable_destroy(cache->index);

while (cur_entry != NULL) {
while (cur_entry != NULL)
{
struct cache_entry *next_entry = cur_entry->next;

free_entry(cur_entry);
Expand All @@ -125,6 +163,33 @@ void cache_put(struct cache *cache, char *path, char *content_type, void *conten
///////////////////
// IMPLEMENT ME! //
///////////////////

// Allocate a new cache entry with the passed parameters
struct cache_entry *entry = alloc_entry(path, content_type, content, content_length);

// Insert entry at the head of the doubly linked list
dllist_insert_head(cache, entry);
// Store the entry in the hashtable as well, indexed by the entry's path
hashtable_put(cache->index, path, entry);
// Increment the current size of the cache
cache->cur_size++;

// If the cache size is greater than the max size
if (cache->cur_size > cache->max_size)
{
// Remove the cache entry at the tail of the linked list
struct cache_entry *old_tail = dllist_remove_tail(cache);
// Remove old_tail from the hashtable,
// using the entry's path and the hashtable_delete function
hashtable_delete(cache->index, old_tail->path);
// Free the cache entry
free_entry(old_tail);
// Ensure the size counter for the number of entries in the cache is correct
if (cache->cur_size > cache->max_size)
{
cache->cur_size -= 1;
}
}
}

/**
Expand All @@ -135,4 +200,18 @@ struct cache_entry *cache_get(struct cache *cache, char *path)
///////////////////
// IMPLEMENT ME! //
///////////////////

struct cache_entry *entry = hashtable_get(cache->index, path);

if (entry == NULL)
{
printf("Cache miss: %s\n", path);
return NULL;
}

printf("Cache hit: %s\n", path);

dllist_move_to_head(cache, entry);

return entry;
}
Loading