Add option to enable memory-mapped I/O

This commit is contained in:
chme 2015-09-13 09:10:42 +02:00
parent 2da993cc7b
commit 56f4b32ef3
4 changed files with 103 additions and 0 deletions

View File

@ -315,6 +315,16 @@ sqlite {
# Change the setting of the "synchronous" flag
# 0: OFF, 1: NORMAL, 2: FULL (default)
# pragma_synchronous = 2
# Number of bytes set aside for memory-mapped I/O for the library database
# (requires sqlite 3.7.17 or later)
# 0: disables mmap (default), any other value > 0: number of bytes for mmap
# pragma_mmap_size_library = 0
# Number of bytes set aside for memory-mapped I/O for the cache database
# (requires sqlite 3.7.17 or later)
# 0: disables mmap (default), any other value > 0: number of bytes for mmap
# pragma_mmap_size_cache = 0
# Should the database be vacuumed on startup? (increases startup time,
# but may reduce database size). Default is yes.

View File

@ -445,11 +445,13 @@ cache_create(void)
#define Q_PRAGMA_CACHE_SIZE "PRAGMA cache_size=%d;"
#define Q_PRAGMA_JOURNAL_MODE "PRAGMA journal_mode=%s;"
#define Q_PRAGMA_SYNCHRONOUS "PRAGMA synchronous=%d;"
#define Q_PRAGMA_MMAP_SIZE "PRAGMA mmap_size=%d;"
char *errmsg;
int ret;
int cache_size;
char *journal_mode;
int synchronous;
int mmap_size;
char *query;
// Open db
@ -534,12 +536,29 @@ cache_create(void)
}
}
// Set mmap size
mmap_size = cfg_getint(cfg_getsec(cfg, "sqlite"), "pragma_mmap_size_cache");
if (synchronous > -1)
{
query = sqlite3_mprintf(Q_PRAGMA_MMAP_SIZE, mmap_size);
ret = sqlite3_exec(g_db_hdl, query, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
DPRINTF(E_LOG, L_CACHE, "Error setting pragma_mmap_size: %s\n", errmsg);
sqlite3_free(errmsg);
sqlite3_close(g_db_hdl);
return -1;
}
}
DPRINTF(E_DBG, L_CACHE, "Cache created\n");
return 0;
#undef Q_PRAGMA_CACHE_SIZE
#undef Q_PRAGMA_JOURNAL_MODE
#undef Q_PRAGMA_SYNCHRONOUS
#undef Q_PRAGMA_MMAP_SIZE
}
static void

View File

@ -151,6 +151,8 @@ static cfg_opt_t sec_sqlite[] =
CFG_INT("pragma_cache_size_cache", -1, CFGF_NONE),
CFG_STR("pragma_journal_mode", NULL, CFGF_NONE),
CFG_INT("pragma_synchronous", -1, CFGF_NONE),
CFG_INT("pragma_mmap_size_library", -1, CFGF_NONE),
CFG_INT("pragma_mmap_size_cache", -1, CFGF_NONE),
CFG_BOOL("vacuum", cfg_true, CFGF_NONE),
CFG_END()
};

View File

@ -6037,6 +6037,70 @@ db_pragma_set_synchronous(int synchronous)
#undef Q_TMPL
}
static int
db_pragma_get_mmap_size()
{
sqlite3_stmt *stmt;
char *query = "PRAGMA mmap_size;";
int ret;
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
ret = db_blocking_prepare_v2(query, -1, &stmt, NULL);
if (ret != SQLITE_OK)
{
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
sqlite3_free(query);
return 0;
}
ret = db_blocking_step(stmt);
if (ret == SQLITE_DONE)
{
DPRINTF(E_DBG, L_DB, "End of query results\n");
sqlite3_free(query);
return 0;
}
else if (ret != SQLITE_ROW)
{
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
sqlite3_free(query);
return -1;
}
ret = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return ret;
}
static int
db_pragma_set_mmap_size(int mmap_size)
{
#define Q_TMPL "PRAGMA mmap_size=%d;"
sqlite3_stmt *stmt;
char *query;
int ret;
query = sqlite3_mprintf(Q_TMPL, mmap_size);
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
ret = db_blocking_prepare_v2(query, -1, &stmt, NULL);
if (ret != SQLITE_OK)
{
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
sqlite3_free(query);
return 0;
}
sqlite3_finalize(stmt);
sqlite3_free(query);
return 0;
#undef Q_TMPL
}
int
@ -6047,6 +6111,7 @@ db_perthread_init(void)
int cache_size;
char *journal_mode;
int synchronous;
int mmap_size;
ret = sqlite3_open(db_path, &hdl);
if (ret != SQLITE_OK)
@ -6118,6 +6183,13 @@ db_perthread_init(void)
DPRINTF(E_DBG, L_DB, "Database synchronous: %d\n", synchronous);
}
mmap_size = cfg_getint(cfg_getsec(cfg, "sqlite"), "pragma_mmap_size_library");
if (mmap_size > -1)
{
db_pragma_set_mmap_size(mmap_size);
mmap_size = db_pragma_get_mmap_size();
DPRINTF(E_DBG, L_DB, "Database mmap_size: %d\n", mmap_size);
}
return 0;
}