experimental QDBM TXN patch
Matthias Andree
matthias.andree at gmx.de
Tue Nov 9 00:07:11 CET 2004
Stefan Bellon <sbellon at sbellon.de> writes:
> Matthias Andree wrote:
>> OK, here's the second try of transactions for QDBM. Turns out QDBM
>> allows transactions only for writer database handles.
>
> This patch never sets handle->writer. So either, the transaction code
> always returns DST_OK without vltran* really being used (as
> !handle->writer is always true) or your patch isn't complete.
Something's jinxed... next version enclosed:
--- src/datastore_qdbm.c 1 Nov 2004 01:04:25 -0000 1.33
+++ src/datastore_qdbm.c 8 Nov 2004 23:04:41 -0000
@@ -7,7 +7,7 @@
AUTHORS:
Gyepi Sam <gyepi at praxis-sw.com> 2003
-Matthias Andree <matthias.andree at gmx.de> 2003
+Matthias Andree <matthias.andree at gmx.de> 2003-2004
Stefan Bellon <sbellon at sbellon.de> 2003-2004
******************************************************************************/
@@ -18,6 +18,7 @@
#include <cabin.h>
#include <villa.h>
#include <stdlib.h>
+#include <assert.h>
#include "datastore.h"
#include "datastore_db.h"
@@ -34,6 +35,7 @@
char *name;
bool locked;
bool created;
+ bool writer;
VILLA *dbp;
} dbh_t;
@@ -41,6 +43,7 @@
* or transactional initialization/shutdown */
static bool init = false;
+static bool txn = false;
/* Function definitions */
@@ -59,7 +62,6 @@
size_t len = strlen(path) + strlen(name) + 2;
handle = xmalloc(sizeof(dbh_t));
- memset(handle, 0, sizeof(dbh_t)); /* valgrind */
handle->path = xstrdup(path);
@@ -68,6 +70,9 @@
handle->locked = false;
handle->created = false;
+ handle->writer = false;
+
+ handle->dbp = NULL;
return handle;
}
@@ -123,6 +128,7 @@
dbp = handle->dbp = vlopen(handle->name, open_flags, cmpkey);
+ /* retry if a writer */
if ((dbp == NULL) && (open_mode & DS_WRITE)) {
dbp = handle->dbp = vlopen(handle->name, open_flags|VL_OCREAT, cmpkey);
if (dbp != NULL)
@@ -132,6 +138,9 @@
if (dbp == NULL)
goto open_err;
+ if (open_flags == VL_OWRITER)
+ handle->writer = true;
+
if (DEBUG_DATABASE(1))
fprintf(dbgout, "(qdbm) vlopen( %s, %d )\n", handle->name, open_mode);
@@ -203,14 +212,10 @@
*/
static inline void db_optimize(VILLA *dbp, char *name)
{
- UNUSED(dbp);
UNUSED(name);
- /* The Villa API doesn't need optimizing like the formerly used
- Depot API because Villa uses B+ trees and Depot uses hash tables.
- Database size may grow larger and could get compacted with
- vloptimize() however as the database size with Villa is smaller
- anyway, I don't think it is worth it. */
+ assert(!txn);
+ vloptimize(dbp);
}
@@ -230,7 +235,16 @@
exit(EX_ERROR);
}
+#if 0
+ /* The Villa API doesn't need optimizing like the formerly used
+ Depot API because Villa uses B+ trees and Depot uses hash tables.
+ Database size may grow larger and could get compacted with
+ vloptimize() however as the database size with Villa is smaller
+ anyway, I don't think it is worth it. -- Stefan Bellon */
+
+ /* NOTE: db_optimize must not be called with a transaction open! */
db_optimize(dbp, handle->name);
+#endif
return 0;
}
@@ -271,6 +285,7 @@
dbh_t *handle = vhandle;
VILLA * dbp = handle->dbp;
+ assert(!txn);
if (!vlsync(dbp))
print_error(__FILE__, __LINE__, "(qdbm) vlsync failed: %s",
dperrmsg(dpecode));
@@ -342,25 +357,61 @@
}
/** begin transaction. Returns 0 for success. */
-int db_txn_begin(void *d)
+int db_txn_begin(void *vhandle)
{
- UNUSED(d);
+ dbh_t *handle = vhandle;
+ VILLA *dbp = handle->dbp;
- return 0;
+ assert(!txn);
+ if (!handle->writer) return DST_OK;
+
+ if (vltranbegin(dbp)) {
+ if (DEBUG_DATABASE(2))
+ fprintf(dbgout, "(qdbm) vltranbegin(%p) success\n", (void *)dbp);
+ txn = true;
+ return DST_OK;
+ }
+ print_error(__FILE__, __LINE__, "(qdbm) vltranbegin(%s) failed: %s",
+ handle->name, dperrmsg(dpecode));
+ return DST_FAILURE;
}
-int db_txn_abort(void *d)
+int db_txn_abort(void *vhandle)
{
- UNUSED(d);
+ dbh_t *handle = vhandle;
+ VILLA *dbp = handle->dbp;
- return 0;
+ if (!handle->writer) return DST_OK;
+ assert(txn);
+
+ txn = false;
+ if (vltranabort(dbp)) {
+ if (DEBUG_DATABASE(2))
+ fprintf(dbgout, "(qdbm) vltranabort(%p) success\n", (void *)dbp);
+ return DST_OK;
+ }
+ print_error(__FILE__, __LINE__, "(qdbm) vltranabort(%s) failed: %s",
+ handle->name, dperrmsg(dpecode));
+ return DST_FAILURE;
}
-int db_txn_commit(void *d)
+int db_txn_commit(void *vhandle)
{
- UNUSED(d);
+ dbh_t *handle = vhandle;
+ VILLA *dbp = handle->dbp;
- return 0;
+ if (!handle->writer) return DST_OK;
+ assert(txn);
+
+ txn = false;
+ if (vltrancommit(dbp)) {
+ if (DEBUG_DATABASE(2))
+ fprintf(dbgout, "(qdbm) vltrancommit(%p) success\n", (void *)dbp);
+ return DST_OK;
+ }
+ print_error(__FILE__, __LINE__, "(qdbm) vltrancommit(%s) failed: %s",
+ handle->name, dperrmsg(dpecode));
+ return DST_FAILURE;
}
int db_recover(int a, int b)
--
Matthias Andree
More information about the bogofilter-dev
mailing list