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