Skip to content

Commit

Permalink
Optimize file_cache_get() by only moving element to front if needed
Browse files Browse the repository at this point in the history
(most of the time there is no need).
Reduce code redundancy in file_cache_put() by calling file_cache_get().
Enhance debugging code.
  • Loading branch information
Laurent Monin committed Jul 2, 2008
1 parent 5f4a945 commit 86bea11
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 32 deletions.
63 changes: 32 additions & 31 deletions src/filecache.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "main.h"
#include "filecache.h"

/* Set to TRUE to add file cache dumps to the debug output */
const gboolean debug_file_cache = FALSE;

/* this implements a simple LRU algorithm */

struct _FileCacheData {
Expand All @@ -28,15 +31,6 @@ struct _FileCacheEntry {
gulong size;
};

static gint file_cache_entry_compare_cb(gconstpointer a, gconstpointer b)
{
const FileCacheEntry *fca = a;
const FileData *fd = b;
if (fca->fd == fd) return 0;
return 1;
}


FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size)
{
FileCacheData *fc = g_new(FileCacheData, 1);
Expand All @@ -47,26 +41,41 @@ FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size)
return fc;
}

gint file_cache_get(FileCacheData *fc, FileData *fd)
gboolean file_cache_get(FileCacheData *fc, FileData *fd)
{
GList *work;

work = g_list_find_custom(fc->list, fd, file_cache_entry_compare_cb);
if (work)
g_assert(fc && fd);

work = fc->list;
while (work)
{
fc->list = g_list_remove_link(fc->list, work);
fc->list = g_list_concat(work, fc->list);
DEBUG_1("cache hit: %s", fd->path);
return TRUE;
FileCacheEntry *fce = work->data;
if (fce->fd == fd)
{
/* entry exists */
DEBUG_1("cache hit: fc=%p %s", fc, fd->path);
if (work == fc->list) return TRUE; /* already at the beginning */
/* move it to the beginning */
DEBUG_1("cache move to front: fc=%p %s", fc, fd->path);
fc->list = g_list_remove_link(fc->list, work);
fc->list = g_list_concat(work, fc->list);
if (debug_file_cache) file_cache_dump(fc);
return TRUE;
}
work = work->next;
}
DEBUG_1("cache miss: %s", fd->path);
DEBUG_1("cache miss: fc=%p %s", fc, fd->path);
return FALSE;
}

void file_cache_set_size(FileCacheData *fc, gulong size)
{
GList *work;
FileCacheEntry *last_fe;

if (debug_file_cache) file_cache_dump(fc);

work = g_list_last(fc->list);
while (fc->size > size && work)
{
Expand All @@ -76,7 +85,7 @@ void file_cache_set_size(FileCacheData *fc, gulong size)
fc->list = g_list_delete_link(fc->list, work);
work = prev;

DEBUG_1("cache remove: %s", last_fe->fd->path);
DEBUG_1("cache remove: fc=%p %s", fc, last_fe->fd->path);
fc->size -= last_fe->size;
fc->release(last_fe->fd);
file_data_unref(last_fe->fd);
Expand All @@ -86,19 +95,11 @@ void file_cache_set_size(FileCacheData *fc, gulong size)

void file_cache_put(FileCacheData *fc, FileData *fd, gulong size)
{
GList *work;
FileCacheEntry *fe;

work = g_list_find_custom(fc->list, fd, file_cache_entry_compare_cb);
if (work)
{
/* entry already exists, move it to the beginning */
fc->list = g_list_remove_link(fc->list, work);
fc->list = g_list_concat(work, fc->list);
return;
}
if (file_cache_get(fc, fd)) return;

DEBUG_1("cache add: %s", fd->path);
DEBUG_1("cache add: fc=%p %s", fc, fd->path);
fe = g_new(FileCacheEntry, 1);
fe->fd = file_data_ref(fd);
fe->size = size;
Expand Down Expand Up @@ -128,13 +129,13 @@ void file_cache_dump(FileCacheData *fc)
{
GList *work;
work = fc->list;

DEBUG_1("cache dump: max size:%ld size:%ld", fc->max_size, fc->size);
guint n = 0;
DEBUG_1("cache dump: fc=%p max size:%ld size:%ld", fc, fc->max_size, fc->size);

while (work)
{
FileCacheEntry *fe = work->data;
work = work->next;
DEBUG_1("cache entry: %s %ld", fe->fd->path, fe->size);
DEBUG_1("cache entry: fc=%p [%lu] %s %ld", fc, ++n, fe->fd->path, fe->size);
}
}
2 changes: 1 addition & 1 deletion src/filecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ typedef void (*FileCacheReleaseFunc)(FileData *fd);


FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size);
gint file_cache_get(FileCacheData *fc, FileData *fd);
gboolean file_cache_get(FileCacheData *fc, FileData *fd);
void file_cache_put(FileCacheData *fc, FileData *fd, gulong size);
void file_cache_dump(FileCacheData *fc);
void file_cache_set_size(FileCacheData *fc, gulong size);
Expand Down

0 comments on commit 86bea11

Please sign in to comment.