Changes specific to mutt-ng:
+2005-05-14:
+ * header caching update: support for qdbm (which supports compressed
+ database files) has been added
+
2005-04-18:
* sidebar updates: eventually counting can be disabled and
$sidebar_newmail_only works way better
the necessary keywords to look them up in the manual, ChangeLog or other
sources of information.
+2005-05-14:
+
+ New Configuration Variables:
+ - $header_cache_compress - compress header cache database with qdbm
+ when switching to qdbm, please make sure to _first_ _completely_
+ remove the old header cache (files) as you need to start off from
+ scratch; compressed qdbm require much less space (only ~1/5)
+
2005-04-18:
New Configuration Variables:
OLDLIBS="$LIBS"
need_md5="yes"
+
+ ac_prefer_qdbm=yes
+ AC_ARG_WITH(qdbm, AC_HELP_STRING([--without-qdbm], [Don't use qdbm even if it is available]),
+ ac_prefer_qdbm=$withval)
+ if test x$ac_prefer_qdbm != xno; then
+ ac_cv_vlopen=no
+ QDBM_DIRS="$mutt_cv_prefix /usr/local /usr"
+ AC_MSG_CHECKING([for vlopen])
+ for d in $QDBM_DIRS; do
+ if test x$ac_cv_vlopen = xno && test -d "$d/include" && test -d "$d/lib"; then
+ QDBM_INC="-I$d/include"
+ QDBM_LIB="-L$d/lib"
+ CPPFLAGS="$OLDCPPFLAGS $QDBM_INC"
+ LIBS="$OLDLIBS $QDBM_LIB -lqdbm"
+ AC_TRY_LINK([#include <villa.h>],[vlopen(0,0,0);],[ac_cv_vlopen=yes])
+ fi
+ done
+ if test x$ac_cv_vlopen = xyes; then
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ fi
+
ac_prefer_gdbm=yes
AC_ARG_WITH(gdbm, AC_HELP_STRING([--without-gdbm], [Don't use gdbm even if it is available]),
ac_prefer_gdbm=$withval)
- if test x$ac_prefer_gdbm != xno; then
+ if test x$ac_prefer_gdbm != xno -a x$ac_cv_vlopen != xyes; then
ac_cv_gdbmopen=no
GDBM_DIRS="$mutt_cv_prefix /usr/local /usr"
AC_MSG_CHECKING([for gdbm_open])
ac_bdb_prefix=yes
AC_ARG_WITH(bdb, AC_HELP_STRING([--with-bdb[=DIR]], [Use BerkeleyDB4 if gdbm is not available ]),
ac_bdb_prefix=$withval)
- if test x$ac_bdb_prefix != xno -a x$ac_cv_gdbmopen != xyes; then
+ if test x$ac_bdb_prefix != xno -a x$ac_cv_gdbmopen != xyes -a x$ac_cv_vlopen != xyes; then
test x$ac_bdb_prefix = xyes && ac_bdb_prefix="$mutt_cv_prefix /opt/csw/bdb4 /opt /usr/local /usr"
for d in $ac_bdb_prefix; do
bdbpfx="$bdbpfx $d"
fi
fi
- if test x$ac_cv_gdbmopen = xyes; then
+ if test x$ac_cv_vlopen = xyes; then
+ CPPFLAGS="$OLDCPPFLAGS $QDBM_INC"
+ LIBS="$OLDLIBS $QDBM_LIB -lqdbm"
+ AC_DEFINE(HAVE_QDBM, 1, [QDBM Support])
+ elif test x$ac_cv_gdbmopen = xyes; then
CPPFLAGS="$OLDCPPFLAGS $GDBM_INC"
LIBS="$OLDLIBS $GDBM_LIB -lgdbm";
AC_DEFINE(HAVE_GDBM, 1, [GDBM Support])
LIBS="$OLDLIBS -L$BDB_LIB_DIR -l$BDB_LIB"
AC_DEFINE(HAVE_DB4, 1, [Sleepycat DB4 Support])
else
- AC_MSG_ERROR(You need Sleepycat DB4 or GDBM for --enable-hcache)
+ AC_MSG_ERROR(You need QDBM, GDBM or Sleepycat DB4 for --enable-hcache)
fi
fi])
dnl -- end cache --
#ifdef USE_HCACHE
-#if HAVE_GDBM
+#if HAVE_QDBM
+#include <depot.h>
+#include <cabin.h>
+#include <villa.h>
+#elif HAVE_GDBM
#include <gdbm.h>
#elif HAVE_DB4
#include <db.h>
#include "md5.h"
#include "lib/mem.h"
+#include "lib/debug.h"
-#if HAVE_GDBM
+#if HAVE_QDBM
+static struct
+ header_cache {
+ VILLA *db;
+ char *folder;
+ unsigned int crc;
+} HEADER_CACHE;
+#elif HAVE_GDBM
static struct
header_cache {
GDBM_FILE db;
return h;
}
-#if HAVE_GDBM
+#if HAVE_QDBM
+void *
+mutt_hcache_open(const char *path, const char *folder)
+{
+ struct header_cache *h = safe_calloc(1, sizeof (HEADER_CACHE));
+ int flags = 0;
+#if 0 /* FIXME */
+ int pagesize = atoi(HeaderCachePageSize) ? atoi(HeaderCachePageSize) : 16384;
+#endif
+ h->db = NULL;
+ h->folder = safe_strdup(folder);
+ h->crc = generate_crc32();
+
+ if (!path || path[0] == '\0')
+ {
+ FREE(&h->folder);
+ FREE(&h);
+ return NULL;
+ }
+
+ path = mutt_hcache_per_folder(path, folder);
+
+ if (option(OPTHCACHECOMPRESS))
+ flags = VL_OZCOMP;
+
+ h->db = vlopen(path, flags | VL_OWRITER | VL_OCREAT, VL_CMPLEX);
+ if (h->db)
+ return h;
+
+ /* if rw failed try ro */
+ h->db = vlopen(path, flags | VL_OREADER, VL_CMPLEX);
+ if (h->db)
+ return h;
+ else
+ {
+ FREE(&h->folder);
+ FREE(&h);
+
+ return NULL;
+ }
+}
+
+void
+mutt_hcache_close(void *db)
+{
+ struct header_cache *h = db;
+
+ if (!h)
+ return;
+
+ vlclose(h->db);
+ FREE(&h->folder);
+ FREE(&h);
+}
+
+void *
+mutt_hcache_fetch(void *db, const char *filename,
+ size_t(*keylen) (const char *fn))
+{
+ struct header_cache *h = db;
+ char path[_POSIX_PATH_MAX];
+ int ksize;
+ char *data = NULL;
+
+ if (!h)
+ return NULL;
+
+ strncpy(path, h->folder, sizeof (path));
+ safe_strcat(path, sizeof (path), filename);
+
+ ksize = strlen(h->folder) + keylen(path + strlen(h->folder));
+
+ data = vlget(h->db, path, ksize, NULL);
+
+ if (! crc32_matches(data, h->crc))
+ {
+ if (data) {
+ FREE(&data);
+ }
+ return NULL;
+ }
+
+ return data;
+}
+
+int
+mutt_hcache_store(void *db, const char *filename, HEADER * header,
+ unsigned long uid_validity,
+ size_t(*keylen) (const char *fn))
+{
+ struct header_cache *h = db;
+ char path[_POSIX_PATH_MAX];
+ int ret;
+ int ksize, dsize;
+ char *data = NULL;
+
+ if (!h)
+ return -1;
+
+ strncpy(path, h->folder, sizeof (path));
+ safe_strcat(path, sizeof (path), filename);
+
+ ksize = strlen(h->folder) + keylen(path + strlen(h->folder));
+
+ data = mutt_hcache_dump(db, header, &dsize, uid_validity);
+
+ ret = vlput(h->db, path, ksize, data, dsize, VL_DOVER);
+
+ FREE(&data);
+
+ return ret;
+}
+
+int
+mutt_hcache_delete(void *db, const char *filename,
+ size_t(*keylen) (const char *fn))
+{
+ struct header_cache *h = db;
+ char path[_POSIX_PATH_MAX];
+ int ksize;
+
+ if (!h)
+ return -1;
+
+ strncpy(path, h->folder, sizeof (path));
+ safe_strcat(path, sizeof (path), filename);
+
+ ksize = strlen(h->folder) + keylen(path + strlen(h->folder));
+
+ return vlout(h->db, path, ksize);
+}
+
+#elif HAVE_GDBM
void *mutt_hcache_open (const char *path, const char *folder)
{
** .pp
** If $$header_cache points to a directory it will contain a header cache
** database per folder. If $$header_cache points to a file that file will
- ** be a single global header cache. By default it is \fIunset\fP and so no
- ** header caching will be done.
+ ** be a single global header cache. By default it is \fIunset\fP so no
+ ** header caching will be used.
*/
{"maildir_header_cache_verify", DT_BOOL, R_NONE, OPTHCACHEVERIFY, 1},
/*
** Too large
** or too small of a page size for the common header can waste
** space, memory effectiveness, or CPU time. The default should be more or
- ** less the best you can get. For details google after Mutt-ng maildir header
+ ** less the best you can get. For details google for mutt header
** cache (first hit).
*/
+#if HAVE_QDBM
+ { "header_cache_compress", DT_BOOL, R_NONE, OPTHCACHECOMPRESS, 0 },
+ /*
+ ** .pp
+ ** If enabled the header cache will be compressed. So only one fifth of the usual
+ ** diskspace is used, but the uncompression can result in a slower open of the
+ ** cached folder.
+ */
+#endif /* HAVE_QDBM */
#endif /* USE_HCACHE */
{"maildir_trash", DT_BOOL, R_NONE, OPTMAILDIRTRASH, 0},
/*
OPTFORWQUOTE,
#if USE_HCACHE
OPTHCACHEVERIFY,
+#if HAVE_QDBM
+ OPTHCACHECOMPRESS,
+#endif /* HAVE_QDBM */
#endif
OPTHDRS,
OPTHEADER,