Mercurial > geeqie.yaz
annotate src/filecache.c @ 1433:b4ad1d201279
Use gboolean where applicable, minor cleanup and indentations fixes.
author | zas_ |
---|---|
date | Sat, 14 Mar 2009 19:25:21 +0000 |
parents | cf4029d10d38 |
children | 5f49f305a6b6 |
rev | line source |
---|---|
844 | 1 /* |
2 * Geeqie | |
1284 | 3 * Copyright (C) 2008 - 2009 The Geeqie Team |
844 | 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 | |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
16 /* Set to TRUE to add file cache dumps to the debug output */ |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
17 const gboolean debug_file_cache = FALSE; |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
18 |
844 | 19 /* this implements a simple LRU algorithm */ |
20 | |
21 struct _FileCacheData { | |
22 FileCacheReleaseFunc release; | |
23 GList *list; | |
24 gulong max_size; | |
25 gulong size; | |
1422 | 26 }; |
844 | 27 |
847 | 28 typedef struct _FileCacheEntry FileCacheEntry; |
29 struct _FileCacheEntry { | |
30 FileData *fd; | |
31 gulong size; | |
1422 | 32 }; |
847 | 33 |
888 | 34 static void file_cache_notify_cb(FileData *fd, NotifyType type, gpointer data); |
35 | |
844 | 36 FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size) |
37 { | |
38 FileCacheData *fc = g_new(FileCacheData, 1); | |
1422 | 39 |
844 | 40 fc->release = release; |
41 fc->list = NULL; | |
42 fc->max_size = max_size; | |
43 fc->size = 0; | |
888 | 44 |
45 file_data_register_notify_func(file_cache_notify_cb, fc, NOTIFY_PRIORITY_HIGH); | |
46 | |
844 | 47 return fc; |
48 } | |
49 | |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
50 gboolean file_cache_get(FileCacheData *fc, FileData *fd) |
844 | 51 { |
52 GList *work; | |
855 | 53 |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
54 g_assert(fc && fd); |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
55 |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
56 work = fc->list; |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
57 while (work) |
844 | 58 { |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
59 FileCacheEntry *fce = work->data; |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
60 if (fce->fd == fd) |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
61 { |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
62 /* entry exists */ |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
63 DEBUG_1("cache hit: fc=%p %s", fc, fd->path); |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
64 if (work == fc->list) return TRUE; /* already at the beginning */ |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
65 /* move it to the beginning */ |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
66 DEBUG_1("cache move to front: fc=%p %s", fc, fd->path); |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
67 fc->list = g_list_remove_link(fc->list, work); |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
68 fc->list = g_list_concat(work, fc->list); |
888 | 69 |
891 | 70 if (file_data_check_changed_files(fd)) /* this will eventually remove changed files from cache via file_cache_notify_cb */ |
71 return FALSE; | |
888 | 72 |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
73 if (debug_file_cache) file_cache_dump(fc); |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
74 return TRUE; |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
75 } |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
76 work = work->next; |
844 | 77 } |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
78 DEBUG_1("cache miss: fc=%p %s", fc, fd->path); |
844 | 79 return FALSE; |
80 } | |
81 | |
847 | 82 void file_cache_set_size(FileCacheData *fc, gulong size) |
83 { | |
84 GList *work; | |
85 FileCacheEntry *last_fe; | |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
86 |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
87 if (debug_file_cache) file_cache_dump(fc); |
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
88 |
847 | 89 work = g_list_last(fc->list); |
90 while (fc->size > size && work) | |
91 { | |
92 GList *prev; | |
93 last_fe = work->data; | |
995 | 94 prev = work->prev; |
847 | 95 fc->list = g_list_delete_link(fc->list, work); |
96 work = prev; | |
97 | |
888 | 98 DEBUG_1("file changed - cache remove: fc=%p %s", fc, last_fe->fd->path); |
847 | 99 fc->size -= last_fe->size; |
100 fc->release(last_fe->fd); | |
101 file_data_unref(last_fe->fd); | |
102 g_free(last_fe); | |
103 } | |
104 } | |
105 | |
844 | 106 void file_cache_put(FileCacheData *fc, FileData *fd, gulong size) |
107 { | |
847 | 108 FileCacheEntry *fe; |
855 | 109 |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
110 if (file_cache_get(fc, fd)) return; |
844 | 111 |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
112 DEBUG_1("cache add: fc=%p %s", fc, fd->path); |
847 | 113 fe = g_new(FileCacheEntry, 1); |
114 fe->fd = file_data_ref(fd); | |
115 fe->size = size; | |
116 fc->list = g_list_prepend(fc->list, fe); | |
117 fc->size += size; | |
844 | 118 |
847 | 119 file_cache_set_size(fc, fc->max_size); |
120 } | |
121 | |
122 gulong file_cache_get_max_size(FileCacheData *fc) | |
123 { | |
124 return fc->max_size; | |
125 } | |
126 | |
127 gulong file_cache_get_size(FileCacheData *fc) | |
128 { | |
129 return fc->size; | |
130 } | |
131 | |
132 void file_cache_set_max_size(FileCacheData *fc, gulong size) | |
133 { | |
134 fc->max_size = size; | |
135 file_cache_set_size(fc, fc->max_size); | |
844 | 136 } |
846 | 137 |
888 | 138 static void file_cache_remove_fd(FileCacheData *fc, FileData *fd) |
139 { | |
140 GList *work; | |
141 FileCacheEntry *fe; | |
142 | |
143 if (debug_file_cache) file_cache_dump(fc); | |
144 | |
145 work = fc->list; | |
146 while (work) | |
147 { | |
148 GList *current = work; | |
149 fe = work->data; | |
995 | 150 work = work->next; |
888 | 151 |
152 if (fe->fd == fd) | |
153 { | |
154 fc->list = g_list_delete_link(fc->list, current); | |
155 | |
156 DEBUG_1("cache remove: fc=%p %s", fc, fe->fd->path); | |
157 fc->size -= fe->size; | |
158 fc->release(fe->fd); | |
159 file_data_unref(fe->fd); | |
160 g_free(fe); | |
161 } | |
162 } | |
163 } | |
164 | |
846 | 165 void file_cache_dump(FileCacheData *fc) |
166 { | |
1422 | 167 GList *work = fc->list; |
1164 | 168 gulong n = 0; |
1422 | 169 |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
170 DEBUG_1("cache dump: fc=%p max size:%ld size:%ld", fc, fc->max_size, fc->size); |
847 | 171 |
855 | 172 while (work) |
846 | 173 { |
847 | 174 FileCacheEntry *fe = work->data; |
846 | 175 work = work->next; |
873
bd3bdceb1230
Optimize file_cache_get() by only moving element to front if needed
zas_
parents:
855
diff
changeset
|
176 DEBUG_1("cache entry: fc=%p [%lu] %s %ld", fc, ++n, fe->fd->path, fe->size); |
846 | 177 } |
178 } | |
888 | 179 |
180 static void file_cache_notify_cb(FileData *fd, NotifyType type, gpointer data) | |
181 { | |
182 FileCacheData *fc = data; | |
183 | |
1432 | 184 if (type & (NOTIFY_REREAD | NOTIFY_CHANGE)) /* invalidate the entry on each file change */ |
888 | 185 { |
186 file_cache_remove_fd(fc, fd); | |
187 } | |
893 | 188 } |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
995
diff
changeset
|
189 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |