diff --git a/README.md b/README.md index 66cb2560173481a7d50df800aeebebeab9864a94..9133982334efc6ec02515bbca95f07841b65b035 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Then copy your resulting wheel and install it via pip on the target system. ## v0.4.5 * if page_size is default, it won't be written as part of the metadata +* added support for per-series metadata ## v0.4.4 diff --git a/setup.py b/setup.py index dc3677ac408d44b19a95918e6264afb90ecb85be..73b48e04f19a2131ac8df7b4320751f8afac662f 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ if 'CI' in os.environ: setup(name='tempsdb', - version='0.4.5a2', + version='0.4.5a3', packages=['tempsdb'], install_requires=['satella>=2.14.24', 'ujson'], ext_modules=build([Multibuild('tempsdb', find_pyx('tempsdb')), ], diff --git a/tempsdb/series.pxd b/tempsdb/series.pxd index 15335fd3f0282647d763ff52fba385217c947827..7f12446814347b783d4a04f2e09ffdf719740363 100644 --- a/tempsdb/series.pxd +++ b/tempsdb/series.pxd @@ -14,6 +14,7 @@ cdef class TimeSeries: readonly unsigned int block_size readonly unsigned long long last_entry_ts unsigned int page_size + readonly dict metadata readonly bint descriptor_based_access list chunks dict refs_chunks # type: tp.Dict[int, int] @@ -40,6 +41,7 @@ cdef class TimeSeries: cpdef tuple get_current_value(self) cpdef int disable_mmap(self) except -1 cpdef int enable_mmap(self) except -1 + cpdef int set_metadata(self, dict new_meta) except -1 cdef inline int get_references_for(self, unsigned long long timestamp): return self.refs_chunks.get(timestamp, 0) diff --git a/tempsdb/series.pyx b/tempsdb/series.pyx index a3fdbd48e298541673ce81a34383f3c868af7a19..98bc8a99411534c61493a787d681be6cb7ff9c53 100644 --- a/tempsdb/series.pyx +++ b/tempsdb/series.pyx @@ -1,3 +1,4 @@ +import typing as tp import shutil import threading from satella.json import write_json_to_file, read_json_from_file @@ -20,6 +21,7 @@ cdef class TimeSeries: :ivar path: path to the directory containing the series (str) :ivar descriptor_based_access: are all chunks using descriptor-based access? (bool) :ivar name: name of the series (str) + :ivar metadata: extra data (tp.Optional[dict]) """ cpdef tuple get_current_value(self): """ @@ -51,6 +53,18 @@ cdef class TimeSeries: chunk.switch_to_descriptor_based_access() return 0 + cpdef int set_metadata(self, dict new_meta) except -1: + """ + Set a new value for the :attr:`~tempsdb.series.TimeSeries.metadata` property. + + This writes the disk. + + :param new_meta: new value of metadata property + """ + self.metadata = new_meta + self.sync_metadata() + return 0 + cpdef int enable_mmap(self) except -1: """ Switches to mmap-based file access method for the entire series, @@ -94,6 +108,7 @@ cdef class TimeSeries: self.max_entries_per_chunk = metadata['max_entries_per_chunk'] self.last_entry_synced = metadata['last_entry_synced'] self.page_size = metadata.get('page_size', DEFAULT_PAGE_SIZE) + self.metadata = metadata.get('metadata') except (OSError, ValueError) as e: raise Corruption('Corrupted series: %s' % (e, )) except KeyError: @@ -315,6 +330,8 @@ cdef class TimeSeries: } if self.page_size != DEFAULT_PAGE_SIZE: meta['page_size'] = self.page_size + if self.metadata is not None: + meta['metadata'] = self.metadata return meta cdef void register_memory_pressure_manager(self, object mpm):