From 7ec347c73eae86e40792179e088824bdc01e8fb2 Mon Sep 17 00:00:00 2001 From: Phillip Toland Date: Wed, 10 Dec 2008 16:04:34 -0600 Subject: [PATCH] Added flags to the put function. --- c_src/bdberl_drv.c | 21 ++++++++++++--------- src/bdberl_port.erl | 24 +++++++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/c_src/bdberl_drv.c b/c_src/bdberl_drv.c index 3ccd0e5..a10f89b 100644 --- a/c_src/bdberl_drv.c +++ b/c_src/bdberl_drv.c @@ -80,8 +80,9 @@ static hive_hash* G_DATABASES_NAMES; #define WRITE_UNLOCK(L) erl_drv_rwlock_rwunlock(L) #define DECODE_BYTE(_buf, _off) (_buf[_off]) -#define DECODE_INT(_buf, _off) (*((int*)_buf+_off)) -#define DECODE_STRING(_buf, _off) (char*)(_buf+_off) +#define DECODE_INT(_buf, _off) *((int*)(_buf+(_off))) +#define DECODE_STRING(_buf, _off) (char*)(_buf+(_off)) +#define DECODE_BLOB(_buf, _off) (void*)(_buf+(_off)) #define RETURN_BH(bh, outbuf) *outbuf = (char*)bh.bin; return bh.bin->orig_size; @@ -585,8 +586,11 @@ static int close_database(int dbref, unsigned flags, PortData* data) static void do_async_put(void* arg) { printf("do_async_put\n"); + + // Payload is: <> AsyncData* adata = (AsyncData*)arg; - + unsigned flags = DECODE_INT(adata->payload, 4); + // Setup DBTs DBT key; DBT value; @@ -594,16 +598,15 @@ static void do_async_put(void* arg) memset(&value, '\0', sizeof(DBT)); // Parse payload into DBTs - // Payload is: << DbRef:32, KeyLen:32, Key:KeyLen, ValLen:32, Val:ValLen>> - key.size = *((int*)(adata->payload + 4)); - key.data = (void*)(adata->payload + 8); - value.size = *((int*)(adata->payload + 8 + key.size)); - value.data = (void*)(adata->payload + 8 + key.size + 4); + key.size = DECODE_INT(adata->payload, 8); + key.data = DECODE_BLOB(adata->payload, 12); + value.size = DECODE_INT(adata->payload, 12 + key.size); + value.data = DECODE_BLOB(adata->payload, 12 + key.size + 4); // Execute the actual put -- we'll process the result back in the driver_async_ready function // All databases are opened with AUTO_COMMIT, so if msg->port->txn is NULL, the put will still // be atomic - adata->rc = adata->db->put(adata->db, adata->port->txn, &key, &value, 0); + adata->rc = adata->db->put(adata->db, adata->port->txn, &key, &value, flags); } static void do_async_put_free(void* arg) diff --git a/src/bdberl_port.erl b/src/bdberl_port.erl index 3a0c57c..24db0e8 100644 --- a/src/bdberl_port.erl +++ b/src/bdberl_port.erl @@ -10,7 +10,7 @@ open_database/3, open_database/4, close_database/2, txn_begin/1, txn_commit/1, txn_abort/1, - put/4, + put/4, put/5, get/3]). -define(CMD_NONE, 0). @@ -36,7 +36,10 @@ -define(DB_THREAD, 16#00000004). -define(DB_TRUNCATE, 16#00008000). --define(DB_NOSYNC, 21). +-define(DB_APPEND, 2). +-define(DB_NODUPDATA, 19). +-define(DB_NOOVERWRITE, 20). +-define(DB_NOSYNC, 21). -define(STATUS_OK, 0). -define(STATUS_ERROR, 1). @@ -119,11 +122,14 @@ txn_abort(Port) -> ?ERROR_NO_TXN -> {error, no_txn} end. - put(Port, DbRef, Key, Value) -> + put(Port, DbRef, Key, Value, []). + +put(Port, DbRef, Key, Value, Opts) -> {KeyLen, KeyBin} = to_binary(Key), {ValLen, ValBin} = to_binary(Value), - Cmd = <>, + Flags = process_flags(Opts), + Cmd = <>, <> = erlang:port_control(Port, ?CMD_PUT, Cmd), case Result of ?ERROR_NONE -> @@ -150,27 +156,27 @@ get(Port, DbRef, Key) -> ?ERROR_ASYNC_PENDING -> {error, async_pending}; ?ERROR_INVALID_DBREF -> {error, invalid_dbref} end. - - - to_binary(Term) -> Bin = term_to_binary(Term), {size(Bin), Bin}. -process_flags([Flag]) -> - flag_value(Flag); +process_flags([]) -> + 0; process_flags([Flag|Flags]) -> flag_value(Flag) bor process_flags(Flags). flag_value(Flag) -> case Flag of + append -> ?DB_APPEND; auto_commit -> ?DB_AUTO_COMMIT; create -> ?DB_CREATE; exclusive -> ?DB_EXCL; multiversion -> ?DB_MULTIVERSION; + no_duplicate -> ?DB_NODUPDATA; no_mmap -> ?DB_NOMMAP; + no_overwrite -> ?DB_NOOVERWRITE; no_sync -> ?DB_NOSYNC; readonly -> ?DB_RDONLY; threaded -> ?DB_THREAD;