Begin to work on a pop reimplementation, using jobs and the event loop
[apps/madmutt.git] / lib-mx / hcache.c
index 74ccb5d..01db5bd 100644 (file)
 
 #ifdef USE_HCACHE
 
-#if defined(HAVE_QDBM)
-#include <depot.h>
-#include <cabin.h>
-#include <villa.h>
+#if defined(HAVE_TOKYOCABINET)
+#include <tcutil.h>
+#include <tchdb.h>
 #elif defined(HAVE_GDBM)
 #include <gdbm.h>
 #else
-#error neither HAVE_QDBM nor HAVE_GDBM are set ?!
+#error no supported DB library found ?
 #endif
 
 #include "charset.h"
@@ -28,8 +27,8 @@
 #include "hcache.h"
 
 struct hcache_t {
-#if defined(HAVE_QDBM)
-    VILLA *db;
+#if defined(HAVE_TOKYOCABINET)
+    TCHDB *db;
 #elif defined(HAVE_GDBM)
     GDBM_FILE db;
 #endif
@@ -52,20 +51,14 @@ static unsigned int crc32(unsigned int crc, const void *src, ssize_t len)
 
 static int generate_crc32(void)
 {
-    static int crc = 0;
+    int crc = 0;
 
     crc = crc32(crc, "madmutt.2007.05.13", m_strlen("madmutt.2007.05.13"));
-#ifdef HAVE_LANGINFO_CODESET
-    crc = crc32(crc, MCharset.charset, m_strlen(MCharset.charset));
-    crc = crc32(crc, "HAVE_LANGINFO_CODESET",
-                m_strlen("HAVE_LANGINFO_CODESET"));
+#ifdef HAVE_LANGINFO_H
+    crc = crc32(crc, mod_cset.charset, m_strlen(mod_cset.charset));
 #endif
     crc = crc32(crc, "USE_POP",   m_strlen("USE_POP"));
-    crc = crc32(crc, "MIXMASTER", m_strlen("MIXMASTER"));
     crc = crc32(crc, "USE_IMAP",  m_strlen("USE_IMAP"));
-#ifdef USE_NNTP
-    crc = crc32(crc, "USE_NNTP",  m_strlen("USE_NNTP"));
-#endif
     return crc;
 }
 
@@ -97,6 +90,11 @@ mutt_hcache_per_folder(const char *path, const char *folder)
 
 /* store and restore things {{{ */
 
+static void dump_int(buffer_t *buf, int i)
+{
+    buffer_add(buf, &i, sizeof(i));
+}
+
 static const void *restore_int(const char *d, int *i)
 {
     memcpy(i, d, sizeof(*i));
@@ -108,12 +106,12 @@ static void dump_cstr(buffer_t *buf, const char *s)
     int size = 0;
 
     if (m_strisempty(s)) {
-        buffer_add(buf, &size, sizeof(size));
+        dump_int(buf, size);
         return;
     }
 
     size = strlen(s) + 1;
-    buffer_add(buf, &size, sizeof(size));
+    dump_int(buf, size);
     buffer_add(buf, s, size);
 }
 
@@ -130,12 +128,12 @@ static void dump_address(buffer_t *buf, address_t *a)
 {
     int counter = 0, pos = buf->len;
 
-    buffer_add(buf, &counter, sizeof(counter));
+    dump_int(buf, counter);
 
     for (; a; a = a->next, counter++) {
         dump_cstr(buf, a->personal);
         dump_cstr(buf, a->mailbox);
-        buffer_add(buf, &a->group, sizeof(a->group));
+        dump_int(buf, a->group);
     }
 
     memcpy(buf->data + pos, &counter, sizeof(counter));
@@ -164,7 +162,7 @@ static void dump_list(buffer_t *buf, string_list_t *l)
     int pos = buf->len;
     int counter = 0;
 
-    buffer_add(buf, &counter, sizeof(counter));
+    dump_int(buf, counter);
 
     for (; l; l = l->next, counter++) {
         dump_cstr(buf, l->data);
@@ -193,7 +191,7 @@ static void dump_parameter(buffer_t *buf, parameter_t *p)
 {
     int pos = buf->len, counter = 0;
 
-    buffer_add(buf, &counter, sizeof(counter));
+    dump_int(buf, counter);
 
     for (; p; p = p->next, counter++) {
         dump_cstr(buf, p->attribute);
@@ -266,7 +264,7 @@ static void dump_envelope(buffer_t *buf, ENVELOPE * e)
 
     dump_cstr(buf, e->subject);
     n = e->real_subj ? e->real_subj - e->subject : -1;
-    buffer_add(buf, &n, sizeof(n));
+    dump_int(buf, n);
 
     dump_cstr(buf, e->message_id);
     dump_cstr(buf, e->supersedes);
@@ -274,13 +272,6 @@ static void dump_envelope(buffer_t *buf, ENVELOPE * e)
     dump_cstr(buf, e->x_label);
     dump_cstr(buf, e->list_post);
 
-#ifdef USE_NNTP
-    dump_cstr(buf, e->newsgroups);
-    dump_cstr(buf, e->xref);
-    dump_cstr(buf, e->followup_to);
-    dump_cstr(buf, e->x_comment_to);
-#endif
-
     dump_list(buf, e->references);
     dump_list(buf, e->in_reply_to);
     dump_list(buf, e->userhdrs);
@@ -312,17 +303,9 @@ static const void *restore_envelope(const char *d, ENVELOPE *e)
     d = restore_cstr(d, &e->x_label);
     d = restore_cstr(d, &e->list_post);
 
-#ifdef USE_NNTP
-    d = restore_cstr(d, &e->newsgroups);
-    d = restore_cstr(d, &e->xref);
-    d = restore_cstr(d, &e->followup_to);
-    d = restore_cstr(d, &e->x_comment_to);
-#endif
-
     d = restore_list(d, &e->references);
     d = restore_list(d, &e->in_reply_to);
     d = restore_list(d, &e->userhdrs);
-
     return d;
 }
 
@@ -334,7 +317,7 @@ static buffer_t *mutt_hcache_dump(hcache_t *db, HEADER *h, long uid_validity)
         uid_validity = time(NULL);
     }
     buffer_add(res, &uid_validity, sizeof(uid_validity));
-    buffer_add(res, &db->crc, sizeof(db->crc));
+    dump_int(res, db->crc);
     buffer_add(res, h, sizeof(*h));
 
     dump_envelope(res, h->env);
@@ -374,32 +357,30 @@ HEADER *mutt_hcache_restore(const void *_d, HEADER **oh)
 
 /* }}} */
 
-hcache_t *mutt_hcache_open(const char *path, const char *folder)
+hcache_t *mutt_hcache_open(const char *folder)
 {
-    hcache_t *h = p_new(hcache_t, 1);
-
-    h->folder = m_strdup(folder);
-    h->crc = generate_crc32();
+    const char *path;
+    hcache_t *h;
 
-    if (m_strisempty(path)) {
-        p_delete(&h->folder);
-        p_delete(&h);
+    if (m_strisempty(mod_core.cachedir)) {
         return NULL;
     }
 
-    path = mutt_hcache_per_folder(path, folder);
+    h = p_new(hcache_t, 1);
+    h->folder = m_strdup(folder);
+    h->crc    = generate_crc32();
 
-    {
-#if defined(HAVE_QDBM)
-        int flags = VL_OWRITER | VL_OCREAT;
-        if (option(OPTHCACHECOMPRESS))
-            flags |= VL_OZCOMP;
+    path = mutt_hcache_per_folder(mod_core.cachedir, folder);
 
-        h->db = vlopen(path, flags, VL_CMPLEX);
+    {
+#if defined(HAVE_TOKYOCABINET)
+        h->db = tchdbnew();
+        if (!tchdbopen(h->db, path, HDBOWRITER | HDBOCREAT)) {
+            tchdbdel(h->db);
+            h->db = NULL;
+        }
 #elif defined(HAVE_GDBM)
-        int pagesize = atoi(HeaderCachePageSize) ?: 16384;
-
-        h->db = gdbm_open((char *) path, pagesize, GDBM_WRCREAT, 00600, NULL);
+        h->db = gdbm_open((char *) path, 16384, GDBM_WRCREAT, 00600, NULL);
 #endif
     }
 
@@ -415,8 +396,9 @@ void mutt_hcache_close(hcache_t **db)
     if (!*db)
         return;
 
-#if defined(HAVE_QDBM)
-    vlclose((*db)->db);
+#if defined(HAVE_TOKYOCABINET)
+    tchdbdel((*db)->db);
+    (*db)->db = NULL;
 #elif defined(HAVE_GDBM)
     gdbm_close((*db)->db);
 #endif
@@ -429,7 +411,7 @@ void *mutt_hcache_fetch(hcache_t *db, const char *filename,
                         ssize_t (*keylen)(const char *fn))
 {
     char path[_POSIX_PATH_MAX];
-    void *data = NULL;
+    char *data = NULL;
 
     if (!db)
         return NULL;
@@ -437,11 +419,12 @@ void *mutt_hcache_fetch(hcache_t *db, const char *filename,
     snprintf(path, sizeof(path), "%s%s", db->folder, filename);
 
     {
-#if defined(HAVE_QDBM)
-        int ksize = strlen(db->folder) + keylen(path + strlen(db->folder));
-        data  = vlget(db->db, path, ksize, NULL);
+        int ksize = keylen(path);
+#if defined(HAVE_TOKYOCABINET)
+        int unused;
+        data  = tchdbget(db->db, path, ksize, &unused);
 #elif defined(HAVE_GDBM)
-        datum k = { .dptr = path, .dsize = keylen(path) };
+        datum k = { .dptr = path, .dsize = ksize };
 
         data = gdbm_fetch(db->db, k).dtpr;
 #endif
@@ -472,12 +455,11 @@ int mutt_hcache_store(hcache_t *db, const char *filename, HEADER *header,
     data = mutt_hcache_dump(db, header, uid_validity);
 
     {
-#if defined(HAVE_QDBM)
-        int ksize = strlen(db->folder) + keylen(path + strlen(db->folder));
-
-        ret = vlput(db->db, path, ksize, data->data, data->len, VL_DOVER);
+        int ksize = keylen(path);
+#if defined(HAVE_TOKYOCABINET)
+        ret = !!tchdbput(db->db, path, ksize, data->data, data->len) - 1;
 #elif defined(HAVE_GDBM)
-        datum k = { .dptr = path, .dsize = keylen(path) };
+        datum k = { .dptr = path, .dsize = ksize };
         datum v = { .dptr = data->data, .dsize = data->len };
 
         ret = gdbm_store(db->db, k, v, GDBM_REPLACE);
@@ -488,23 +470,23 @@ int mutt_hcache_store(hcache_t *db, const char *filename, HEADER *header,
     return ret;
 }
 
-int mutt_hcache_delete(hcache_t *db, const char *filename,
+void mutt_hcache_delete(hcache_t *db, const char *filename,
                        ssize_t (*keylen)(const char *fn))
 {
     char path[_POSIX_PATH_MAX];
 
     if (!db)
-        return -1;
+        return;
 
     snprintf(path, sizeof(path), "%s%s", db->folder, filename);
 
     {
-#if defined(HAVE_QDBM)
-        int ksize = strlen(db->folder) + keylen(path + strlen(db->folder));
-        return vlout(db->db, path, ksize);
+        int ksize = keylen(path);
+#if defined(HAVE_TOKYOCABINET)
+        tchdbout(db->db, path, ksize);
 #elif defined(HAVE_GDBM)
-        datum k = { .dptr = path, .dsize = keylen(path) };
-        return gdbm_delete(db->db, k);
+        datum k = { .dptr = path, .dsize = ksize };
+        gdbm_delete(db->db, k);
 #endif
     }
 }