Commit d1786bbf authored by Julien Muchembled's avatar Julien Muchembled

Release GIL while (de)compressing

parent aaa67d43
...@@ -9,7 +9,7 @@ cdef extern from "Python.h": ...@@ -9,7 +9,7 @@ cdef extern from "Python.h":
void Py_DECREF(PyObject *o) void Py_DECREF(PyObject *o)
PyObject *PyBytes_FromStringAndSize(char *v, Py_ssize_t len) except NULL PyObject *PyBytes_FromStringAndSize(char *v, Py_ssize_t len) except NULL
int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1 int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1
char *PyBytes_AS_STRING(PyObject *string) char *PyBytes_AS_STRING(PyObject *string) nogil
cdef extern from "zstd.h": cdef extern from "zstd.h":
# To simplify implementation, we use signed types (and detect errors with # To simplify implementation, we use signed types (and detect errors with
...@@ -20,9 +20,9 @@ cdef extern from "zstd.h": ...@@ -20,9 +20,9 @@ cdef extern from "zstd.h":
PY_LONG_LONG ZSTD_getFrameContentSize(const void *src, ssize_t srcSize) PY_LONG_LONG ZSTD_getFrameContentSize(const void *src, ssize_t srcSize)
ssize_t ZSTD_compress(void *dst, ssize_t dstCapacity, ssize_t ZSTD_compress(void *dst, ssize_t dstCapacity,
const void *src, ssize_t srcSize, const void *src, ssize_t srcSize,
int compressionLevel) int compressionLevel) nogil
ssize_t ZSTD_decompress(void *dst, ssize_t dstCapacity, ssize_t ZSTD_decompress(void *dst, ssize_t dstCapacity,
const void *src, ssize_t compressedSize) const void *src, ssize_t compressedSize) nogil
def maxCLevel(): def maxCLevel():
return ZSTD_maxCLevel() return ZSTD_maxCLevel()
...@@ -40,34 +40,39 @@ def getErrorName(code): ...@@ -40,34 +40,39 @@ def getErrorName(code):
# why can't I just cast to str ? # why can't I just cast to str ?
IF str is bytes: IF str is bytes:
return ZSTD_getErrorName(code) return ZSTD_getErrorName(code)
return ZSTD_getErrorName(code).decode() ELSE:
return ZSTD_getErrorName(code).decode()
error = None global error
def compress(bytes string not None, int level=0): def compress(bytes string not None, int level=0):
cdef: cdef:
int x
ssize_t srcSize = len(string) ssize_t srcSize = len(string)
ssize_t dstCapacity = ZSTD_compressBound(srcSize) ssize_t dstCapacity = ZSTD_compressBound(srcSize)
PyObject *dst = PyBytes_FromStringAndSize(NULL, dstCapacity) PyObject *dst = PyBytes_FromStringAndSize(NULL, dstCapacity)
int x = ZSTD_compress(PyBytes_AS_STRING(dst), dstCapacity, with nogil:
_PyBytes_AS_STRING(string), srcSize, x = ZSTD_compress(PyBytes_AS_STRING(dst), dstCapacity,
level) PyBytes_AS_STRING(<PyObject*>string), srcSize,
level)
if x < 0: if x < 0:
Py_DECREF(dst) Py_DECREF(dst)
raise error(-x) raise error(-x)
_PyBytes_Resize(&dst, x) _PyBytes_Resize(&dst, x)
r = <object>dst r = <object>dst
Py_DECREF(dst) # revert the unwanted incref on the previous line Py_DECREF(<PyObject*>r) # revert the unwanted incref on the previous line
return r return r
def decompress(bytes string not None): def decompress(bytes string not None):
cdef: cdef:
int x
ssize_t compressedSize = len(string) ssize_t compressedSize = len(string)
void *src = _PyBytes_AS_STRING(string) void *src = _PyBytes_AS_STRING(string)
PY_LONG_LONG dstCapacity = _getFrameContentSize(src, compressedSize) PY_LONG_LONG dstCapacity = _getFrameContentSize(src, compressedSize)
dst = _PyBytes_FromStringAndSize(NULL, dstCapacity) dst = _PyBytes_FromStringAndSize(NULL, dstCapacity)
cdef int x = ZSTD_decompress(_PyBytes_AS_STRING(dst), dstCapacity, with nogil:
src, compressedSize) x = ZSTD_decompress(PyBytes_AS_STRING(<PyObject*>dst), dstCapacity,
src, compressedSize)
if x < 0: if x < 0:
raise error(-x) raise error(-x)
return dst return dst
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment