Performance tests of TCBDB.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 5 Oct 2008 20:04:21 +0000 (22:04 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 5 Oct 2008 20:04:21 +0000 (22:04 +0200)
Random insertion is not very fast, but enumeration is. Maintenance may run
withing 15 seconds.

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
postlicyd/Makefile
postlicyd/tst-greylist.c [new file with mode: 0644]

index 0983841..8ffe7cd 100644 (file)
@@ -36,7 +36,7 @@ GENERATED = policy_tokens.h policy_tokens.c \
                                                filter_tokens.h filter_tokens.c \
                                                hook_tokens.h hook_tokens.c \
                                                param_tokens.h param_tokens.c
-TESTS     = tst-rbl tst-filters
+TESTS     = tst-rbl tst-filters tst-greylist
 
 FILTERS                = iplist.c greylist.c strlist.c match.c
 
@@ -44,9 +44,13 @@ postlicyd_SOURCES = main-postlicyd.c ../common/lib.a filter.c config.c query.c $
 postlicyd_LIBADD  = $(TC_LIBS)
 
 tst-rbl_SOURCES   = tst-rbl.c ../common/lib.a filter.c config.c query.c iplist.c $(GENERATED)
+
 tst-filters_SOURCES = tst-filters.c ../common/lib.a config.c filter.c query.c $(FILTERS) $(GENERATED)
 tst-filters_LIBADD  = $(TC_LIBS)
 
+tst-greylist_SOURCES = tst-greylist.c ../common/lib.a
+tst-greylist_LIBADD  = $(TC_LIBS)
+
 hook_tokens.h hook_tokens.c: $(FILTERS)
 param_tokens.c param_tokens.h: $(FILTERS) config.c
 
diff --git a/postlicyd/tst-greylist.c b/postlicyd/tst-greylist.c
new file mode 100644 (file)
index 0000000..ba5aa28
--- /dev/null
@@ -0,0 +1,161 @@
+/******************************************************************************/
+/*          pfixtools: a collection of postfix related tools                  */
+/*          ~~~~~~~~~                                                         */
+/*  ________________________________________________________________________  */
+/*                                                                            */
+/*  Redistribution and use in source and binary forms, with or without        */
+/*  modification, are permitted provided that the following conditions        */
+/*  are met:                                                                  */
+/*                                                                            */
+/*  1. Redistributions of source code must retain the above copyright         */
+/*     notice, this list of conditions and the following disclaimer.          */
+/*  2. Redistributions in binary form must reproduce the above copyright      */
+/*     notice, this list of conditions and the following disclaimer in the    */
+/*     documentation and/or other materials provided with the distribution.   */
+/*  3. The names of its contributors may not be used to endorse or promote    */
+/*     products derived from this software without specific prior written     */
+/*     permission.                                                            */
+/*                                                                            */
+/*  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND   */
+/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     */
+/*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        */
+/*  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS    */
+/*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR    */
+/*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF      */
+/*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  */
+/*  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN   */
+/*  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)   */
+/*  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF    */
+/*  THE POSSIBILITY OF SUCH DAMAGE.                                           */
+/******************************************************************************/
+
+/*
+ * Copyright © 2008 Florent Bruneau
+ */
+
+#include <tcbdb.h>
+
+#include "common.h"
+#include "str.h"
+
+
+struct awl_entry {
+    int32_t count;
+    time_t  last;
+};
+
+union obj {
+  struct {
+    unsigned a:8;
+    unsigned b:8;
+    unsigned c:8;
+    unsigned d:8;
+    unsigned e:8;
+    unsigned f:8;
+    unsigned g:8;
+    unsigned h:8;
+  } b;
+
+  struct {
+    unsigned a:32;
+    unsigned b:32;
+  } w;
+
+  uint64_t l;
+};
+
+__attribute__((used))
+static void fill_tree(TCBDB *db)
+{
+    char key[BUFSIZ];
+    union obj val;
+    ssize_t key_len;
+
+    struct awl_entry entry = { 0, 0 };
+
+    for (uint32_t i = 0 ; i < 1000000 ; ++i) {
+        val.w.a = random();
+        val.w.b = random();
+        key_len = snprintf(key, BUFSIZ, "%u.%u.%u.%u.%u.%u.%u.%u",
+                           val.b.a, val.b.b, val.b.c, val.b.d,
+                           val.b.e, val.b.f, val.b.g, val.b.h);
+        tcbdbput(db, key, key_len, &entry, sizeof(entry));
+        if (i && i % 10000 == 0) {
+            info("%u inserted... sill %u to go", i, 1000000 - i);
+        }
+    }
+    tcbdbsync(db);
+}
+
+static void enumerate_tree(TCBDB *src, TCBDB *dest)
+{
+    BDBCUR *cur = tcbdbcurnew(src);
+    TCXSTR *key, *value;
+    uint32_t new_count = 0;
+
+    key = tcxstrnew();
+    value = tcxstrnew();
+    if (tcbdbcurfirst(cur)) {
+        do {
+            tcxstrclear(key);
+            tcxstrclear(value);
+            (void)tcbdbcurrec(cur, key, value);
+
+            tcbdbput(dest, tcxstrptr(key), tcxstrsize(key),
+                      tcxstrptr(value), sizeof(struct awl_entry));
+            ++new_count;
+            if (new_count % 10000 == 0) {
+                info("%u enumerated... strill %u to go", new_count, 1000000 - new_count);
+            }
+        } while (tcbdbcurnext(cur));
+    }
+    tcxstrdel(key);
+    tcxstrdel(value);
+    tcbdbcurdel(cur);
+    tcbdbsync(dest);
+}
+
+int main(void)
+{
+    TCBDB *db;
+    TCBDB *tmp;
+    common_startup();
+
+    info("Fill the database with 1.000.000 of random entries");
+    db = tcbdbnew();
+    if (!tcbdbopen(db, "/tmp/test_greylist_perf", BDBOWRITER | BDBOCREAT | BDBOTRUNC)) {
+        err("can not open database: %s", tcbdberrmsg(tcbdbecode(db)));
+        tcbdbdel(db);
+        return -1;
+    }
+
+    fill_tree(db);
+    info("Done");
+    tcbdbclose(db);
+    tcbdbdel(db);
+
+    info("Enumerate the database in a new one");
+    tmp = tcbdbnew();
+    if (!tcbdbopen(tmp, "/tmp/test_greylist_perf.tmp",
+                   BDBOWRITER | BDBOCREAT | BDBOTRUNC)) {
+        err("can not open database: %s", tcbdberrmsg(tcbdbecode(tmp)));
+        tcbdbdel(tmp);
+        return -1;
+    }
+    db = tcbdbnew();
+    if (!tcbdbopen(db, "/tmp/test_greylist_perf", BDBOREADER)) {
+        err("can not open database: %s", tcbdberrmsg(tcbdbecode(db)));
+        tcbdbdel(db);
+        tcbdbdel(tmp);
+        return -1;
+    }
+
+    enumerate_tree(db, tmp);
+    info("done");
+    tcbdbclose(db);
+    tcbdbdel(db);
+    tcbdbclose(tmp);
+    tcbdbdel(tmp);
+
+    return 0;
+}