Link Here
|
2 |
--- a/PATCHES |
2 |
--- a/PATCHES |
3 |
+++ b/PATCHES |
3 |
+++ b/PATCHES |
4 |
@@ -0,0 +1 @@ |
4 |
@@ -0,0 +1 @@ |
5 |
+mutt-cvs-header-cache.29 |
5 |
+mutt-cvs-header-cache.30 |
6 |
diff -Nru a/init.h b/init.h |
6 |
--- a/configure.in |
7 |
--- a/init.h 2005-02-12 22:08:19 +01:00 |
7 |
+++ b/configure.in |
8 |
+++ b/init.h 2005-02-13 00:51:10 +01:00 |
8 |
@@ -804,10 +804,23 @@ |
9 |
@@ -1032,6 +1032,13 @@ |
9 |
OLDLIBS="$LIBS" |
10 |
** global header cache for all folders is used. Per default it is unset and so |
10 |
|
11 |
** no header caching will be used. |
11 |
need_md5="yes" |
12 |
*/ |
12 |
+ |
13 |
+ { "maildir_header_cache_verify", DT_BOOL, R_NONE, OPTHCACHEVERIFY, 1 }, |
13 |
+ ac_prefer_qdbm=yes |
14 |
+ /* |
14 |
+ AC_ARG_WITH(qdbm, AC_HELP_STRING([--without-qdbm], [Don't use qdbm even if it is available]), |
15 |
+ ** .pp |
15 |
+ ac_prefer_qdbm=$withval) |
16 |
+ ** Check for Maildir unaware programs other than mutt having modified maildir |
16 |
+ if test x$ac_prefer_qdbm != xno; then |
17 |
+ ** files when the header cache is in use. This incurs one stat(2) per |
17 |
+ CPPFLAGS="$OLDCPPFLAGS" |
18 |
+ ** message every time the folder is opened. |
18 |
+ LIBS="$OLDLIBS -lqdbm"; |
19 |
+ */ |
19 |
+ AC_CACHE_CHECK(for vlopen, ac_cv_vlopen,[ |
20 |
{ "header_cache_pagesize", DT_STR, R_NONE, UL &HeaderCachePageSize, UL "16384" }, |
20 |
+ ac_cv_vlopen=no |
21 |
/* |
21 |
+ AC_TRY_LINK([#include <villa.h>],[vlopen(0,0,0);],[ac_cv_vlopen=yes]) |
22 |
** .pp |
22 |
+ ]) |
23 |
diff -Nru a/mh.c b/mh.c |
23 |
+ fi |
24 |
--- a/mh.c 2005-02-03 19:01:43 +01:00 |
24 |
+ |
25 |
+++ b/mh.c 2005-02-05 12:25:16 +01:00 |
25 |
ac_prefer_gdbm=yes |
26 |
@@ -791,6 +791,14 @@ |
26 |
AC_ARG_WITH(gdbm, AC_HELP_STRING([--without-gdbm], [Don't use gdbm even if it is available]), |
27 |
return r; |
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; |
28 |
} |
88 |
} |
29 |
|
89 |
|
30 |
+#if USE_HCACHE |
90 |
-#if HAVE_GDBM |
31 |
+static size_t maildir_hcache_keylen (const char *fn) |
91 |
+#if HAVE_QDBM |
|
|
92 |
+void * |
93 |
+mutt_hcache_open(const char *path, const char *folder) |
32 |
+{ |
94 |
+{ |
33 |
+ const char * p = strrchr (fn, ':'); |
95 |
+ struct header_cache *h = safe_calloc(1, sizeof (HEADER_CACHE)); |
34 |
+ return p ? (size_t) (p - fn) : mutt_strlen(fn); |
96 |
+ int flags = 0; |
35 |
+} |
97 |
+#if 0 /* FIXME */ |
36 |
+#endif |
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(); |
37 |
+ |
103 |
+ |
38 |
#ifdef USE_INODESORT |
104 |
+ if (!path || path[0] == '\0') |
39 |
/* |
105 |
+ { |
40 |
* Merge two maildir lists according to the inode numbers. |
106 |
+ FREE(&h->folder); |
41 |
@@ -886,27 +894,67 @@ |
107 |
+ FREE(&h); |
42 |
* This function does the second parsing pass for a maildir-style |
108 |
+ return NULL; |
43 |
* folder. |
109 |
+ } |
44 |
*/ |
|
|
45 |
- |
46 |
void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) |
47 |
{ |
48 |
struct maildir *p; |
49 |
char fn[_POSIX_PATH_MAX]; |
50 |
int count; |
51 |
|
52 |
+#if USE_HCACHE |
53 |
+ void *hc = NULL; |
54 |
+ void *data; |
55 |
+ struct timeval *when = NULL; |
56 |
+ struct stat lastchanged; |
57 |
+ int ret; |
58 |
+ |
110 |
+ |
59 |
+ hc = mutt_hcache_open (HeaderCache, ctx->path); |
111 |
+ path = mutt_hcache_per_folder(path, folder); |
60 |
+#endif |
|
|
61 |
+ |
112 |
+ |
62 |
for (p = md, count = 0; p; p = p->next, count++) |
113 |
+ if (option(OPTHCACHECOMPRESS)) |
63 |
- if (p && p->h && !p->header_parsed) |
114 |
+ flags = VL_OZCOMP; |
64 |
- { |
115 |
+ |
65 |
- if (!ctx->quiet && ReadInc && ((count % ReadInc) == 0 || count == 1)) |
116 |
+ h->db = vlopen(path, flags | VL_OWRITER | VL_OCREAT, VL_CMPLEX); |
66 |
- mutt_message (_("Reading %s... %d"), ctx->path, count); |
117 |
+ if (h->db) |
67 |
- snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path); |
118 |
+ return h; |
68 |
- if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) |
119 |
+ |
69 |
- p->header_parsed = 1; |
120 |
+ /* if rw failed try ro */ |
70 |
- else |
121 |
+ h->db = vlopen(path, flags | VL_OREADER, 0); |
71 |
- mutt_free_header (&p->h); |
122 |
+ if (h->db) |
72 |
- } |
123 |
+ return h; |
73 |
-} |
124 |
+ else |
74 |
+ { |
125 |
+ { |
75 |
+ if (! (p && p->h && !p->header_parsed)) |
126 |
+ FREE(&h->folder); |
76 |
+ continue; |
127 |
+ FREE(&h); |
77 |
|
128 |
+ |
78 |
+ if (!ctx->quiet && ReadInc && ((count % ReadInc) == 0 || count == 1)) |
129 |
+ return NULL; |
79 |
+ mutt_message (_("Reading %s... %d"), ctx->path, count); |
130 |
+ } |
80 |
|
131 |
+} |
81 |
+#if USE_HCACHE |
|
|
82 |
+ data = mutt_hcache_fetch (hc, p->h->path + 3, &maildir_hcache_keylen); |
83 |
+ when = (struct timeval *) data; |
84 |
+#endif |
85 |
+ |
132 |
+ |
86 |
+ snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path); |
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 |
+} |
87 |
+ |
145 |
+ |
88 |
+#if USE_HCACHE |
146 |
+void * |
89 |
+ if (option(OPTHCACHEVERIFY)) |
147 |
+mutt_hcache_fetch(void *db, const char *filename, |
90 |
+ ret = stat(fn, &lastchanged); |
148 |
+ size_t(*keylen) (const char *fn)) |
91 |
+ else { |
149 |
+{ |
92 |
+ lastchanged.st_mtime = 0; |
150 |
+ struct header_cache *h = db; |
93 |
+ ret = 0; |
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); |
94 |
+ } |
169 |
+ } |
95 |
+ |
170 |
+ return NULL; |
96 |
+ if (data != NULL && !ret && lastchanged.st_mtime <= when->tv_sec) |
|
|
97 |
+ { |
98 |
+ p->h = mutt_hcache_restore ((unsigned char *)data, &p->h); |
99 |
+ maildir_parse_flags (p->h, fn); |
100 |
+ } else |
101 |
+#endif |
102 |
+ if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) |
103 |
+ { |
104 |
+ p->header_parsed = 1; |
105 |
+#if USE_HCACHE |
106 |
+ mutt_hcache_store (hc, p->h->path + 3, p->h, 0, &maildir_hcache_keylen); |
107 |
+#endif |
108 |
+ } else |
109 |
+ mutt_free_header (&p->h); |
110 |
+#if USE_HCACHE |
111 |
+ FREE(&data); |
112 |
+#endif |
113 |
+ } |
171 |
+ } |
114 |
+#if USE_HCACHE |
172 |
+ |
115 |
+ mutt_hcache_close (hc); |
173 |
+ return data; |
116 |
+#endif |
|
|
117 |
+} |
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 |
118 |
|
224 |
|
119 |
/* Read a MH/maildir style mailbox. |
225 |
void * |
120 |
* |
226 |
mutt_hcache_open(const char *path, const char *folder) |
121 |
@@ -1403,6 +1451,9 @@ |
227 |
--- a/init.h |
122 |
{ |
228 |
+++ b/init.h |
123 |
char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX]; |
229 |
@@ -1079,6 +1079,15 @@ |
124 |
int i, j; |
230 |
** files when the header cache is in use. This incurs one stat(2) per |
125 |
+#if USE_HCACHE |
231 |
** message every time the folder is opened. |
126 |
+ void *hc = NULL; |
232 |
*/ |
127 |
+#endif /* USE_HCACHE */ |
233 |
+#if HAVE_QDBM |
128 |
|
234 |
+ { "header_cache_compress", DT_BOOL, R_NONE, OPTHCACHECOMPRESS, 0 }, |
129 |
if (ctx->magic == M_MH) |
235 |
+ /* |
130 |
i = mh_check_mailbox (ctx, index_hint); |
236 |
+ ** .pp |
131 |
@@ -1412,6 +1463,11 @@ |
237 |
+ ** If enabled the header cache will be compressed. So only one fifth of the usual |
132 |
if (i != 0) |
238 |
+ ** diskspace is used, but the uncompression can result in a slower open of the |
133 |
return i; |
239 |
+ ** cached folder. |
134 |
|
240 |
+ */ |
135 |
+#if USE_HCACHE |
241 |
+#endif /* HAVE_QDBM */ |
136 |
+ if (ctx->magic == M_MAILDIR) |
242 |
{ "header_cache_pagesize", DT_STR, R_NONE, UL &HeaderCachePageSize, UL "16384" }, |
137 |
+ hc = mutt_hcache_open(HeaderCache, ctx->path); |
243 |
/* |
138 |
+#endif /* USE_HCACHE */ |
244 |
** .pp |
139 |
+ |
245 |
--- a/mutt.h |
140 |
for (i = 0; i < ctx->msgcount; i++) |
246 |
+++ b/mutt.h |
141 |
{ |
247 |
@@ -353,6 +353,9 @@ |
142 |
if (ctx->hdrs[i]->deleted |
|
|
143 |
@@ -1420,7 +1476,13 @@ |
144 |
snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path); |
145 |
if (ctx->magic == M_MAILDIR |
146 |
|| (option (OPTMHPURGE) && ctx->magic == M_MH)) |
147 |
+ { |
148 |
+#if USE_HCACHE |
149 |
+ if (ctx->magic == M_MAILDIR) |
150 |
+ mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, &maildir_hcache_keylen); |
151 |
+#endif /* USE_HCACHE */ |
152 |
unlink (path); |
153 |
+ } |
154 |
else if (ctx->magic == M_MH) |
155 |
{ |
156 |
/* MH just moves files out of the way when you delete them */ |
157 |
@@ -1442,16 +1504,21 @@ |
158 |
if (ctx->magic == M_MAILDIR) |
159 |
{ |
160 |
if (maildir_sync_message (ctx, i) == -1) |
161 |
- return -1; |
162 |
+ goto err; |
163 |
} |
164 |
else |
165 |
{ |
166 |
if (mh_sync_message (ctx, i) == -1) |
167 |
- return -1; |
168 |
+ goto err; |
169 |
} |
170 |
} |
171 |
} |
172 |
|
173 |
+#if USE_HCACHE |
174 |
+ if (ctx->magic == M_MAILDIR) |
175 |
+ mutt_hcache_close (hc); |
176 |
+#endif /* USE_HCACHE */ |
177 |
+ |
178 |
if (ctx->magic == M_MH) |
179 |
mh_update_sequences (ctx); |
180 |
|
181 |
@@ -1472,6 +1539,13 @@ |
182 |
} |
183 |
|
184 |
return 0; |
185 |
+ |
186 |
+err: |
187 |
+#if USE_HCACHE |
188 |
+ if (ctx->magic == M_MAILDIR) |
189 |
+ mutt_hcache_close (hc); |
190 |
+#endif /* USE_HCACHE */ |
191 |
+ return -1; |
192 |
} |
193 |
|
194 |
static char *maildir_canon_filename (char *dest, const char *src, size_t l) |
195 |
diff -Nru a/mutt.h b/mutt.h |
196 |
--- a/mutt.h 2005-02-12 21:19:25 +01:00 |
197 |
+++ b/mutt.h 2005-02-13 00:51:10 +01:00 |
198 |
@@ -351,6 +351,9 @@ |
199 |
OPTFORCENAME, |
200 |
OPTFORWDECODE, |
201 |
OPTFORWQUOTE, |
248 |
OPTFORWQUOTE, |
202 |
+#if USE_HCACHE |
249 |
#if USE_HCACHE |
203 |
+ OPTHCACHEVERIFY, |
250 |
OPTHCACHEVERIFY, |
204 |
+#endif |
251 |
+#if HAVE_QDBM |
|
|
252 |
+ OPTHCACHECOMPRESS, |
253 |
+#endif /* HAVE_QDBM */ |
254 |
#endif |
205 |
OPTHDRS, |
255 |
OPTHDRS, |
206 |
OPTHEADER, |
256 |
OPTHEADER, |
207 |
OPTHELP, |
|
|