Author: hwright Date: Mon Oct 25 18:22:59 2010 New Revision: 1027225 URL: http://svn.apache.org/viewvc?rev=1027225&view=rev Log: Merge r984984 from the performance branch.
This revision reduces the number of revprop lookups during export and checkout by caching rev, author, and timestamp triple locally. While I was initially concerned about the cache growing too large, those concerns were allayed here: http://svn.haxx.se/dev/archive-2010-10/0373.shtml Modified: subversion/trunk/ (props changed) subversion/trunk/subversion/libsvn_repos/reporter.c Propchange: subversion/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon Oct 25 18:22:59 2010 @@ -23,7 +23,7 @@ /subversion/branches/log-g-performance:870941-871032 /subversion/branches/merge-skips-obstructions:874525-874615 /subversion/branches/nfc-nfd-aware-client:870276,870376 -/subversion/branches/performance:982355,983764,983766,984927,985014,985037,985046,985472,985477,985482,985500,985669,987888,987893,995507,995603,1001413,1025660 +/subversion/branches/performance:982355,983764,983766,984927,984984,985014,985037,985046,985472,985477,985482,985500,985669,987888,987893,995507,995603,1001413,1025660 /subversion/branches/ra_serf-digest-authn:875693-876404 /subversion/branches/reintegrate-improvements:873853-874164 /subversion/branches/subtree-mergeinfo:876734-878766 Modified: subversion/trunk/subversion/libsvn_repos/reporter.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/reporter.c?rev=1027225&r1=1027224&r2=1027225&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_repos/reporter.c (original) +++ subversion/trunk/subversion/libsvn_repos/reporter.c Mon Oct 25 18:22:59 2010 @@ -84,6 +84,17 @@ typedef struct path_info_t apr_pool_t *pool; /* Container pool */ } path_info_t; +/* Describes the standard revision properties that are relevant for + reports. Since a particular revision will often show up more than + once in the report, we cache these properties for the time of the + report generation. */ +typedef struct revision_info_t +{ + svn_revnum_t rev; /* revision number */ + svn_string_t* date; /* revision timestamp */ + svn_string_t* author; /* name of the revisions' author */ +} revision_info_t; + /* A structure used by the routines within the `reporter' vtable, driven by the client as it describes its working copy revisions. */ typedef struct report_baton_t @@ -118,6 +129,11 @@ typedef struct report_baton_t path_info_t *lookahead; svn_fs_root_t *t_root; svn_fs_root_t *s_roots[NUM_CACHED_SOURCE_ROOTS]; + + /* Cache for revision properties. This is used to eliminate redundant + revprop fetching. */ + apr_hash_t* revision_infos; + apr_pool_t *pool; } report_baton_t; @@ -428,6 +444,53 @@ change_file_prop(report_baton_t *b, void return b->editor->change_file_prop(file_baton, name, value, pool); } +/* For the report B, return the relevant revprop data of revision REV in + REVISION_INFO. The revision info will be allocated in b->pool. + Temporaries get allocated on SCRATCH_POOL. */ +static svn_error_t * +get_revision_info(report_baton_t *b, + svn_revnum_t rev, + revision_info_t** revision_info, + apr_pool_t *scratch_pool) +{ + apr_hash_t *r_props; + svn_string_t *cdate, *author; + revision_info_t* info; + + /* Try to find the info in the report's cache */ + info = apr_hash_get(b->revision_infos, &rev, sizeof(rev)); + if (!info) + { + /* Info is not available, yet. + Get all revprops. */ + SVN_ERR(svn_fs_revision_proplist(&r_props, + b->repos->fs, + rev, + scratch_pool)); + + /* Extract the committed-date. */ + cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE, + APR_HASH_KEY_STRING); + + /* Extract the last-author. */ + author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR, + APR_HASH_KEY_STRING); + + /* Create a result object */ + info = apr_palloc(b->pool, sizeof(*info)); + info->rev = rev; + info->date = cdate ? svn_string_dup(cdate, b->pool) : NULL; + info->author = author ? svn_string_dup(author, b->pool) : NULL; + + /* Cache it */ + apr_hash_set(b->revision_infos, &rev, sizeof(rev), info); + } + + *revision_info = info; + return SVN_NO_ERROR; +} + + /* Generate the appropriate property editing calls to turn the properties of S_REV/S_PATH into those of B->t_root/T_PATH. If S_PATH is NULL, this is an add, so assume the target starts with no @@ -440,12 +503,13 @@ delta_proplists(report_baton_t *b, svn_r void *object, apr_pool_t *pool) { svn_fs_root_t *s_root; - apr_hash_t *s_props, *t_props, *r_props; + apr_hash_t *s_props, *t_props; apr_array_header_t *prop_diffs; int i; svn_revnum_t crev; const char *uuid; - svn_string_t *cr_str, *cdate, *last_author; + svn_string_t *cr_str; + revision_info_t* revision_info; svn_boolean_t changed; const svn_prop_t *pc; svn_lock_t *lock; @@ -459,21 +523,17 @@ delta_proplists(report_baton_t *b, svn_r SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_COMMITTED_REV, cr_str, pool)); - SVN_ERR(svn_fs_revision_proplist(&r_props, b->repos->fs, crev, pool)); + SVN_ERR(get_revision_info(b, crev, &revision_info, pool)); /* Transmit the committed-date. */ - cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE, - APR_HASH_KEY_STRING); - if (cdate || s_path) + if (revision_info->date || s_path) SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_COMMITTED_DATE, - cdate, pool)); + revision_info->date, pool)); /* Transmit the last-author. */ - last_author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR, - APR_HASH_KEY_STRING); - if (last_author || s_path) + if (revision_info->author || s_path) SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_LAST_AUTHOR, - last_author, pool)); + revision_info->author, pool)); /* Transmit the UUID. */ SVN_ERR(svn_fs_get_uuid(b->repos->fs, &uuid, pool)); @@ -1403,6 +1463,8 @@ svn_repos_begin_report2(void **report_ba b->edit_baton = edit_baton; b->authz_read_func = authz_read_func; b->authz_read_baton = authz_read_baton; + b->revision_infos = apr_hash_make(pool); + b->pool = pool; SVN_ERR(svn_io_open_unique_file3(&b->tempfile, NULL, NULL, svn_io_file_del_on_pool_cleanup,
