[pypy-commit] pypy default: sqlite: clear cursor weakrefs periodically like statement weakrefs

bdkearns noreply at buildbot.pypy.org
Sun Mar 17 04:59:22 CET 2013


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r62379:061b9919d6c7
Date: 2013-03-16 23:29 -0400
http://bitbucket.org/pypy/pypy/changeset/061b9919d6c7/

Log:	sqlite: clear cursor weakrefs periodically like statement weakrefs

diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -364,9 +364,10 @@
         self._in_transaction = False
         self.isolation_level = isolation_level
 
-        self._cursors = []
+        self.__cursors = []
+        self.__cursors_counter = 0
         self.__statements = []
-        self.__statement_counter = 0
+        self.__statements_counter = 0
         self._statement_cache = _StatementCache(self, cached_statements)
 
         self.__func_cache = {}
@@ -466,13 +467,21 @@
         exc.error_code = error_code
         return exc
 
+    def _remember_cursor(self, cursor):
+        self.__cursors.append(weakref.ref(cursor))
+        self.__cursors_counter += 1
+        if self.__cursors_counter < 200:
+            return
+        self.__cursors_counter = 0
+        self.__cursors = [r for r in self.__cursors if r() is not None]
+
     def _remember_statement(self, statement):
         self.__statements.append(weakref.ref(statement))
-        self.__statement_counter += 1
-
-        if self.__statement_counter % 100 == 0:
-            self.__statements = [ref for ref in self.__statements
-                                 if ref() is not None]
+        self.__statements_counter += 1
+        if self.__statements_counter < 200:
+            return
+        self.__statements_counter = 0
+        self.__statements = [r for r in self.__statements if r() is not None]
 
     def __do_all_statements(self, action, reset_cursors):
         for weakref in self.__statements:
@@ -481,7 +490,7 @@
                 action(statement)
 
         if reset_cursors:
-            for weakref in self._cursors:
+            for weakref in self.__cursors:
                 cursor = weakref()
                 if cursor is not None:
                     cursor._reset = True
@@ -785,14 +794,9 @@
     __statement = None
 
     def __init__(self, con):
-        self.__initialized = True
-        self.__connection = con
-
         if not isinstance(con, Connection):
             raise TypeError
-        con._check_thread()
-        con._check_closed()
-        con._cursors.append(weakref.ref(self))
+        self.__connection = con
 
         self.arraysize = 1
         self.row_factory = None
@@ -802,11 +806,12 @@
         self.__description = None
         self.__rowcount = -1
 
+        con._check_thread()
+        con._remember_cursor(self)
+
+        self.__initialized = True
+
     def __del__(self):
-        try:
-            self.__connection._cursors.remove(weakref.ref(self))
-        except (AttributeError, ValueError):
-            pass
         if self.__statement:
             self.__statement._reset()
 
@@ -998,6 +1003,7 @@
 
     def __init__(self, connection, sql):
         self.__con = connection
+        self.__con._remember_statement(self)
 
         if not isinstance(sql, basestring):
             raise Warning("SQL is of wrong type. Must be string or unicode.")
@@ -1025,10 +1031,9 @@
             ret = _lib.sqlite3_prepare_v2(self.__con._db, sql, -1,
                                           byref(self._statement), byref(sql))
             self._kind = Statement._DQL
-
         if ret != _lib.SQLITE_OK:
             raise self.__con._get_exception(ret)
-        self.__con._remember_statement(self)
+
         sql = sql.value.decode('utf-8')
         if _check_remaining_sql(sql):
             raise Warning("You can only execute one statement at a time.")


More information about the pypy-commit mailing list