From 00b0956cb80ced3149f4443439c9fb63394089f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Tue, 6 Jul 2021 14:00:33 +0200
Subject: [PATCH] added `MemoryPressureManager` support for `Database`

---
 README.md            |  1 +
 setup.cfg            |  2 +-
 tempsdb/database.pxd |  3 ++-
 tempsdb/database.pyx | 23 +++++++++++++++++++++++
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index b70034e..c6624ea 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.
 * added the context manager syntax to VarlenIterator
 * fixed a memory leak that happened during getting current value
     from an empty series
+* added `MemoryPressureManager` support for `Database`
 
 ## v0.6.1
 
diff --git a/setup.cfg b/setup.cfg
index 3e4aa7c..3e4676b 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
 # coding: utf-8
 [metadata]
 name = tempsdb
-version = 0.6.2a3
+version = 0.6.2a4
 long-description = file: README.md
 long-description-content-type = text/markdown; charset=UTF-8
 license_files = LICENSE
diff --git a/tempsdb/database.pxd b/tempsdb/database.pxd
index 03b94be..24594a7 100644
--- a/tempsdb/database.pxd
+++ b/tempsdb/database.pxd
@@ -6,11 +6,12 @@ cdef class Database:
         readonly str path
         bint closed
         object lock
-        object mpm
+        object mpm, mpm_handler
         dict open_series
         dict open_varlen_series
         readonly dict metadata
 
+    cpdef int checkpoint(self) except -1
     cpdef int reload_metadata(self) except -1
     cpdef int set_metadata(self, dict meta) except -1
     cpdef int close(self) except -1
diff --git a/tempsdb/database.pyx b/tempsdb/database.pyx
index 8bd7c3b..7391449 100644
--- a/tempsdb/database.pyx
+++ b/tempsdb/database.pyx
@@ -38,6 +38,7 @@ cdef class Database:
         self.open_varlen_series = {}
         self.lock = threading.RLock()
         self.mpm = None
+        self.mpm_handler = None
         self.metadata = {}
         self.reload_metadata()
 
@@ -89,6 +90,24 @@ cdef class Database:
                         output.append(v_series)
         return output
 
+    cpdef int checkpoint(self) except -1:
+        """
+        Destroy closed series
+        """
+        cdef:
+            TimeSeries series
+            VarlenSeries v_series
+        with self.lock:
+            with DictDeleter(self.open_series) as dd:
+                for series in dd.values():
+                    if series.closed:
+                        dd.delete()
+            with DictDeleter(self.open_varlen_series) as dd:
+                for v_series in dd.values():
+                    if v_series.closed:
+                        dd.delete()
+        return 0
+
     cpdef int delete_series(self, str name) except -1:
         """
         Deletes a constant-length time series.
@@ -353,6 +372,7 @@ cdef class Database:
         cdef TimeSeries series
         for series in self.open_series.values():
             series.register_memory_pressure_manager(mpm)    # no-op if already closed
+        self.mpm_handler = mpm.register_on_entered_severity(1)(self.checkpoint)
         return 0
 
     def __del__(self):
@@ -378,6 +398,9 @@ cdef class Database:
                 var_series.close(True)
             self.open_varlen_series = {}
         self.closed = True
+        if self.mpm_handler is not None:
+            self.mpm_handler.cancel()
+            self.mpm_handler = None
         return 0
 
 
-- 
GitLab