Link Here
|
1 |
diff -Nru a/PATCHES b/PATCHES |
|
|
2 |
--- a/PATCHES |
3 |
+++ b/PATCHES |
4 |
@@ -0,0 +1 @@ |
5 |
+mutt-cvs-header-cache.30 |
6 |
--- a/configure.in |
7 |
+++ b/configure.in |
8 |
@@ -804,10 +804,23 @@ |
9 |
OLDLIBS="$LIBS" |
10 |
|
11 |
need_md5="yes" |
12 |
+ |
13 |
+ ac_prefer_qdbm=yes |
14 |
+ AC_ARG_WITH(qdbm, AC_HELP_STRING([--without-qdbm], [Don't use qdbm even if it is available]), |
15 |
+ ac_prefer_qdbm=$withval) |
16 |
+ if test x$ac_prefer_qdbm != xno; then |
17 |
+ CPPFLAGS="$OLDCPPFLAGS" |
18 |
+ LIBS="$OLDLIBS -lqdbm"; |
19 |
+ AC_CACHE_CHECK(for vlopen, ac_cv_vlopen,[ |
20 |
+ ac_cv_vlopen=no |
21 |
+ AC_TRY_LINK([#include <villa.h>],[vlopen(0,0,0);],[ac_cv_vlopen=yes]) |
22 |
+ ]) |
23 |
+ fi |
24 |
+ |
25 |
ac_prefer_gdbm=yes |
26 |
AC_ARG_WITH(gdbm, AC_HELP_STRING([--without-gdbm], [Don't use gdbm even if it is available]), |
27 |
ac_prefer_gdbm=$withval) |
28 |
- if test x$ac_prefer_gdbm != xno; then |
29 |
+ if test x$ac_prefer_gdbm != xno -a x$ac_cv_vlopen != xyes; then |
30 |
CPPFLAGS="$OLDCPPFLAGS" |
31 |
LIBS="$OLDLIBS -lgdbm"; |
32 |
AC_CACHE_CHECK(for gdbm_open, ac_cv_gdbmopen,[ |
33 |
@@ -819,7 +832,7 @@ |
34 |
ac_bdb_prefix=yes |
35 |
AC_ARG_WITH(bdb, AC_HELP_STRING([--with-bdb[=DIR]], [Use BerkeleyDB4 if gdbm is not available]), |
36 |
ac_bdb_prefix=$withval) |
37 |
- if test x$ac_bdb_prefix != xno -a x$ac_cv_gdbmopen != xyes; then |
38 |
+ if test x$ac_bdb_prefix != xno -a x$ac_cv_gdbmopen != xyes -a x$ac_cv_vlopen != xyes; then |
39 |
test x$ac_bdb_prefix = xyes && ac_bdb_prefix="$mutt_cv_prefix /opt/csw/bdb4 /opt /usr/local /usr" |
40 |
for d in $ac_bdb_prefix; do |
41 |
bdbpfx="$bdbpfx $d" |
42 |
@@ -865,7 +878,11 @@ |
43 |
fi |
44 |
fi |
45 |
|
46 |
- if test x$ac_cv_gdbmopen = xyes; then |
47 |
+ if test x$ac_cv_vlopen = xyes; then |
48 |
+ CPPFLAGS="$OLDCPPFLAGS" |
49 |
+ LIBS="$OLDLIBS -lqdbm"; |
50 |
+ AC_DEFINE(HAVE_QDBM, 1, [QDBM Support]) |
51 |
+ elif test x$ac_cv_gdbmopen = xyes; then |
52 |
CPPFLAGS="$OLDCPPFLAGS" |
53 |
LIBS="$OLDLIBS -lgdbm"; |
54 |
AC_DEFINE(HAVE_GDBM, 1, [GDBM Support]) |
55 |
--- a/hcache.c |
56 |
+++ b/hcache.c |
57 |
@@ -22,7 +22,11 @@ |
58 |
#include "config.h" |
59 |
#endif /* HAVE_CONFIG_H */ |
60 |
|
61 |
-#if HAVE_GDBM |
62 |
+#if HAVE_QDBM |
63 |
+#include <depot.h> |
64 |
+#include <cabin.h> |
65 |
+#include <villa.h> |
66 |
+#elif HAVE_GDBM |
67 |
#include <gdbm.h> |
68 |
#elif HAVE_DB4 |
69 |
#include <db.h> |
70 |
@@ -42,7 +46,14 @@ |
71 |
#include "lib.h" |
72 |
#include "md5.h" |
73 |
|
74 |
-#if HAVE_GDBM |
75 |
+#if HAVE_QDBM |
76 |
+static struct header_cache |
77 |
+{ |
78 |
+ VILLA *db; |
79 |
+ char *folder; |
80 |
+ unsigned int crc; |
81 |
+} HEADER_CACHE; |
82 |
+#elif HAVE_GDBM |
83 |
static struct header_cache |
84 |
{ |
85 |
GDBM_FILE db; |
86 |
@@ -615,7 +626,139 @@ |
87 |
return h; |
88 |
} |
89 |
|
90 |
-#if HAVE_GDBM |
91 |
+#if HAVE_QDBM |
92 |
+void * |
93 |
+mutt_hcache_open(const char *path, const char *folder) |
94 |
+{ |
95 |
+ struct header_cache *h = safe_calloc(1, sizeof (HEADER_CACHE)); |
96 |
+ int flags = 0; |
97 |
+#if 0 /* FIXME */ |
98 |
+ int pagesize = atoi(HeaderCachePageSize) ? atoi(HeaderCachePageSize) : 16384; |
99 |
+#endif |
100 |
+ h->db = NULL; |
101 |
+ h->folder = safe_strdup(folder); |
102 |
+ h->crc = generate_crc32(); |
103 |
+ |
104 |
+ if (!path || path[0] == '\0') |
105 |
+ { |
106 |
+ FREE(&h->folder); |
107 |
+ FREE(&h); |
108 |
+ return NULL; |
109 |
+ } |
110 |
+ |
111 |
+ path = mutt_hcache_per_folder(path, folder); |
112 |
+ |
113 |
+ if (option(OPTHCACHECOMPRESS)) |
114 |
+ flags = VL_OZCOMP; |
115 |
+ |
116 |
+ h->db = vlopen(path, flags | VL_OWRITER | VL_OCREAT, VL_CMPLEX); |
117 |
+ if (h->db) |
118 |
+ return h; |
119 |
+ |
120 |
+ /* if rw failed try ro */ |
121 |
+ h->db = vlopen(path, flags | VL_OREADER, 0); |
122 |
+ if (h->db) |
123 |
+ return h; |
124 |
+ else |
125 |
+ { |
126 |
+ FREE(&h->folder); |
127 |
+ FREE(&h); |
128 |
+ |
129 |
+ return NULL; |
130 |
+ } |
131 |
+} |
132 |
+ |
133 |
+void |
134 |
+mutt_hcache_close(void *db) |
135 |
+{ |
136 |
+ struct header_cache *h = db; |
137 |
+ |
138 |
+ if (!h) |
139 |
+ return; |
140 |
+ |
141 |
+ vlclose(h->db); |
142 |
+ FREE(&h->folder); |
143 |
+ FREE(&h); |
144 |
+} |
145 |
+ |
146 |
+void * |
147 |
+mutt_hcache_fetch(void *db, const char *filename, |
148 |
+ size_t(*keylen) (const char *fn)) |
149 |
+{ |
150 |
+ struct header_cache *h = db; |
151 |
+ char path[_POSIX_PATH_MAX]; |
152 |
+ int ksize; |
153 |
+ char *data = NULL; |
154 |
+ |
155 |
+ if (!h) |
156 |
+ return NULL; |
157 |
+ |
158 |
+ strncpy(path, h->folder, sizeof (path)); |
159 |
+ safe_strcat(path, sizeof (path), filename); |
160 |
+ |
161 |
+ ksize = strlen(h->folder) + keylen(path + strlen(h->folder)); |
162 |
+ |
163 |
+ data = vlget(h->db, path, ksize, NULL); |
164 |
+ |
165 |
+ if (! crc32_matches(data, h->crc)) |
166 |
+ { |
167 |
+ if (data) { |
168 |
+ FREE(&data); |
169 |
+ } |
170 |
+ return NULL; |
171 |
+ } |
172 |
+ |
173 |
+ return data; |
174 |
+} |
175 |
+ |
176 |
+int |
177 |
+mutt_hcache_store(void *db, const char *filename, HEADER * header, |
178 |
+ unsigned long uid_validity, |
179 |
+ size_t(*keylen) (const char *fn)) |
180 |
+{ |
181 |
+ struct header_cache *h = db; |
182 |
+ char path[_POSIX_PATH_MAX]; |
183 |
+ int ret; |
184 |
+ int ksize, dsize; |
185 |
+ char *data = NULL; |
186 |
+ |
187 |
+ if (!h) |
188 |
+ return -1; |
189 |
+ |
190 |
+ strncpy(path, h->folder, sizeof (path)); |
191 |
+ safe_strcat(path, sizeof (path), filename); |
192 |
+ |
193 |
+ ksize = strlen(h->folder) + keylen(path + strlen(h->folder)); |
194 |
+ |
195 |
+ data = mutt_hcache_dump(db, header, &dsize, uid_validity); |
196 |
+ |
197 |
+ ret = vlput(h->db, path, ksize, data, dsize, VL_DOVER); |
198 |
+ |
199 |
+ FREE(&data); |
200 |
+ |
201 |
+ return ret; |
202 |
+} |
203 |
+ |
204 |
+int |
205 |
+mutt_hcache_delete(void *db, const char *filename, |
206 |
+ size_t(*keylen) (const char *fn)) |
207 |
+{ |
208 |
+ struct header_cache *h = db; |
209 |
+ char path[_POSIX_PATH_MAX]; |
210 |
+ int ksize; |
211 |
+ |
212 |
+ if (!h) |
213 |
+ return -1; |
214 |
+ |
215 |
+ strncpy(path, h->folder, sizeof (path)); |
216 |
+ safe_strcat(path, sizeof (path), filename); |
217 |
+ |
218 |
+ ksize = strlen(h->folder) + keylen(path + strlen(h->folder)); |
219 |
+ |
220 |
+ return vlout(h->db, path, ksize); |
221 |
+} |
222 |
+ |
223 |
+#elif HAVE_GDBM |
224 |
|
225 |
void * |
226 |
mutt_hcache_open(const char *path, const char *folder) |
227 |
--- a/init.h |
228 |
+++ b/init.h |
229 |
@@ -1079,6 +1079,15 @@ |
230 |
** files when the header cache is in use. This incurs one stat(2) per |
231 |
** message every time the folder is opened. |
232 |
*/ |
233 |
+#if HAVE_QDBM |
234 |
+ { "header_cache_compress", DT_BOOL, R_NONE, OPTHCACHECOMPRESS, 0 }, |
235 |
+ /* |
236 |
+ ** .pp |
237 |
+ ** If enabled the header cache will be compressed. So only one fifth of the usual |
238 |
+ ** diskspace is used, but the uncompression can result in a slower open of the |
239 |
+ ** cached folder. |
240 |
+ */ |
241 |
+#endif /* HAVE_QDBM */ |
242 |
{ "header_cache_pagesize", DT_STR, R_NONE, UL &HeaderCachePageSize, UL "16384" }, |
243 |
/* |
244 |
** .pp |
245 |
--- a/mutt.h |
246 |
+++ b/mutt.h |
247 |
@@ -353,6 +353,9 @@ |
248 |
OPTFORWQUOTE, |
249 |
#if USE_HCACHE |
250 |
OPTHCACHEVERIFY, |
251 |
+#if HAVE_QDBM |
252 |
+ OPTHCACHECOMPRESS, |
253 |
+#endif /* HAVE_QDBM */ |
254 |
#endif |
255 |
OPTHDRS, |
256 |
OPTHEADER, |