experiments with Cython

This commit is contained in:
2025-11-28 15:40:09 +01:00
parent a7e9bc9bc1
commit 245b9532b9
4 changed files with 3469 additions and 1295 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,47 @@
"""placeholder module for compilation"""
import typing as t
from __future__ import annotations
import datetime
import cython
from cython.cimports.cpython.ref import Py_INCREF
import dopt_basics.datetime
# from cython.cimports.cpython.ref import Py_INCREF, PyObject
PyStringC = cython.struct(
ptr=cython.p_char,
length=cython.Py_ssize_t,
)
@cython.cfunc
def PyStringC_to_unicode(
string: PyStringC,
) -> str:
return string.ptr[: string.length].decode("UTF-8", "strict")
@cython.cfunc
def PyStringC_to_bytes(
string: PyStringC,
) -> bytes:
return cython.cast(bytes, string.ptr[: string.length])
@cython.cfunc
def timestamp_to_datetime(
ts: cython.double,
) -> datetime.datetime:
return datetime.datetime.fromtimestamp(ts, dopt_basics.datetime.TIMEZONE_UTC)
@cython.cclass
class StringHolder:
_data = cython.declare(cython.p_char, visibility="private")
_length = cython.declare(cython.Py_ssize_t, visibility="readonly")
_py_cache = cython.declare(object, visibility="private")
c = cython.declare(PyStringC, visibility="readonly")
_py_data = cython.declare(object, visibility="private")
def __cinit__(self, data: str) -> None:
def __cinit__(self, data: str):
"""accepting Python str
Parameters
@@ -23,23 +52,68 @@ class StringHolder:
if not isinstance(data, str):
raise TypeError("Data not 'str'")
tmp = data.encode("utf-8")
Py_INCREF(tmp)
self._data = tmp
self._length = len(tmp)
self._py_cache = None
@cython.cfunc
def _bytes_to_str(self) -> str:
tmp = t.cast(bytes, self._data[: self._length])
return tmp.decode("utf-8")
self._py_data = data.encode("UTF-8")
self.c = PyStringC(self._py_data, len(self._py_data))
@property
def py_string(self) -> str:
if self._py_cache is None:
self._py_cache = self._bytes_to_str()
return t.cast(str, self._py_cache)
def py_string(self):
return PyStringC_to_unicode(self.c)
@property
def py_bytes(self) -> bytes:
return t.cast(bytes, self._data[: self._length])
def py_bytes(self):
return PyStringC_to_bytes(self.c)
# BlockC = cython.struct(
# index=cython.ulonglong,
# timestamp=cython.double,
# data=PyStringC,
# previous_hash=PyStringC,
# nonce=cython.ulonglong,
# )
@cython.cclass
class Block:
_index = cython.declare(cython.ulong, visibility="private")
_timestamp = cython.declare(cython.double, visibility="private")
_data = cython.declare(StringHolder, visibility="private")
_prev_hash = cython.declare(StringHolder, visibility="private")
_nonce = cython.declare(cython.ulong, visibility="private")
def __init__(
self,
index: int,
data: str,
previous_hash: str,
nonce: int,
):
self._index = index
self._timestamp = dopt_basics.datetime.current_time_tz().timestamp()
self._data = StringHolder.__new__(StringHolder, data)
self._prev_hash = StringHolder.__new__(StringHolder, previous_hash)
self._nonce = nonce
@property
def index(self):
return self._index
@property
def timestamp(self):
return timestamp_to_datetime(self._timestamp)
@property
def data(self):
return self._data.py_string
@property
def prev_hash(self):
return self._prev_hash.py_string
@property
def nonce(self):
return self._nonce
@nonce.setter
def nonce(self, value: int):
self._nonce = value