[geary] Improve database parallelization
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Improve database parallelization
- Date: Thu, 12 Jun 2014 00:52:57 +0000 (UTC)
commit 8dec339f2ec05bf717b81ed46eaa483899d33851
Author: Jim Nelson <jim yorba org>
Date: Wed Jun 11 17:05:54 2014 -0700
Improve database parallelization
Prior attempts to use multiple threads to access the SQLite database
failed due to locking reasons. This re-attempt fixes this, alloc'ing
four threads per database and slightly changing the locking strategy
for read-write transactions.
Part of the prior issues may have been an attempt to use a connection
pool (this patch simply opens a new connection for each transaction,
which for our purposes seems fine). The read-write strategy of
deferring locking until the write portion of the transaction was also
too optimistic, causing transactions to stall in the middle of their
operations.
src/engine/db/db-database.vala | 33 +++++++-----------------------
src/engine/db/db-transaction-type.vala | 2 +-
src/engine/imap-db/imap-db-account.vala | 2 +-
3 files changed, 10 insertions(+), 27 deletions(-)
---
diff --git a/src/engine/db/db-database.vala b/src/engine/db/db-database.vala
index 2ecfcfb..ba0beaa 100644
--- a/src/engine/db/db-database.vala
+++ b/src/engine/db/db-database.vala
@@ -17,9 +17,7 @@
*/
public class Geary.Db.Database : Geary.Db.Context {
- // Dealing with BUSY signal is a bear, and so for now concurrency is turned off
- // http://redmine.yorba.org/issues/6460
- public const int DEFAULT_MAX_CONCURRENCY = 1;
+ public const int DEFAULT_MAX_CONCURRENCY = 4;
public File db_file { get; private set; }
public DatabaseFlags flags { get; private set; }
@@ -42,7 +40,6 @@ public class Geary.Db.Database : Geary.Db.Context {
private Connection? master_connection = null;
private int outstanding_async_jobs = 0;
private ThreadPool<TransactionAsyncJob>? thread_pool = null;
- private Gee.LinkedList<Connection>? cx_pool = null;
private unowned PrepareConnection? prepare_cb = null;
public Database(File db_file) {
@@ -83,9 +80,6 @@ public class Geary.Db.Database : Geary.Db.Context {
thread_pool = new ThreadPool<TransactionAsyncJob>.with_owned_data(on_async_job,
DEFAULT_MAX_CONCURRENCY, true);
}
-
- if (cx_pool == null)
- cx_pool = new Gee.LinkedList<Connection>();
} else {
warning("SQLite not thread-safe: asynchronous queries will not be available");
}
@@ -274,22 +268,15 @@ public class Geary.Db.Database : Geary.Db.Context {
// This method must be thread-safe.
private void on_async_job(owned TransactionAsyncJob job) {
- // go to connection pool before creating a connection -- *never* use master connection for
- // threaded operations
+ // *never* use master connection for threaded operations
Connection? cx = null;
- lock (cx_pool) {
- cx = cx_pool.poll();
- }
-
Error? open_err = null;
- if (cx == null) {
- try {
- cx = open_connection();
- } catch (Error err) {
- open_err = err;
- debug("Warning: unable to open database connection to %s, cancelling AsyncJob: %s",
- db_file.get_path(), err.message);
- }
+ try {
+ cx = open_connection();
+ } catch (Error err) {
+ open_err = err;
+ debug("Warning: unable to open database connection to %s, cancelling AsyncJob: %s",
+ db_file.get_path(), err.message);
}
if (cx != null)
@@ -301,10 +288,6 @@ public class Geary.Db.Database : Geary.Db.Context {
assert(outstanding_async_jobs > 0);
--outstanding_async_jobs;
}
-
- lock (cx_pool) {
- cx_pool.offer(cx);
- }
}
public override Database? get_database() {
diff --git a/src/engine/db/db-transaction-type.vala b/src/engine/db/db-transaction-type.vala
index bc367eb..651d43b 100644
--- a/src/engine/db/db-transaction-type.vala
+++ b/src/engine/db/db-transaction-type.vala
@@ -11,7 +11,7 @@ public enum Geary.Db.TransactionType {
// coarse synonyms
RO = DEFERRED,
- RW = DEFERRED,
+ RW = IMMEDIATE,
WR = EXCLUSIVE,
WO = EXCLUSIVE;
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index ccb8e3a..49ee528 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -1472,7 +1472,7 @@ private class Geary.ImapDB.Account : BaseObject {
unread_status, Cancellable? cancellable) throws Error {
Gee.Map<Geary.FolderPath, int> unread_change = new Gee.HashMap<Geary.FolderPath, int>();
- yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
+ yield db.exec_transaction_async(Db.TransactionType.RW, (cx) => {
foreach (ImapDB.EmailIdentifier id in unread_status.keys) {
Gee.Set<Geary.FolderPath>? paths = do_find_email_folders(
cx, id.message_id, true, cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]