Author: julianfoad
Date: Tue Nov 30 18:07:51 2010
New Revision: 1040663
URL: http://svn.apache.org/viewvc?rev=1040663&view=rev
Log:
Speed up the pristine store garbage collection done by "svn cleanup". In a
trunk svn WC on my system, this reduces the overall "svn cleanup" time from
about 1 second to about 0.2 seconds for a no-op cleanup with a hot cache.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_pristine_cleanup): Instead of using a separate query to check
whether each pristine text is still referenced, get a list of all the
pristine texts and a list of those that are referenced, and find the
difference by using an APR hash.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_ALL_PRISTINE_REFERENCES): New query.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1040663&r1=1040662&r2=1040663&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Tue Nov 30 18:07:51
2010
@@ -440,6 +440,19 @@ SELECT 1 FROM actual_node
OR right_checksum = ?1 OR right_checksum = ?2
LIMIT 1
+-- STMT_SELECT_ALL_PRISTINE_REFERENCES
+SELECT checksum FROM nodes
+ WHERE checksum IS NOT NULL
+UNION ALL
+SELECT older_checksum FROM actual_node
+ WHERE older_checksum IS NOT NULL
+UNION ALL
+SELECT left_checksum FROM actual_node
+ WHERE left_checksum IS NOT NULL
+UNION ALL
+SELECT right_checksum FROM actual_node
+ WHERE right_checksum IS NOT NULL
+
-- STMT_DELETE_PRISTINE
DELETE FROM pristine
WHERE checksum = ?1
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1040663&r1=1040662&r2=1040663&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Nov 30 18:07:51 2010
@@ -2659,6 +2659,8 @@ svn_wc__db_pristine_cleanup(svn_wc__db_t
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
svn_sqlite__stmt_t *stmt;
+ apr_hash_t *sha1s = apr_hash_make(scratch_pool);
+ apr_hash_index_t *hi;
SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
@@ -2667,25 +2669,63 @@ svn_wc__db_pristine_cleanup(svn_wc__db_t
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- /* Find the pristines in the DB */
+ /* Find all the pristines in the DB; store their SHA-1s in SHA1S. */
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_PRISTINE_ROWS));
while (1)
{
svn_boolean_t have_row;
- const svn_checksum_t *checksum;
+ const svn_checksum_t *sha1_checksum;
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (! have_row)
break;
- SVN_ERR(svn_sqlite__column_checksum(&checksum, stmt, 0,
+ SVN_ERR(svn_sqlite__column_checksum(&sha1_checksum, stmt, 0,
scratch_pool));
- SVN_ERR(svn_wc__db_pristine_remove(db, wri_abspath, checksum,
- scratch_pool));
+ apr_hash_set(sha1s, sha1_checksum->digest,
+ svn_checksum_size(sha1_checksum), (void *)1);
}
SVN_ERR(svn_sqlite__reset(stmt));
+ /* Find all the referenced pristines; remove their SHA-1s from SHA1S. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_SELECT_ALL_PRISTINE_REFERENCES));
+ while (1)
+ {
+ svn_boolean_t have_row;
+ const svn_checksum_t *sha1_checksum;
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (! have_row)
+ break;
+
+ SVN_ERR(svn_sqlite__column_checksum(&sha1_checksum, stmt, 0,
+ scratch_pool));
+ if (sha1_checksum->kind != svn_checksum_sha1)
+ {
+ /* ### Transitional. Should no longer be possible. */
+ SVN_ERR(svn_wc__db_pristine_get_sha1(&sha1_checksum, db, wri_abspath,
+ sha1_checksum,
+ scratch_pool, scratch_pool));
+ }
+ apr_hash_set(sha1s, sha1_checksum->digest,
+ svn_checksum_size(sha1_checksum), NULL);
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ /* Remove each remaining pristine that is listed in SHA1S. */
+ for (hi = apr_hash_first(scratch_pool, sha1s);
+ hi; hi = apr_hash_next(hi))
+ {
+ const unsigned char *sha1_digest = svn__apr_hash_index_key(hi);
+ const svn_checksum_t *sha1_checksum
+ = svn_checksum__from_digest(sha1_digest, svn_checksum_sha1,
+ scratch_pool);
+
+ SVN_ERR(pristine_remove(pdh, sha1_checksum, scratch_pool));
+ }
+
return SVN_NO_ERROR;
}