diff options
author | Magnus Ahltorp <map@kth.se> | 2016-02-11 02:48:12 +0100 |
---|---|---|
committer | Linus Nordberg <linus@nordu.net> | 2016-04-25 13:14:10 +0200 |
commit | d1ea31e0818038452dab54afe8b6350d08075318 (patch) | |
tree | 695942c9c9b66ebc9736e9917c3bda55133df510 /c_src/permdbpy.c | |
parent | 76a135b93d47b9cb5be5b80b831b9c59c805edb7 (diff) |
Added python bindings for permdb.
Diffstat (limited to 'c_src/permdbpy.c')
-rw-r--r-- | c_src/permdbpy.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/c_src/permdbpy.c b/c_src/permdbpy.c new file mode 100644 index 0000000..a98c83a --- /dev/null +++ b/c_src/permdbpy.c @@ -0,0 +1,271 @@ +#include <Python.h> +#include "permdb.h" + +typedef struct permdb_object_py { + PyObject_HEAD + struct permdb_object *permdb; +} permdb_object_py; + +static void +permdb_dealloc(permdb_object_py *state) +{ + permdb_free(state->permdb); +} + +PyTypeObject permdb_type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "permdb.permdb", /*tp_name*/ + sizeof(permdb_object_py), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)permdb_dealloc,/*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "PermDB state", /*tp_doc*/ +}; + +permdb_object_py * +permdb_alloc_py(const char *dbpath) +{ + permdb_object_py *state = PyObject_New(permdb_object_py, &permdb_type); + state->permdb = permdb_alloc(dbpath); + return state; +} + +typedef struct node_object_py { + PyObject_HEAD + node_object nodeobj; +} node_object_py; + +static void +pynode_dealloc(node_object_py *node) +{ + +} + +static PyObject* +node_getitem(PyObject *o, PyObject *key) +{ + unsigned int n = PyLong_AsUnsignedLong(key); + node_object_py *node = (node_object_py *)o; + + return PyLong_FromUnsignedLongLong(get_entry_in_node(node->nodeobj, n)); +} + +static PyMappingMethods node_as_mapping = { + 0, /* mp_length */ + node_getitem, /* mp_subscript */ + 0, /* mp_ass_subscript */ +}; + +static PyTypeObject node_type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "permdb.node", /*tp_name*/ + sizeof(node_object_py), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)pynode_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + &node_as_mapping, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "PermDB node", /*tp_doc*/ +}; + + +static node_object_py * +node_alloc(node_object data) +{ + node_object_py *node = PyObject_New(node_object_py, &node_type); + node->nodeobj = data; + return node; +} + + +static PyObject * +data_pread(PyObject *self, PyObject *args) +{ + unsigned long long offset; + unsigned int length; + permdb_object_py *state; + + if (!PyArg_ParseTuple(args, "O!KI", &permdb_type, &state, &offset, &length)) { + return NULL; + } + + unsigned char *result = read_internal_data(state->permdb, offset, length); + if (result == NULL) { + return NULL; + } + + PyObject* resultObj = PyString_FromStringAndSize((char *)result, length); + free(result); + return resultObj; +} + +static PyObject * +permdb_alloc_wrapper(PyObject *self, PyObject *args) +{ + const char *dbpath = NULL; + + if (!PyArg_ParseTuple(args, "s", &dbpath)) { + return NULL; + } + + return (PyObject*)permdb_alloc_py(dbpath); +} + +static PyObject * +readnode_wrapper(PyObject *self, PyObject *args) +{ + permdb_object_py *state; + unsigned long long offset; + const char *key = NULL; + + if (!PyArg_ParseTuple(args, "O!K|s", &permdb_type, &state, &offset, &key)) { + return NULL; + } + + return (PyObject *)node_alloc(readnode(state->permdb, offset, key)); +} + +static PyObject * +datasize_wrapper(PyObject *self, PyObject *args) +{ + permdb_object_py *state; + + if (!PyArg_ParseTuple(args, "O!", &permdb_type, &state)) { + return NULL; + } + + return PyInt_FromLong(datasize(state->permdb)); +} + +static PyObject * +addvalue_wrapper(PyObject *self, PyObject *args) +{ + permdb_object_py *state; + const char *key; + unsigned int keylength; + const char *data; + unsigned int datalength; + + if (!PyArg_ParseTuple(args, "O!s#s#", &permdb_type, &state, &key, &keylength, &data, &datalength)) { + return NULL; + } + + int result = addvalue(state->permdb, (unsigned char *) key, keylength, (unsigned char *) data, datalength); + + if (result < 0) { + return NULL; + } else if (result == 0) { + Py_INCREF(Py_False); + return Py_False; + } else { + Py_INCREF(Py_True); + return Py_True; + } +} + +static PyObject * +getvalue_wrapper(PyObject *self, PyObject *args) +{ + permdb_object_py *state; + + const char *key; + int keylen; + + if (!PyArg_ParseTuple(args, "O!s#", &permdb_type, &state, &key, &keylen)) { + return NULL; + } + + size_t datalen; + unsigned char *result = getvalue(state->permdb, (unsigned char *) key, keylen, &datalen); + + if (result == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* resultObj = PyString_FromStringAndSize((char *) result, datalen); + free(result); + return resultObj; +} + +static PyObject * +clear_nodecache(PyObject *self, PyObject *args) +{ + permdb_object_py *state; + + if (!PyArg_ParseTuple(args, "O!", &permdb_type, &state)) { + return NULL; + } + + delete_all_nodes_in_cache(state->permdb); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +committree_wrapper(PyObject *self, PyObject *args) +{ + permdb_object_py *state; + + fprintf(stderr, "starting commit\n"); + + if (!PyArg_ParseTuple(args, "O!", &permdb_type, &state)) { + return NULL; + } + + int result = committree(state->permdb); + + if (result < 0) { + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +} + +static PyMethodDef UtilMethods[] = { + {"data_pread", data_pread, METH_VARARGS}, + {"alloc", permdb_alloc_wrapper, METH_VARARGS}, + {"readnode", readnode_wrapper, METH_VARARGS}, + {"datasize", datasize_wrapper, METH_VARARGS}, + {"addvalue", addvalue_wrapper, METH_VARARGS}, + {"getvalue", getvalue_wrapper, METH_VARARGS}, + {"committree", committree_wrapper, METH_VARARGS}, + {"clear_nodecache", clear_nodecache, METH_VARARGS}, + {NULL, NULL} +}; + +void +initpermdb() +{ + (void) Py_InitModule("permdb", UtilMethods); +} |