author | Alberto Bertogli
<albertito@gmail.com> 2007-04-29 06:45:38 UTC |
committer | Alberto Bertogli
<albertito@gmail.com> 2007-04-29 06:45:38 UTC |
parent | d33c7a6be68271cf0300573a8c79b4800072f404 |
bindings/python/nmdb.py | +24 | -4 |
bindings/python/nmdb_ll.c | +44 | -0 |
diff --git a/bindings/python/nmdb.py b/bindings/python/nmdb.py index caa5663..d0d2eba 100644 --- a/bindings/python/nmdb.py +++ b/bindings/python/nmdb.py @@ -50,11 +50,12 @@ class NetworkError (Exception): class _nmdbDict (object): - def __init__(self, db, op_get, op_set, op_delete): + def __init__(self, db, op_get, op_set, op_delete, op_cas): self.db = db self.get = op_get self.set = op_set self.delete = op_delete + self._cas = op_cas self.autopickle = True def add_server(self, port): @@ -115,22 +116,41 @@ class _nmdbDict (object): "Returns True if the key is in the database, False otherwise." return self.__contains__(key) + def cas(self, key, oldval, newval): + "Perform a compare-and-swap." + if self.autopickle: + key = str(hash(key)) + oldval = cPickle.dumps(oldval, protocol = -1) + newval = cPickle.dumps(newval, protocol = -1) + r = self._cas(key, oldval, newval) + if r == 2: + # success + return 1 + elif r == 1: + # no match + return 0 + elif r == 0: + # not in + raise KeyError + else: + raise NetworkError + class Cache (_nmdbDict): def __init__(self, port = -1): db = nmdb_ll.connect(port) _nmdbDict.__init__(self, db, db.cache_get, db.cache_set, - db.cache_delete) + db.cache_delete, db.cache_cas) class DB (_nmdbDict): def __init__(self, port = -1): db = nmdb_ll.connect(port) - _nmdbDict.__init__(self, db, db.get, db.set, db.delete) + _nmdbDict.__init__(self, db, db.get, db.set, db.delete, db.cas) class SyncDB (_nmdbDict): def __init__(self, port = -1): db = nmdb_ll.connect(port) _nmdbDict.__init__(self, db, db.get, db.set_sync, - db.delete_sync) + db.delete_sync, db.cas) diff --git a/bindings/python/nmdb_ll.c b/bindings/python/nmdb_ll.c index 47f5b2c..387ea87 100644 --- a/bindings/python/nmdb_ll.c +++ b/bindings/python/nmdb_ll.c @@ -124,6 +124,28 @@ static PyObject *db_cache_delete(nmdbobject *db, PyObject *args) return PyLong_FromLong(rv); } +/* cache cas */ +static PyObject *db_cache_cas(nmdbobject *db, PyObject *args) +{ + unsigned char *key, *oldval, *newval; + int ksize, ovsize, nvsize; + int rv; + + if (!PyArg_ParseTuple(args, "s#s#s#:cache_cas", &key, &ksize, + &oldval, &ovsize, + &newval, &nvsize)) { + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + rv = nmdb_cache_cas(db->db, key, ksize, oldval, ovsize, + newval, nvsize); + Py_END_ALLOW_THREADS + + return PyLong_FromLong(rv); +} + + /* db set */ static PyObject *db_set(nmdbobject *db, PyObject *args) { @@ -196,6 +218,26 @@ static PyObject *db_delete(nmdbobject *db, PyObject *args) return PyLong_FromLong(rv); } +/* db cas */ +static PyObject *db_cas(nmdbobject *db, PyObject *args) +{ + unsigned char *key, *oldval, *newval; + int ksize, ovsize, nvsize; + int rv; + + if (!PyArg_ParseTuple(args, "s#s#s#:cas", &key, &ksize, + &oldval, &ovsize, + &newval, &nvsize)) { + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + rv = nmdb_cas(db->db, key, ksize, oldval, ovsize, newval, nvsize); + Py_END_ALLOW_THREADS + + return PyLong_FromLong(rv); +} + /* db set sync */ static PyObject *db_set_sync(nmdbobject *db, PyObject *args) @@ -243,9 +285,11 @@ static PyMethodDef nmdb_methods[] = { { "cache_set", (PyCFunction) db_cache_set, METH_VARARGS, NULL }, { "cache_get", (PyCFunction) db_cache_get, METH_VARARGS, NULL }, { "cache_delete", (PyCFunction) db_cache_delete, METH_VARARGS, NULL }, + { "cache_cas", (PyCFunction) db_cache_cas, METH_VARARGS, NULL }, { "set", (PyCFunction) db_set, METH_VARARGS, NULL }, { "get", (PyCFunction) db_get, METH_VARARGS, NULL }, { "delete", (PyCFunction) db_delete, METH_VARARGS, NULL }, + { "cas", (PyCFunction) db_cas, METH_VARARGS, NULL }, { "set_sync", (PyCFunction) db_set_sync, METH_VARARGS, NULL }, { "delete_sync", (PyCFunction) db_delete_sync, METH_VARARGS, NULL },