diff --git a/README.md b/README.md index dd6ceaa92237f03acfa7e6af5a941408d115b854..3d4fea690ee1cd9b4e9f51f2610be2a3b7b75ad5 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ You will need to have both snakehouse and satella installed. * more error conditions during mmap will be supported as well * ENOMEM will be correctly handled during resize operation * added `TimeSeries.descriptor_based_access` +* added `Chunk.switch_to_mmap_based_access` ## v0.4.3 diff --git a/setup.py b/setup.py index f1b34b39bd0e9bc02e4dfbb7ec767ba91100f2e1..3eedbb369295f24c271ed338c3b8c08ee399c799 100644 --- a/setup.py +++ b/setup.py @@ -28,9 +28,9 @@ if 'CI' in os.environ: setup(name='tempsdb', - version='0.4.4a4', + version='0.4.4', packages=['tempsdb'], - install_requires=['satella>=2.14.23', 'ujson'], + install_requires=['satella>=2.14.24', 'ujson'], ext_modules=build([Multibuild('tempsdb', find_pyx('tempsdb')), ], compiler_directives=directives), # ext_modules=cythonize(extensions, diff --git a/tempsdb/chunks.pxd b/tempsdb/chunks.pxd index 10d2ba8b17517b157f0893b97fe526ffe2dbcecb..6db8a1096cd984cf1ea97e5cd95243391ca8c332 100644 --- a/tempsdb/chunks.pxd +++ b/tempsdb/chunks.pxd @@ -32,6 +32,7 @@ cdef class Chunk: cdef int extend(self) except -1 cpdef int delete(self) except -1 cpdef int switch_to_descriptor_based_access(self) except -1 + cpdef int switch_to_mmap_based_access(self) except -1 cpdef unsigned long get_mmap_size(self) cdef inline unsigned long long name(self): diff --git a/tempsdb/chunks.pyx b/tempsdb/chunks.pyx index d03d898dcad34a94b59bbc54d5a16b038d39033f..360da4f38144a57506eb041ac00ca3cbbacef282 100644 --- a/tempsdb/chunks.pyx +++ b/tempsdb/chunks.pyx @@ -86,6 +86,28 @@ cdef class Chunk: else: return self.file_size + cpdef int switch_to_mmap_based_access(self) except -1: + """ + Switch self to mmap-based access instead of descriptor-based. + + No-op if already in mmap mode. + """ + if not isinstance(self.mmap, AlternativeMMap): + return 0 + try: + self.mmap = mmap.mmap(self.file.fileno(), 0) + self.file_lock_object = None + except OSError as e: + if e.errno in (11, # EAGAIN - memory is too low + 12, # ENOMEM - no memory space available + 19, # ENODEV - fs does not support mmapping + 75): # EOVERFLOW - too many pages would have been used + pass + else: + self.file.close() + self.closed = True + raise Corruption(f'Failed to mmap chunk file: {e}') + cpdef int switch_to_descriptor_based_access(self) except -1: """ Switch self to descriptor-based access instead of mmap. diff --git a/tempsdb/series.pxd b/tempsdb/series.pxd index d6f32b309c7978ac6fcc23274c4dbbe2ea0c3503..15335fd3f0282647d763ff52fba385217c947827 100644 --- a/tempsdb/series.pxd +++ b/tempsdb/series.pxd @@ -39,6 +39,7 @@ cdef class TimeSeries: cpdef unsigned long open_chunks_mmap_size(self) cpdef tuple get_current_value(self) cpdef int disable_mmap(self) except -1 + cpdef int enable_mmap(self) except -1 cdef inline int get_references_for(self, unsigned long long timestamp): return self.refs_chunks.get(timestamp, 0)