Externalize more SQLite configuration options.

Moved more configuration into config.xml so we can tweak settings
like the default journal mode, WAL auto-checkpoint interval and
so on.

This change itself should not introduce any functional differences.

Change-Id: Id6c95fa25b116ce47e8ae49cd8a80d52b1c0dd80
This commit is contained in:
Jeff Brown
2012-02-29 21:03:20 -08:00
parent 0e689abaec
commit 5936ff097e
7 changed files with 129 additions and 34 deletions

View File

@@ -208,6 +208,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
mConfiguration.label,
SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME);
setSyncMode();
setPageSize();
setAutoCheckpointInterval();
setJournalSizeLimit();
setJournalModeFromConfiguration();
setLocaleFromConfiguration();
}
@@ -231,6 +236,44 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
}
private void setSyncMode() {
if (!mConfiguration.isInMemoryDb()) {
execute("PRAGMA synchronous=" + SQLiteGlobal.getSyncMode(), null, null);
}
}
private void setPageSize() {
if (!mConfiguration.isInMemoryDb()) {
execute("PRAGMA page_size=" + SQLiteGlobal.getDefaultPageSize(), null, null);
}
}
private void setAutoCheckpointInterval() {
if (!mConfiguration.isInMemoryDb()) {
executeForLong("PRAGMA wal_autocheckpoint=" + SQLiteGlobal.getWALAutoCheckpoint(),
null, null);
}
}
private void setJournalSizeLimit() {
if (!mConfiguration.isInMemoryDb()) {
executeForLong("PRAGMA journal_size_limit=" + SQLiteGlobal.getJournalSizeLimit(),
null, null);
}
}
private void setJournalModeFromConfiguration() {
if (!mConfiguration.isInMemoryDb()) {
String result = executeForString("PRAGMA journal_mode=" + mConfiguration.journalMode,
null, null);
if (!result.equalsIgnoreCase(mConfiguration.journalMode)) {
Log.e(TAG, "setting journal_mode to " + mConfiguration.journalMode
+ " failed for db: " + mConfiguration.label
+ " (on pragma set journal_mode, sqlite returned:" + result);
}
}
}
private void setLocaleFromConfiguration() {
nativeSetLocale(mConnectionPtr, mConfiguration.locale.toString());
}
@@ -246,7 +289,9 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
}
// Remember whether locale has changed.
// Remember what changed.
boolean journalModeChanged = !configuration.journalMode.equalsIgnoreCase(
mConfiguration.journalMode);
boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
// Update configuration parameters.
@@ -255,6 +300,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
// Update prepared statement cache size.
mPreparedStatementCache.resize(configuration.maxSqlCacheSize);
// Update journal mode.
if (journalModeChanged) {
setJournalModeFromConfiguration();
}
// Update locale.
if (localeChanged) {
setLocaleFromConfiguration();

View File

@@ -717,9 +717,6 @@ public class SQLiteDatabase extends SQLiteClosable {
onCorruption();
openInner();
}
// Disable WAL if it was previously enabled.
setJournalMode("TRUNCATE");
} catch (SQLiteException ex) {
Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
close();
@@ -739,19 +736,6 @@ public class SQLiteDatabase extends SQLiteClosable {
}
}
private void setJournalMode(String mode) {
// Journal mode can be set only for non-memory databases
// AND can't be set for readonly databases
if (isInMemoryDatabase() || isReadOnly()) {
return;
}
String s = DatabaseUtils.stringForQuery(this, "PRAGMA journal_mode=" + mode, null);
if (!s.equalsIgnoreCase(mode)) {
Log.e(TAG, "setting journal_mode to " + mode + " failed for db: " + getLabel()
+ " (on pragma set journal_mode, sqlite returned:" + s);
}
}
/**
* Create a memory backed SQLite database. Its contents will be destroyed
* when the database is closed.
@@ -1761,13 +1745,10 @@ public class SQLiteDatabase extends SQLiteClosable {
}
mIsWALEnabledLocked = true;
mConfigurationLocked.maxConnectionPoolSize = Math.max(2,
Resources.getSystem().getInteger(
com.android.internal.R.integer.db_connection_pool_size));
mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
mConfigurationLocked.journalMode = "WAL";
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
}
setJournalMode("WAL");
return true;
}
@@ -1785,10 +1766,9 @@ public class SQLiteDatabase extends SQLiteClosable {
mIsWALEnabledLocked = false;
mConfigurationLocked.maxConnectionPoolSize = 1;
mConfigurationLocked.journalMode = SQLiteGlobal.getDefaultJournalMode();
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
}
setJournalMode("TRUNCATE");
}
/**

View File

@@ -84,6 +84,13 @@ public final class SQLiteDatabaseConfiguration {
*/
public Locale locale;
/**
* The database journal mode.
*
* Default is {@link SQLiteGlobal#getDefaultJournalMode()}.
*/
public String journalMode;
/**
* The custom functions to register.
*/
@@ -110,6 +117,7 @@ public final class SQLiteDatabaseConfiguration {
maxConnectionPoolSize = 1;
maxSqlCacheSize = 25;
locale = Locale.getDefault();
journalMode = SQLiteGlobal.getDefaultJournalMode();
}
/**
@@ -146,6 +154,7 @@ public final class SQLiteDatabaseConfiguration {
maxConnectionPoolSize = other.maxConnectionPoolSize;
maxSqlCacheSize = other.maxSqlCacheSize;
locale = other.locale;
journalMode = other.journalMode;
customFunctions.clear();
customFunctions.addAll(other.customFunctions);
}

View File

@@ -16,6 +16,7 @@
package android.database.sqlite;
import android.content.res.Resources;
import android.os.StatFs;
/**
@@ -64,4 +65,44 @@ public final class SQLiteGlobal {
return sDefaultPageSize;
}
}
/**
* Gets the default journal mode when WAL is not in use.
*/
public static String getDefaultJournalMode() {
return Resources.getSystem().getString(
com.android.internal.R.string.db_default_journal_mode);
}
/**
* Gets the journal size limit in bytes.
*/
public static int getJournalSizeLimit() {
return Resources.getSystem().getInteger(
com.android.internal.R.integer.db_journal_size_limit);
}
/**
* Gets the database synchronization mode.
*/
public static String getSyncMode() {
return Resources.getSystem().getString(
com.android.internal.R.string.db_sync_mode);
}
/**
* Gets the WAL auto-checkpoint integer in database pages.
*/
public static int getWALAutoCheckpoint() {
return Math.max(1, Resources.getSystem().getInteger(
com.android.internal.R.integer.db_wal_autocheckpoint));
}
/**
* Gets the default connection pool size when in WAL mode.
*/
public static int getWALConnectionPoolSize() {
return Math.max(2, Resources.getSystem().getInteger(
com.android.internal.R.integer.db_connection_pool_size));
}
}

