summaryrefslogtreecommitdiff
path: root/jq.pyx
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2020-06-22 22:28:27 +0100
committerMichael Williamson <mike@zwobble.org>2020-06-22 22:28:27 +0100
commit8fb7d79e698ac6d79ed5222f53add761f7212439 (patch)
tree655dae0c05376b4d865b169ad225b9395384a5b6 /jq.pyx
parent1261d9b40376ae3090477987ea493ac508f3c75f (diff)
Use pool for jq_state
Diffstat (limited to 'jq.pyx')
-rw-r--r--jq.pyx50
1 files changed, 39 insertions, 11 deletions
diff --git a/jq.pyx b/jq.pyx
index 38f3893..1846cfd 100644
--- a/jq.pyx
+++ b/jq.pyx
@@ -52,9 +52,6 @@ cdef extern from "jq.h":
def compile(object program):
cdef object program_bytes = program.encode("utf8")
- cdef jq_state* state = _compile(program_bytes)
- jq_teardown(&state)
-
return _Program(program_bytes)
@@ -118,18 +115,47 @@ class _EmptyValue(object):
_NO_VALUE = _EmptyValue()
+
+cdef class _JqStatePool(object):
+ cdef jq_state* _jq_state
+ cdef object _program_bytes
+
+ def __cinit__(self, program_bytes):
+ self._program_bytes = program_bytes
+ self._jq_state = _compile(self._program_bytes)
+
+ def __dealloc__(self):
+ jq_teardown(&self._jq_state)
+
+ cdef jq_state* acquire(self):
+ if self._jq_state == NULL:
+ return _compile(self._program_bytes)
+ else:
+ state = self._jq_state
+ self._jq_state = NULL
+ return state
+
+ cdef void release(self, jq_state* state):
+ if self._jq_state == NULL:
+ self._jq_state = state
+ else:
+ jq_teardown(&state)
+
+
cdef class _Program(object):
cdef object _program_bytes
+ cdef _JqStatePool _jq_state_pool
def __cinit__(self, program_bytes):
self._program_bytes = program_bytes
+ self._jq_state_pool = _JqStatePool(program_bytes)
def input(self, value=_NO_VALUE, text=_NO_VALUE):
if (value is _NO_VALUE) == (text is _NO_VALUE):
raise ValueError("Either the value or text argument should be set")
string_input = text if text is not _NO_VALUE else json.dumps(value)
- return _ProgramWithInput(self._program_bytes, string_input.encode("utf8"))
+ return _ProgramWithInput(self._jq_state_pool, string_input.encode("utf8"))
@property
def program_string(self):
@@ -150,18 +176,18 @@ cdef class _Program(object):
cdef class _ProgramWithInput(object):
- cdef object _program_bytes
+ cdef _JqStatePool _jq_state_pool
cdef object _bytes_input
- def __cinit__(self, program_bytes, bytes_input):
- self._program_bytes = program_bytes
+ def __cinit__(self, jq_state_pool, bytes_input):
+ self._jq_state_pool = jq_state_pool
self._bytes_input = bytes_input
def __iter__(self):
return self._make_iterator()
cdef _ResultIterator _make_iterator(self):
- return _ResultIterator(self._program_bytes, self._bytes_input)
+ return _ResultIterator(self._jq_state_pool, self._bytes_input)
def text(self):
iterator = self._make_iterator()
@@ -180,17 +206,19 @@ cdef class _ProgramWithInput(object):
cdef class _ResultIterator(object):
+ cdef _JqStatePool _jq_state_pool
cdef jq_state* _jq
cdef jv_parser* _parser
cdef object _bytes_input
cdef bint _ready
def __dealloc__(self):
- jq_teardown(&self._jq)
+ self._jq_state_pool.release(self._jq)
jv_parser_free(self._parser)
- def __cinit__(self, object program_bytes, object bytes_input):
- self._jq = _compile(program_bytes)
+ def __cinit__(self, _JqStatePool jq_state_pool, object bytes_input):
+ self._jq_state_pool = jq_state_pool
+ self._jq = jq_state_pool.acquire()
self._bytes_input = bytes_input
self._ready = False
cdef jv_parser* parser = jv_parser_new(0)