[Zodb-checkins] CVS: StandaloneZODB/bsddb3Storage/bsddb3Storage - _helper.c:1.2

Barry Warsaw barry@wooz.org
Fri, 23 Aug 2002 13:14:49 -0400


Update of /cvs-repository/StandaloneZODB/bsddb3Storage/bsddb3Storage
In directory cvs.zope.org:/tmp/cvs-serv1559/bsddb3Storage

Added Files:
	_helper.c 
Log Message:
A simple extension module which can actually improve performance by
doing a critical operation in C.  When fiddling the reference counting
we often need to

    1. unpack a 64bit string into a long
    2. add a delta value to the long
    3. pack the long into a 64bit string

_helper.incr() does these three steps in C.

This extension only works for Python 2.2, but Full.py has a Python
replacement for use with Python 2.1.


=== StandaloneZODB/bsddb3Storage/bsddb3Storage/_helper.c 1.1 => 1.2 ===
--- /dev/null	Fri Aug 23 13:14:49 2002
+++ StandaloneZODB/bsddb3Storage/bsddb3Storage/_helper.c	Fri Aug 23 13:14:49 2002
@@ -0,0 +1,56 @@
+#include <Python.h>
+
+/* This helper only works for Python 2.2.  If using an older version, crap
+ * out now so we don't leave a broken, but compiled and importable module
+ * laying about.
+ */
+#if PY_VERSION_HEX < 0x020200F0
+#error "Must be using at least Python 2.2"
+#endif
+
+static PyObject*
+helper_incr(PyObject* self, PyObject* args)
+{
+    PyObject *pylong, *incr, *sum;
+    char *s, x[8];
+    int len, res;
+
+    if (!PyArg_ParseTuple(args, "s#O:incr", &s, &len, &incr))
+        return NULL;
+
+    assert(len == 8);
+
+    /* there seems to be no direct route from byte array to long long, so
+     * first convert it to a PyLongObject*, then convert /that/ thing to a
+     * long long
+     */
+    pylong = _PyLong_FromByteArray(s, len,
+                                   0 /* big endian */, 0 /* unsigned */);
+    
+    if (!pylong)
+        return NULL;
+
+    sum = PyNumber_Add(pylong, incr);
+    if (!sum)
+        return NULL;
+
+    res = _PyLong_AsByteArray((PyLongObject*)sum, x, 8,
+                              0 /* big endian */, 0 /* unsigned */);
+    if (res < 0)
+        return NULL;
+
+    return PyString_FromStringAndSize(x, 8);
+}
+
+
+static PyMethodDef helper_methods[] = {
+    {"incr", helper_incr, METH_VARARGS},
+    {NULL, NULL}                             /* sentinel */
+};
+
+
+DL_EXPORT(void)
+init_helper(void)
+{
+    (void)Py_InitModule("_helper", helper_methods);
+}