Mercurial > geeqie
annotate src/filecache.c @ 1422:91bed0d66cf2
gint -> gboolean and tidy up.
| author | zas_ |
|---|---|
| date | Thu, 12 Mar 2009 22:35:45 +0000 |
| parents | 8b89e3ff286b |
| children | cf4029d10d38 |
| 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 | |
| 1226 | 184 if (type != NOTIFY_TYPE_INTERNAL) /* 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: */ |
