diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2023-04-25 13:57:27 -0400 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2023-04-25 13:57:27 -0400 |
| commit | c5002a58ffb4b3d25941e146dfb3ce6d4391c1de (patch) | |
| tree | c8df05bc080739b685b9316d4a713ddf138c507a | |
| parent | 94a225203e36b0d9da5b39daab765d465bed76f1 (diff) | |
| download | pyisda-c5002a58ffb4b3d25941e146dfb3ce6d4391c1de.tar.gz | |
add new packed format
| -rw-r--r-- | pyisda/curve.pxd | 5 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 47 |
2 files changed, 40 insertions, 12 deletions
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 8fb6733..d0d85f6 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -206,15 +206,12 @@ cdef extern from "survival_curve.hpp" nogil: string full_ticker() size_t size() -cdef inline const TCurve* get_TCurve(Curve c) nogil: - return <TCurve*>c.buf.get() - cdef class Curve: cdef shared_ptr[char] buf cdef readonly size_t buf_size cdef inline const TCurve* get_TCurve(self) nogil - cpdef bytes as_bytes(self, bint compressed) + cpdef bytes as_bytes(self, int fmt) cdef class YieldCurve(Curve): pass diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 90df782..6dc66f1 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -1,5 +1,6 @@ from cython.operator import dereference as deref, preincrement as preinc +from cpython.bytes cimport PyBytes_FromStringAndSize, PyBytes_AS_STRING from libc.math cimport log1p, log, exp, isnan from libc.string cimport strcpy, strncpy, strlen from .date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc, @@ -69,21 +70,40 @@ cdef class Curve(object): cdef inline const TCurve* get_TCurve(self) nogil: return <TCurve*>self.buf.get() - cpdef bytes as_bytes(self, bint compressed): + cpdef bytes as_bytes(self, int fmt): + """ 0 uncompressed + 1 lz4 compressed + 2 packed + """ + cdef: bytes r - int dst_capacity, compressed_size + int dst_capacity, compressed_size, i char* dst + char* src int size = self.buf_size + int packed_size + const TCurve* curve = self.get_TCurve() - if compressed: + if fmt == 1: dst_capacity = LZ4_compressBound(size) dst = <char*>malloc(dst_capacity) compressed_size = LZ4_compress_default(self.buf.get(), dst, size, dst_capacity) r = dst[:compressed_size] free(dst) - else: + elif fmt == 0: r = self.buf.get()[:self.buf_size] + elif fmt == 2: + packed_size = sizeof(TCurve) + curve.fNumItems * (sizeof(double) + sizeof(short)) + r = PyBytes_FromStringAndSize(NULL, packed_size) + dst = PyBytes_AS_STRING(r) + src = <char*>curve + memcpy(dst, src, sizeof(TCurve)) + src += sizeof(TCurve) + dst += sizeof(TCurve) + for i in range(curve.fNumItems): + (<short*>dst)[i] = (<TRatePt*>src)[i].fDate - curve.fBaseDate + (<double*>(dst + curve.fNumItems * sizeof(short)))[i] = (<TRatePt*>src)[i].fRate return r def __getstate__(self): @@ -116,7 +136,7 @@ cdef class Curve(object): self.buf.reset(curve, char_free) @classmethod - def from_bytes(cls, object state, bint compressed=True): + def from_bytes(cls, object state, int fmt=1): cdef: Curve instance = cls.__new__(cls) Py_buffer* py_buf @@ -126,7 +146,7 @@ cdef class Curve(object): int decomp_size = 512 int retry = 0 TDate base_date - double basis + size_t i, n if PyMemoryView_Check(state): py_buf = PyMemoryView_GET_BUFFER(state) @@ -137,7 +157,7 @@ cdef class Curve(object): size = PyBytes_GET_SIZE(state) with nogil: - if compressed: + if fmt == 1: while True: curve = <char*>realloc(curve, decomp_size) state_size = LZ4_decompress_safe(src, curve, size, decomp_size) @@ -150,10 +170,21 @@ cdef class Curve(object): decomp_size *= 2 else: break - else: + elif fmt == 0: curve = <char*>malloc(size) memcpy(curve, src, size) state_size = size + elif fmt == 2: + n = (<TCurve*>src).fNumItems + state_size = sizeof(TCurve) + n * (sizeof(TDate) + sizeof(double)) + curve = <char*>malloc(state_size) + memcpy(curve, src, sizeof(TCurve)) + base_date = (<TCurve*>src).fBaseDate + curve += sizeof(TCurve) + src += sizeof(TCurve) + for i in range(n): + (<TRatePt*>curve)[i] = TRatePt(base_date + (<short*>src)[i], (<double*>(src + n * sizeof(short)))[i]) + curve -= sizeof(TCurve) instance.buf_size = state_size instance.buf.reset(curve, char_free) return instance |
