-
Notifications
You must be signed in to change notification settings - Fork 0
/
pykv.c
137 lines (115 loc) · 3.62 KB
/
pykv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#define PY_SSIZE_T_CLEAN
#define NPY_NO_DEPRECATED_API NPY_1_14_API_VERSION
#include <Python.h>
#include <stdint.h>
#include <stdio.h>
#include "kv.h"
static PyObject *PyKVError;
static PyTypeObject PyKVType = { PyVarObject_HEAD_INIT(NULL, 0)
"pykv.KV"
};
typedef struct {
PyObject_HEAD
struct kv kv;
} PyKV;
static PyObject *PyKV_insert(PyKV *self, PyObject * args) {
uint64_t key;
const char *value;
Py_ssize_t size;
if (!PyArg_ParseTuple(args, "ks#", &key, &value, &size)) {
PyErr_SetString(PyKVError, "failed to parse tuple");
return NULL;
}
kv_insert(&self->kv, key, (const uint8_t *) value, size);
Py_RETURN_NONE;
}
static PyObject *PyKV_flush(PyKV *self, PyObject * args) {
kv_flush(&self->kv);
Py_RETURN_NONE;
}
static PyObject *PyKV_find(PyKV *self, PyObject * args) {
uint64_t key;
if (!PyArg_ParseTuple(args, "k", &key)) {
PyErr_SetString(PyKVError, "failed to parse tuple");
return NULL;
}
uint8_t *ptr;
size_t size;
kv_find(&self->kv, &ptr, &size, key);
PyObject *ret = PyBytes_FromStringAndSize((char *) ptr, size);
return ret;
}
static PyMethodDef PyKVMethods[] = {
{ NULL, NULL, 0, NULL }
};
static struct PyModuleDef pykvmodule = {
PyModuleDef_HEAD_INIT,
"pykv", /* name of module */
NULL, /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
PyKVMethods
};
static PyObject *PyKV_open(PyKV *self, PyObject *args) {
char *kvinfo;
int delete_on_close;
if (!PyArg_ParseTuple(args, "sp", &kvinfo, &delete_on_close)) {
PyErr_SetString(PyKVError, "wrong open args");
return NULL;
}
if (kv_init(&self->kv, kvinfo, delete_on_close) < 0) {
PyErr_SetString(PyKVError, "failed to init pykv");
return NULL;
}
Py_RETURN_NONE;
}
static PyObject *PyKV_save(PyKV * self, PyObject * args) {
if (!PyArg_ParseTuple(args, "")) {
PyErr_SetString(PyKVError, "wrong save args");
return NULL;
}
char saved[1024];
if (kv_save(&self->kv, saved, sizeof(saved)) < 0) {
PyErr_SetString(PyKVError, "failed to save pykv");
return NULL;
}
return Py_BuildValue("s", saved);
}
static PyMethodDef PyKV_methods[] = {
{ "open", (PyCFunction) PyKV_open, METH_VARARGS, "open"},
{ "save", (PyCFunction) PyKV_save, METH_VARARGS, "save"},
{ "insert", (PyCFunction) PyKV_insert, METH_VARARGS, "Insert key and value" },
{ "find", (PyCFunction) PyKV_find, METH_VARARGS, "Find key" },
{ "flush", (PyCFunction) PyKV_flush, METH_VARARGS, "Flush inserts" },
{NULL} /* Sentinel */
};
static int PyKV_typeinit(PyKV *self, PyObject *args, PyObject *kwds) {
return 0;
}
static void PyKV_dealloc(PyKV* self) {
kv_close(&self->kv);
Py_TYPE(self)->tp_free(self);
}
PyMODINIT_FUNC PyInit_pykv(void) {
kv_global_init();
PyObject *m = PyModule_Create(&pykvmodule);
if (!m) {
return NULL;
}
PyKVError = PyErr_NewException("pykv.error", NULL, NULL);
Py_INCREF(PyKVError);
PyModule_AddObject(m, "error", PyKVError);
PyKVType.tp_new = PyType_GenericNew;
PyKVType.tp_basicsize = sizeof(PyKV);
PyKVType.tp_dealloc = (destructor) PyKV_dealloc;
PyKVType.tp_flags = Py_TPFLAGS_DEFAULT;
PyKVType.tp_doc = "KV object";
PyKVType.tp_methods = PyKV_methods;
PyKVType.tp_init= (initproc) PyKV_typeinit;
if (PyType_Ready(&PyKVType) < 0) {
return NULL;
}
Py_INCREF(&PyKVType);
PyModule_AddObject(m, "KV", (PyObject *)&PyKVType);
return m;
}