Author: rhuijben
Date: Thu Jul 1 23:39:49 2010
New Revision: 959812
URL: http://svn.apache.org/viewvc?rev=959812&view=rev
Log:
Add a simple repository root->uuid cache to the upgrade code to allow
upgrading Subversion 1.4 and 1.5 working copies that just contain a
new subdir to upgrade without contacting the repository.
* subversion/libsvn_wc/upgrade.c
(ensure_repos_info): Try to find a repository in the cache.
(upgrade_to_wcng): Pass and fill the cache.
(upgrade_working_copy): Pass the cache between invocations.
(svn_wc_upgrade): Pass new hashtable.
Modified:
subversion/trunk/subversion/libsvn_wc/upgrade.c
Modified: subversion/trunk/subversion/libsvn_wc/upgrade.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/upgrade.c?rev=959812&r1=959811&r2=959812&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/trunk/subversion/libsvn_wc/upgrade.c Thu Jul 1 23:39:49 2010
@@ -508,7 +508,8 @@ wipe_obsolete_files(const char *wcroot_a
used within the upgraded entries as they are written into the database.
If one or both are not available, then it attempts to retrieve this
- information from REPOS_INFO_FUNC, passing REPOS_INFO_BATON.
+ information from REPOS_CACHE. And if that fails from REPOS_INFO_FUNC,
+ passing REPOS_INFO_BATON.
Returns a user understandable error using LOCAL_ABSPATH if the
information cannot be obtained. */
static svn_error_t *
@@ -516,6 +517,7 @@ ensure_repos_info(svn_wc_entry_t *entry,
const char *local_abspath,
svn_wc_upgrade_get_repos_info_t repos_info_func,
void *repos_info_baton,
+ apr_hash_t *repos_cache,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -523,6 +525,28 @@ ensure_repos_info(svn_wc_entry_t *entry,
if (entry->repos != NULL && entry->uuid != NULL)
return SVN_NO_ERROR;
+ if ((entry->repos == NULL || entry->uuid == NULL)
+ && entry->url)
+ {
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(scratch_pool, repos_cache);
+ hi; hi = apr_hash_next(hi))
+ {
+ if (svn_uri_is_child(svn__apr_hash_index_key(hi),
+ entry->url, NULL))
+ {
+ if (!entry->repos)
+ entry->repos = svn__apr_hash_index_key(hi);
+
+ if (!entry->uuid)
+ entry->uuid = svn__apr_hash_index_val(hi);
+
+ return SVN_NO_ERROR;
+ }
+ }
+ }
+
if (entry->repos == NULL && repos_info_func == NULL)
return svn_error_createf(
SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
@@ -1130,6 +1154,11 @@ bump_to_XXX(void *baton, svn_sqlite__db_
/* Upgrade the working copy directory represented by DB/DIR_ABSPATH
from OLD_FORMAT to the wc-ng format (SVN_WC__WC_NG_VERSION)'.
+ Pass REPOS_INFO_FUNC, REPOS_INFO_BATON and REPOS_CACHE to
+ ensure_repos_info. Add the found repository root and UUID to
+ REPOS_CACHE if it doesn't have a cached entry for this
+ repository.
+
Uses SCRATCH_POOL for all temporary allocation. */
static svn_error_t *
upgrade_to_wcng(svn_wc__db_t *db,
@@ -1137,6 +1166,7 @@ upgrade_to_wcng(svn_wc__db_t *db,
int old_format,
svn_wc_upgrade_get_repos_info_t repos_info_func,
void *repos_info_baton,
+ apr_hash_t *repos_cache,
apr_pool_t *scratch_pool)
{
const char *logfile_path = svn_wc__adm_child(dir_abspath, ADM_LOG,
@@ -1187,8 +1217,20 @@ upgrade_to_wcng(svn_wc__db_t *db,
this_dir = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING);
SVN_ERR(ensure_repos_info(this_dir, dir_abspath,
repos_info_func, repos_info_baton,
+ repos_cache,
scratch_pool, iterpool));
+ /* Cache repos UUID pairs for when a subdir doesn't have this information */
+ if (!apr_hash_get(repos_cache, this_dir->repos, APR_HASH_KEY_STRING))
+ {
+ apr_pool_t *hash_pool = apr_hash_pool_get(repos_cache);
+
+ apr_hash_set(repos_cache,
+ apr_pstrdup(hash_pool, this_dir->repos),
+ APR_HASH_KEY_STRING,
+ apr_pstrdup(hash_pool, this_dir->uuid));
+ }
+
/* Create an empty sqlite database for this directory. */
SVN_ERR(svn_wc__db_upgrade_begin(&sdb, &repos_id, &wc_id, dir_abspath,
this_dir->repos, this_dir->uuid,
@@ -1385,6 +1427,7 @@ upgrade_working_copy(svn_wc__db_t *db,
const char *dir_abspath,
svn_wc_upgrade_get_repos_info_t repos_info_func,
void *repos_info_baton,
+ apr_hash_t *repos_cache,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -1410,7 +1453,7 @@ upgrade_working_copy(svn_wc__db_t *db,
if (old_format < SVN_WC__WC_NG_VERSION)
SVN_ERR(upgrade_to_wcng(db, dir_abspath, old_format,
repos_info_func, repos_info_baton,
- iterpool));
+ repos_cache, iterpool));
if (notify_func)
notify_func(notify_baton,
@@ -1427,6 +1470,7 @@ upgrade_working_copy(svn_wc__db_t *db,
SVN_ERR(upgrade_working_copy(db, child_abspath,
repos_info_func, repos_info_baton,
+ repos_cache,
cancel_func, cancel_baton,
notify_func, notify_baton,
iterpool));
@@ -1473,6 +1517,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
/* Upgrade this directory and/or its subdirectories. */
SVN_ERR(upgrade_working_copy(db, local_abspath,
repos_info_func, repos_info_baton,
+ apr_hash_make(scratch_pool),
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));