View File

@@ -128,15 +128,6 @@ static jint nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlag
return 0;
}
// Enable WAL auto-checkpointing after a commit whenever at least one frame is in the log.
// This ensures that a checkpoint will occur after each transaction if needed.
err = sqlite3_wal_autocheckpoint(db, 1);
if (err) {
throw_sqlite3_exception(env, db, "Could not enable auto-checkpointing.");
sqlite3_close(db);
return 0;
}
// Register custom Android functions.
err = register_android_functions(db, UTF16_STORAGE);
if (err) {

View File

@@ -646,9 +646,29 @@
<bool translatable="false" name="skip_restoring_network_selection">false</bool>
<!-- Maximum number of database connections opened and managed by framework layer
to handle queries on each database. -->
to handle queries on each database when using Write-Ahead Logging. -->
<integer name="db_connection_pool_size">4</integer>
<!-- The default journal mode to use use when Write-Ahead Logging is not active.
Choices are: OFF, DELETE, TRUNCATE, PERSIST and MEMORY.
PERSIST may improve performance by reducing how often journal blocks are
reallocated (compared to truncation) resulting in better data block locality
and less churn of the storage media. -->
<string name="db_default_journal_mode">TRUNCATE</string>
<!-- Maximum size of the persistent journal file in bytes.
If the journal file grows to be larger than this amount then SQLite will
truncate it after committing the transaction. -->
<integer name="db_journal_size_limit">524288</integer>
<!-- The database synchronization mode.
Choices are: FULL, NORMAL, OFF. -->
<string name="db_sync_mode">FULL</string>
<!-- The Write-Ahead Log auto-checkpoint interval in database pages.
The log is checkpointed automatically whenever it exceeds this many pages. -->
<integer name="db_wal_autocheckpoint">1</integer>
<!-- Max space (in MB) allocated to DownloadManager to store the downloaded
files if they are to be stored in DownloadManager's data dir,
which typically is /data/data/com.android.providers.downloads/files -->

View File

@@ -250,6 +250,8 @@
<java-symbol type="integer" name="config_wifi_framework_scan_interval" />
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
<java-symbol type="integer" name="db_connection_pool_size" />
<java-symbol type="integer" name="db_journal_size_limit" />
<java-symbol type="integer" name="db_wal_autocheckpoint" />
<java-symbol type="integer" name="max_action_buttons" />
<java-symbol type="color" name="tab_indicator_text_v4" />
@@ -438,6 +440,8 @@
<java-symbol type="string" name="day_of_week_shortest_thursday" />
<java-symbol type="string" name="day_of_week_shortest_tuesday" />
<java-symbol type="string" name="day_of_week_shortest_wednesday" />
<java-symbol type="string" name="db_default_journal_mode" />
<java-symbol type="string" name="db_sync_mode" />
<java-symbol type="string" name="decline" />
<java-symbol type="string" name="default_permission_group" />
<java-symbol type="string" name="default_text_encoding" />