You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/05/20 21:16:50 UTC
svn commit: r1340806 - in /subversion/trunk/subversion/libsvn_subr:
internal_statements.sql sqlite.c
Author: rhuijben
Date: Sun May 20 19:16:50 2012
New Revision: 1340806
URL: http://svn.apache.org/viewvc?rev=1340806&view=rev
Log:
Speed up the Sqlite savepoint creation and releasing in our Sqlite api by
using a prepared statement instead of generated sql.
The SQL tokenizer shouldn't show up in filtered performance reports for a
simple checkout...
Sqlite allows nesting savepoints with the same name, so this doesn't require
changes to our private api. Extend the set of prepared statements with a few
library internal statements to allow using the current infrastructure.
* subversion/libsvn_subr/internal_statements.sql
(STMT_DUMMY_SELECT_FOR_BACKUP): Remove unused dummy.
(STMT_INTERNAL_SAVEPOINT_SVN,
STMT_INTERNAL_RELEASE_SAVEPOINT_SVN,
STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN,
STMT_INTERNAL_LAST): New statements.
* subversion/libsvn_subr/sqlite.c
(get_internal_statement): New function.
(close_apr): finalize the internal statements.
(svn_sqlite__open): Keep space for a few extra statements.
(svn_sqlite__with_lock): Use internal statements instead of sql text.
Modified:
subversion/trunk/subversion/libsvn_subr/internal_statements.sql
subversion/trunk/subversion/libsvn_subr/sqlite.c
Modified: subversion/trunk/subversion/libsvn_subr/internal_statements.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/internal_statements.sql?rev=1340806&r1=1340805&r2=1340806&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/internal_statements.sql (original)
+++ subversion/trunk/subversion/libsvn_subr/internal_statements.sql Sun May 20 19:16:50 2012
@@ -21,5 +21,15 @@
* ====================================================================
*/
--- STMT_DUMMY_SELECT_FOR_BACKUP
-SELECT * FROM SQLITE_MASTER;
+-- STMT_INTERNAL_SAVEPOINT_SVN
+SAVEPOINT svn;
+
+-- STMT_INTERNAL_RELEASE_SAVEPOINT_SVN
+RELEASE SAVEPOINT svn;
+
+-- STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN
+ROLLBACK TO SAVEPOINT svn;
+
+/* Dummmy statement to determine the number of internal statements */
+-- STMT_INTERNAL_LAST
+;
Modified: subversion/trunk/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/sqlite.c?rev=1340806&r1=1340805&r2=1340806&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/trunk/subversion/libsvn_subr/sqlite.c Sun May 20 19:16:50 2012
@@ -204,6 +204,29 @@ svn_sqlite__get_statement(svn_sqlite__st
return SVN_NO_ERROR;
}
+/* Like svn_sqlite__get_statement but gets an internal statement.
+
+ All internal statements that use this api are executed with step_done(),
+ so we don't need the fallback reset handling here or in the pool cleanup */
+svn_error_t *
+get_internal_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
+ int stmt_idx)
+{
+ /* The internal statements are stored after the registered statements */
+ int prep_idx = db->nbr_statements + stmt_idx;
+ SVN_ERR_ASSERT(stmt_idx < STMT_INTERNAL_LAST);
+
+ if (db->prepared_stmts[prep_idx] == NULL)
+ SVN_ERR(prepare_statement(&db->prepared_stmts[prep_idx], db,
+ internal_statements[stmt_idx],
+ db->state_pool));
+
+ *stmt = db->prepared_stmts[prep_idx];
+
+ return SVN_NO_ERROR;
+}
+
+
static svn_error_t *
step_with_expectation(svn_sqlite__stmt_t* stmt,
svn_boolean_t expecting_row)
@@ -742,6 +765,15 @@ close_apr(void *data)
svn_sqlite__finalize(db->prepared_stmts[i]), err);
}
}
+ /* And finalize any used internal statements */
+ for (; i < db->nbr_statements + STMT_INTERNAL_LAST; i++)
+ {
+ if (db->prepared_stmts[i])
+ {
+ err = svn_error_compose_create(
+ svn_sqlite__finalize(db->prepared_stmts[i]), err);
+ }
+ }
result = sqlite3_close(db->db3);
@@ -844,11 +876,19 @@ svn_sqlite__open(svn_sqlite__db_t **db,
statements++;
(*db)->nbr_statements++;
}
- (*db)->prepared_stmts = apr_pcalloc(result_pool, (*db)->nbr_statements
+
+ (*db)->prepared_stmts = apr_pcalloc(
+ result_pool,
+ ((*db)->nbr_statements + STMT_INTERNAL_LAST)
* sizeof(svn_sqlite__stmt_t *));
}
else
- (*db)->nbr_statements = 0;
+ {
+ (*db)->nbr_statements = 0;
+ (*db)->prepared_stmts = apr_pcalloc(result_pool,
+ (0 + STMT_INTERNAL_LAST)
+ * sizeof(svn_sqlite__stmt_t *));
+ }
(*db)->state_pool = result_pool;
apr_pool_cleanup_register(result_pool, *db, close_apr, apr_pool_cleanup_null);
@@ -970,20 +1010,21 @@ svn_sqlite__with_lock(svn_sqlite__db_t *
apr_pool_t *scratch_pool)
{
svn_error_t *err;
- int savepoint = db->savepoint_nr++;
- /* This buffer is plenty big to hold the SAVEPOINT and RELEASE commands. */
- char buf[32];
+ svn_sqlite__stmt_t *stmt;
- snprintf(buf, sizeof(buf), "SAVEPOINT s%u", savepoint);
- SVN_ERR(exec_sql(db, buf));
+ SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_SAVEPOINT_SVN));
+ SVN_ERR(svn_sqlite__step_done(stmt));
err = cb_func(cb_baton, db, scratch_pool);
if (err)
{
svn_error_t *err2;
- snprintf(buf, sizeof(buf), "ROLLBACK TO s%u", savepoint);
- err2 = exec_sql(db, buf);
+ err2 = get_internal_statement(&stmt, db,
+ STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN);
+
+ if (!err2)
+ err2 = svn_sqlite__step_done(stmt);
if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
{
@@ -994,17 +1035,23 @@ svn_sqlite__with_lock(svn_sqlite__db_t *
further details */
err2 = reset_all_statements(db, err2);
- err2 = svn_error_compose_create(exec_sql(db, buf), err2);
+ err2 = svn_error_compose_create(svn_sqlite__step_done(stmt), err2);
}
- snprintf(buf, sizeof(buf), "RELEASE s%u", savepoint);
- err2 = svn_error_compose_create(exec_sql(db, buf), err2);
+ err = svn_error_compose_create(err, err2);
+ err2 = get_internal_statement(&stmt, db,
+ STMT_INTERNAL_RELEASE_SAVEPOINT_SVN);
+
+ if (!err2)
+ err2 = svn_sqlite__step_done(stmt);
return svn_error_trace(svn_error_compose_create(err, err2));
}
- snprintf(buf, sizeof(buf), "RELEASE s%u", savepoint);
- return svn_error_trace(exec_sql(db, buf));
+ SVN_ERR(get_internal_statement(&stmt, db,
+ STMT_INTERNAL_RELEASE_SAVEPOINT_SVN));
+
+ return svn_error_trace(svn_sqlite__step_done(stmt));
}
svn_error_t *
@@ -1015,7 +1062,7 @@ svn_sqlite__hotcopy(const char *src_path
svn_sqlite__db_t *src_db;
SVN_ERR(svn_sqlite__open(&src_db, src_path, svn_sqlite__mode_readonly,
- internal_statements, 0, NULL,
+ NULL, 0, NULL,
scratch_pool, scratch_pool));
{