Tidy up.
[geeqie.git] / src / filecache.c
1 /*
2  * Geeqie
3  * Copyright (C) 2008 The Geeqie Team
4  *
5  * Author: Vladimir Nadvornik
6  *
7  * This software is released under the GNU General Public License (GNU GPL).
8  * Please read the included file COPYING for more information.
9  * This software comes with no warranty of any kind, use at your own risk!
10  */
11
12
13 #include "main.h"
14 #include "filecache.h"
15
16 /* this implements a simple LRU algorithm */
17
18 struct _FileCacheData {
19         FileCacheReleaseFunc release;
20         GList *list;
21         gulong max_size;
22         gulong size;
23         };
24
25 typedef struct _FileCacheEntry FileCacheEntry;
26 struct _FileCacheEntry {
27         FileData *fd;
28         gulong size;
29         };
30
31 static gint file_cache_entry_compare_cb(gconstpointer a, gconstpointer b)
32 {
33         const FileCacheEntry *fca = a;
34         const FileData *fd = b;
35         if (fca->fd == fd) return 0;
36         return 1;
37 }
38
39
40 FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size)
41 {
42         FileCacheData *fc = g_new(FileCacheData, 1);
43         fc->release = release;
44         fc->list = NULL;
45         fc->max_size = max_size;
46         fc->size = 0;
47         return fc;
48 }
49
50 gint file_cache_get(FileCacheData *fc, FileData *fd)
51 {
52         GList *work;
53         
54         work = g_list_find_custom(fc->list, fd, file_cache_entry_compare_cb);
55         if (work)
56                 {
57                 fc->list = g_list_remove_link(fc->list, work);
58                 fc->list = g_list_concat(work, fc->list);
59                 DEBUG_1("cache hit: %s", fd->path);
60                 return TRUE;
61                 }
62         DEBUG_1("cache miss: %s", fd->path);
63         return FALSE;
64 }
65
66 void file_cache_set_size(FileCacheData *fc, gulong size)
67 {
68         GList *work;
69         FileCacheEntry *last_fe;
70         work = g_list_last(fc->list);
71         while (fc->size > size && work)
72                 {
73                 GList *prev;
74                 last_fe = work->data;
75                 prev = work->prev; 
76                 fc->list = g_list_delete_link(fc->list, work);
77                 work = prev;
78                 
79                 DEBUG_1("cache remove: %s", last_fe->fd->path);
80                 fc->size -= last_fe->size;
81                 fc->release(last_fe->fd);
82                 file_data_unref(last_fe->fd);
83                 g_free(last_fe);
84                 }
85 }
86
87 void file_cache_put(FileCacheData *fc, FileData *fd, gulong size)
88 {
89         GList *work;
90         FileCacheEntry *fe;
91
92         work = g_list_find_custom(fc->list, fd, file_cache_entry_compare_cb);
93         if (work)
94                 { 
95                 /* entry already exists, move it to the beginning */
96                 fc->list = g_list_remove_link(fc->list, work);
97                 fc->list = g_list_concat(work, fc->list);
98                 return;
99                 }
100         
101         DEBUG_1("cache add: %s", fd->path);
102         fe = g_new(FileCacheEntry, 1);
103         fe->fd = file_data_ref(fd);
104         fe->size = size;
105         fc->list = g_list_prepend(fc->list, fe);
106         fc->size += size;
107         
108         file_cache_set_size(fc, fc->max_size);
109 }
110
111 gulong file_cache_get_max_size(FileCacheData *fc)
112 {
113         return fc->max_size;
114 }
115
116 gulong file_cache_get_size(FileCacheData *fc)
117 {
118         return fc->size;
119 }
120
121 void file_cache_set_max_size(FileCacheData *fc, gulong size)
122 {
123         fc->max_size = size;
124         file_cache_set_size(fc, fc->max_size);
125 }
126
127 void file_cache_dump(FileCacheData *fc)
128 {
129         GList *work;
130         work = fc->list;
131         
132         DEBUG_1("cache dump: max size:%ld size:%ld", fc->max_size, fc->size);
133                 
134         while (work)
135                 {
136                 FileCacheEntry *fe = work->data;
137                 work = work->next;
138                 DEBUG_1("cache entry: %s %ld", fe->fd->path, fe->size);
139                 }
140 }