Bug 834449 - Part 2: clean up cached statements in Sqlite.jsm. r=gps
authorRichard Newman <rnewman@mozilla.com>
Fri, 25 Jan 2013 00:38:59 -0800
changeset 129850 dce840cda6b8c16c8698f99de4883b2edbddcf2c
parent 129849 0f28b10053de6f87ee40a4aead2af75105b27b4e
child 129851 8efd1355f4acd9c646e3b7d853dd90e7fd8cef85
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs834449
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 834449 - Part 2: clean up cached statements in Sqlite.jsm. r=gps
toolkit/modules/Sqlite.jsm
toolkit/modules/tests/xpcshell/test_sqlite.js
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -726,16 +726,36 @@ OpenedConnection.prototype = Object.free
   shrinkMemory: function () {
     this._log.info("Shrinking memory usage.");
 
     let onShrunk = this._clearIdleShrinkTimer.bind(this);
 
     return this.execute("PRAGMA shrink_memory").then(onShrunk, onShrunk);
   },
 
+  /**
+   * Discard all inactive cached statements.
+   *
+   * @return (integer) the number of statements discarded.
+   */
+  discardCachedStatements: function () {
+    let count = 0;
+    for (let [k, statement] of this._cachedStatements) {
+      if (this.inProgress(statement)) {
+        continue;
+      }
+
+      ++count;
+      this._cachedStatements.delete(k);
+      statement.finalize();
+    }
+    this._log.debug("Discarded " + count + " cached statements.");
+    return count;
+  },
+
   _executeStatement: function (sql, statement, params, onRow) {
     if (statement.state != statement.MOZ_STORAGE_STATEMENT_READY) {
       throw new Error("Statement is not ready for execution.");
     }
 
     if (onRow && typeof(onRow) != "function") {
       throw new Error("onRow must be a function. Got: " + onRow);
     }
--- a/toolkit/modules/tests/xpcshell/test_sqlite.js
+++ b/toolkit/modules/tests/xpcshell/test_sqlite.js
@@ -523,8 +523,55 @@ add_task(function test_in_progress_count
   do_check_eq(expectOne, 1);
   do_check_eq(expectTwo, 2);
   do_check_eq(c._statementCounter, c._initialStatementCount + 3);
   do_check_eq(c.inProgress(), 0);
 
   yield c.close();
 });
 
+add_task(function test_discard_while_active() {
+  let c = yield getDummyDatabase("discard_while_active");
+
+  yield c.executeCached("INSERT INTO dirs (path) VALUES ('foo')");
+  yield c.executeCached("INSERT INTO dirs (path) VALUES ('bar')");
+
+  let discarded = -1;
+  let first = true;
+  let sql = "SELECT * FROM dirs";
+  yield c.executeCached(sql, null, function onRow(row) {
+    if (!first) {
+      return;
+    }
+    first = false;
+    discarded = c.discardCachedStatements();
+  });
+
+  // We didn't discard the SELECT, only the two INSERTs.
+  do_check_eq(2, discarded);
+
+  // But we got the remainder when it became inactive.
+  do_check_eq(1, c.discardCachedStatements());
+
+  // And again is safe.
+  do_check_eq(0, c.discardCachedStatements());
+
+  yield c.close();
+});
+
+add_task(function test_discard_cached() {
+  let c = yield getDummyDatabase("discard_cached");
+
+  yield c.executeCached("SELECT * from dirs");
+  do_check_eq(1, c._cachedStatements.size);
+
+  yield c.executeCached("SELECT * from files");
+  do_check_eq(2, c._cachedStatements.size);
+
+  yield c.executeCached("SELECT * from dirs");
+  do_check_eq(2, c._cachedStatements.size);
+
+  c.discardCachedStatements();
+  do_check_eq(0, c._cachedStatements.size);
+
+  yield c.close();
+});
+