measure pixbuf cache size in bytes
[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         if ((work = g_list_find_custom(fc->list, fd, file_cache_entry_compare_cb)))
54                 {
55                 fc->list = g_list_remove_link(fc->list, work);
56                 fc->list = g_list_concat(work, fc->list);
57                 DEBUG_1("cache hit: %s", fd->path);
58                 return TRUE;
59                 }
60         DEBUG_1("cache miss: %s", fd->path);
61         return FALSE;
62 }
63
64 void file_cache_set_size(FileCacheData *fc, gulong size)
65 {
66         GList *work;
67         FileCacheEntry *last_fe;
68         work = g_list_last(fc->list);
69         while (fc->size > size && work)
70                 {
71                 GList *prev;
72                 last_fe = work->data;
73                 prev = work->prev; 
74                 fc->list = g_list_delete_link(fc->list, work);
75                 work = prev;
76                 
77                 DEBUG_1("cache remove: %s", last_fe->fd->path);
78                 fc->size -= last_fe->size;
79                 fc->release(last_fe->fd);
80                 file_data_unref(last_fe->fd);
81                 g_free(last_fe);
82                 }
83 }
84
85 void file_cache_put(FileCacheData *fc, FileData *fd, gulong size)
86 {
87         GList *work;
88         FileCacheEntry *fe;
89         if ((work = g_list_find_custom(fc->list, fd, file_cache_entry_compare_cb)))
90                 { 
91                 /* entry already exists, move it to the beginning */
92                 fc->list = g_list_remove_link(fc->list, work);
93                 fc->list = g_list_concat(work, fc->list);
94                 return;
95                 }
96         
97         DEBUG_1("cache add: %s", fd->path);
98         fe = g_new(FileCacheEntry, 1);
99         fe->fd = file_data_ref(fd);
100         fe->size = size;
101         fc->list = g_list_prepend(fc->list, fe);
102         fc->size += size;
103         
104         file_cache_set_size(fc, fc->max_size);
105 }
106
107 gulong file_cache_get_max_size(FileCacheData *fc)
108 {
109         return fc->max_size;
110 }
111
112 gulong file_cache_get_size(FileCacheData *fc)
113 {
114         return fc->size;
115 }
116
117 void file_cache_set_max_size(FileCacheData *fc, gulong size)
118 {
119         fc->max_size = size;
120         file_cache_set_size(fc, fc->max_size);
121 }
122
123 void file_cache_dump(FileCacheData *fc)
124 {
125         GList *work;
126         work = fc->list;
127         
128         DEBUG_1("cache dump: max size:%ld size:%ld", fc->max_size, fc->size);
129                 
130         while(work)
131                 {
132                 FileCacheEntry *fe = work->data;
133                 work = work->next;
134                 DEBUG_1("cache entry: %s %ld", fe->fd->path, fe->size);
135                 }
136 }