AC_ARG_WITH(gdbm, AS_HELP_STRING([--without-gdbm],[Don't use gdbm even if it is available]))
AC_ARG_WITH(bdb, AS_HELP_STRING([--with-bdb@<:@=DIR@:>@],[Use BerkeleyDB4 if gdbm is not available]))
AC_ARG_WITH(lmdb, AS_HELP_STRING([--with-lmdb@<:@=DIR@:>@],[Use LMDB if gdbm is not available]))
+AC_ARG_WITH(kyotocabinet, AS_HELP_STRING([--with-kyotocabinet@<:@=DIR@:>@],[Use kyotocabinet if gdbm is not available]))
db_found=no
if test x$enable_hcache = xyes
db_requested=lmdb
fi
fi
+ if test -n "$with_kyotocabinet" && test "$with_kyotocabinet" != "no"
+ then
+ if test "$db_requested" != "auto"
+ then
+ AC_MSG_ERROR([more than one header cache engine requested.])
+ else
+ db_requested=kc
+ fi
+ fi
dnl -- Tokyo Cabinet --
if test "$with_tokyocabinet" != "no" \
fi
fi
+ dnl -- Kyoto Cabinet --
+ if test x$with_kyotocabinet != xno && test $db_found = no \
+ && test "$db_requested" = auto -o "$db_requested" = kc
+ then
+ if test -n "$with_kyotocabinet" && test "$with_kyotocabinet" != "yes"
+ then
+ CPPFLAGS="$CPPFLAGS -I$with_kyotocabinet/include"
+ LDFLAGS="$LDFLAGS -L$with_kyotocabinet/lib"
+ fi
+
+ AC_CHECK_HEADER(kclangc.h,
+ AC_CHECK_LIB(kyotocabinet, kcdbopen,
+ [MUTTLIBS="$MUTTLIBS -lkyotocabinet"
+ AC_DEFINE(HAVE_KC, 1, [Kyoto Cabinet Support])
+ db_found=kc],
+ [CPPFLAGS="$OLDCPPFLAGS"
+ LDFLAGS="$OLDLDFLAGS"]))
+ if test "$db_requested" != auto && test "$db_found" != "$db_requested"
+ then
+ AC_MSG_ERROR([Kyoto Cabinet could not be used. Check config.log for details.])
+ fi
+ fi
+
if test $db_found = no
then
- AC_MSG_ERROR([You need Tokyo Cabinet, QDBM, GDBM or Berkeley DB4 for hcache])
+ AC_MSG_ERROR([You need Tokyo Cabinet, Kyoto Cabinet, QDBM, GDBM, LMDB or Berkeley DB4 for hcache])
fi
fi
dnl -- end cache --
Header caching can be enabled via the configure script and the
<emphasis>--enable-hcache</emphasis> option. It's not turned on by
default because external database libraries are required: one of
-tokyocabinet, qdbm, gdbm or bdb must be present.
+tokyocabinet, kyotocabinet, lmdb, qdbm, gdbm or bdb must be present.
</para>
<para>
#include <villa.h>
#elif HAVE_TC
#include <tcbdb.h>
+#elif HAVE_KC
+#include <kclangc.h>
#elif HAVE_GDBM
#include <gdbm.h>
#elif HAVE_DB4
char *folder;
unsigned int crc;
};
+#elif HAVE_KC
+struct header_cache
+{
+ KCDB *db;
+ char *folder;
+ unsigned int crc;
+};
#elif HAVE_GDBM
struct header_cache
{
#elif HAVE_TC
void *data;
int sp;
+#elif HAVE_KC
+ void *data;
+ size_t sp;
#elif HAVE_GDBM
datum key;
datum data;
#elif HAVE_TC
data = tcbdbget(h->db, path, ksize, &sp);
+ return data;
+#elif HAVE_KC
+ data = kcdbget(h->db, path, ksize, &sp);
+
return data;
#elif HAVE_GDBM
key.dptr = path;
return vlput(h->db, path, ksize, data, dlen, VL_DOVER);
#elif HAVE_TC
return tcbdbput(h->db, path, ksize, data, dlen);
+#elif HAVE_KC
+ return kcdbset(h->db, path, ksize, data, dlen);
#elif HAVE_GDBM
key.dptr = path;
key.dsize = ksize;
return tcbdbout(h->db, path, ksize);
}
+#elif HAVE_KC
+static int
+hcache_open_kc (struct header_cache* h, const char* path)
+{
+ char fullpath[_POSIX_PATH_MAX];
+
+ /* Kyoto cabinet options are discussed at
+ * http://fallabs.com/kyotocabinet/spex.html
+ * - rcomp is by default lex, so there is no need to specify it.
+ * - opts=l enables linear collision chaining as opposed to using a binary tree.
+ * this isn't suggested unless you are tuning the number of buckets.
+ * - opts=c enables compression
+ */
+ snprintf (fullpath, sizeof(fullpath), "%s#type=kct%s", path,
+ option(OPTHCACHECOMPRESS) ? "#opts=c" : "");
+ h->db = kcdbnew();
+ if (!h->db)
+ return -1;
+ if (kcdbopen(h->db, fullpath, KCOWRITER | KCOCREATE))
+ return 0;
+ else
+ {
+ dprint (2, (debugfile, "kcdbopen failed for %s: %s (ecode %d)\n", fullpath,
+ kcdbemsg (h->db), kcdbecode (h->db)));
+ kcdbdel(h->db);
+ return -1;
+ }
+}
+
+void
+mutt_hcache_close(header_cache_t *h)
+{
+ if (!h)
+ return;
+
+ if (!kcdbclose(h->db))
+ dprint (2, (debugfile, "kcdbclose failed for %s: %s (ecode %d)\n", h->folder,
+ kcdbemsg (h->db), kcdbecode (h->db)));
+ kcdbdel(h->db);
+ FREE(&h->folder);
+ FREE(&h);
+}
+
+int
+mutt_hcache_delete(header_cache_t *h, const char *filename,
+ size_t(*keylen) (const char *fn))
+{
+ 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 kcdbremove(h->db, path, ksize);
+}
+
#elif HAVE_GDBM
static int
hcache_open_gdbm (struct header_cache* h, const char* path)
hcache_open = hcache_open_qdbm;
#elif HAVE_TC
hcache_open= hcache_open_tc;
+#elif HAVE_KC
+ hcache_open= hcache_open_kc;
#elif HAVE_GDBM
hcache_open = hcache_open_gdbm;
#elif HAVE_DB4
{
return "tokyocabinet " _TC_VERSION;
}
+#elif HAVE_KC
+const char *mutt_hcache_backend (void)
+{
+ static char backend[SHORT_STRING];
+ snprintf(backend, sizeof(backend), "kyotocabinet %s", KCVERSION);
+ return backend;
+}
#endif
** Header caching can greatly improve speed when opening POP, IMAP
** MH or Maildir folders, see ``$caching'' for details.
*/
-#if defined(HAVE_QDBM) || defined(HAVE_TC)
+#if defined(HAVE_QDBM) || defined(HAVE_TC) || defined(HAVE_KC)
{ "header_cache_compress", DT_BOOL, R_NONE, OPTHCACHECOMPRESS, 1 },
/*
** .pp
- ** When mutt is compiled with qdbm or tokyocabinet as header cache backend,
- ** this option determines whether the database will be compressed.
+ ** When mutt is compiled with qdbm, tokyocabinet, or kyotocabinet as header
+ ** cache backend, this option determines whether the database will be compressed.
** Compression results in database files roughly being one fifth
** of the usual diskspace, but the decompression can result in a
** slower opening of cached folder(s) which in general is still
OPTFORWQUOTE,
#ifdef USE_HCACHE
OPTHCACHEVERIFY,
-#if defined(HAVE_QDBM) || defined(HAVE_TC)
+#if defined(HAVE_QDBM) || defined(HAVE_TC) || defined(HAVE_KC)
OPTHCACHECOMPRESS,
#endif /* HAVE_QDBM */
#endif