Author: stefan2
Date: Tue Jun 30 12:54:15 2015
New Revision: 1688443
URL: http://svn.apache.org/r1688443
Log:
On the svn-mergeinfo-normalizer branch:
Move the "normalize" logic to the common logic file and make the
progress reporting generic, i.e. cover all 3 sub-command options.
Following commits will merge the logic of the other 2 sub-commands
in there as well.
* tools/client-side/svn-mergeinfo-normalizer/logic.c
(all_positive_ranges,
remove_lines): Logic moved here from normalize-cmd.c.
(progress_t,
progress_string): New, generic progress reporting.
(default_processor): Former "normalize" function. Uses the
generic progress reporting.
(svn_min__run_command): If the sub-command does not provided a
processing callback, use our default
normalizer function.
* tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
(all_positive_ranges,
remove_lines,
normalize): Logic moved to logic.c .
(svn_min__normalize): Use the normalizer in logic.c now.
Modified:
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/logic.c
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
Modified:
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/logic.c
URL:
http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/logic.c?rev=1688443&r1=1688442&r2=1688443&view=diff
==============================================================================
---
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/logic.c
(original)
+++
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/logic.c
Tue Jun 30 12:54:15 2015
@@ -42,6 +42,196 @@
/*** Code. ***/
static svn_boolean_t
+all_positive_ranges(svn_rangelist_t *ranges)
+{
+ int i;
+ for (i = 0; i < ranges->nelts; ++i)
+ {
+ const svn_merge_range_t *range
+ = APR_ARRAY_IDX(ranges, i, const svn_merge_range_t *);
+
+ if (range->start > range->end)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static svn_error_t *
+remove_lines(svn_min__log_t *log,
+ const char *relpath,
+ svn_mergeinfo_t parent_mergeinfo,
+ svn_mergeinfo_t subtree_mergeinfo,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first(scratch_pool, parent_mergeinfo);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *parent_path, *subtree_path;
+ svn_rangelist_t *parent_ranges, *subtree_ranges;
+ svn_rangelist_t *operative_outside_subtree, *operative_in_subtree;
+
+ svn_pool_clear(iterpool);
+
+ parent_path = apr_hash_this_key(hi);
+ subtree_path = svn_fspath__join(parent_path, relpath, iterpool);
+ parent_ranges = apr_hash_this_val(hi);
+ subtree_ranges = svn_hash_gets(subtree_mergeinfo, subtree_path);
+
+ if (subtree_ranges && all_positive_ranges(subtree_ranges))
+ {
+ svn_rangelist_t *subtree_only;
+ svn_rangelist_t *parent_only;
+
+ SVN_ERR(svn_rangelist_diff(&parent_only, &subtree_only,
+ parent_ranges, subtree_ranges, FALSE,
+ iterpool));
+ subtree_only
+ = svn_min__operative(log, subtree_path, parent_only, iterpool);
+
+ operative_outside_subtree
+ = svn_min__operative_outside_subtree(log, parent_path,
subtree_path,
+ subtree_only, iterpool);
+ operative_in_subtree
+ = svn_min__operative(log, subtree_path, parent_only, iterpool);
+
+ /* This will also work when subtree_only is empty. */
+ if ( !operative_outside_subtree->nelts
+ && !operative_in_subtree->nelts)
+ {
+ SVN_ERR(svn_rangelist_merge2(parent_ranges, subtree_only,
+ parent_ranges->pool, iterpool));
+ svn_hash_sets(subtree_mergeinfo, subtree_path, NULL);
+ }
+ }
+ }
+
+ /* TODO: Move subtree ranges to parent even if the parent has no entry
+ * for the respective branches, yet. */
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+typedef struct progress_t
+{
+ int nodes_total;
+ int nodes_todo;
+
+ apr_int64_t nodes_removed;
+ apr_int64_t obsoletes_removed;
+ apr_int64_t ranges_removed;
+} progress_t;
+
+static const char *
+progress_string(const progress_t *progress,
+ svn_min__opt_state_t *opt_state,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *obsoletes_str = apr_psprintf(scratch_pool,
+ "%" APR_UINT64_T_FMT,
+ progress->obsoletes_removed);
+ const char *nodes_str = apr_psprintf(scratch_pool,
+ "%" APR_UINT64_T_FMT,
+ progress->nodes_removed);
+ const char *ranges_str = apr_psprintf(scratch_pool,
+ "%" APR_UINT64_T_FMT,
+ progress->ranges_removed);
+
+ svn_stringbuf_t *result = svn_stringbuf_create_empty(result_pool);
+ svn_stringbuf_appendcstr(result,
+ apr_psprintf(scratch_pool,
+ _("Processed %d nodes"),
+ progress->nodes_total
+ - progress->nodes_todo));
+
+ if (opt_state->remove_obsoletes)
+ svn_stringbuf_appendcstr(result,
+ apr_psprintf(scratch_pool,
+ _(", removed %s obsoletes"),
+ obsoletes_str));
+
+ if (opt_state->remove_redundants)
+ svn_stringbuf_appendcstr(result,
+ apr_psprintf(scratch_pool,
+ _(", removed m/i on %s sub-nodes"),
+ nodes_str));
+
+ if (opt_state->combine_ranges)
+ svn_stringbuf_appendcstr(result,
+ apr_psprintf(scratch_pool,
+ _(", combined %s ranges"),
+ ranges_str));
+
+ return result->data;
+}
+
+static svn_error_t *
+default_processor(apr_array_header_t *wc_mergeinfo,
+ svn_min__log_t *log,
+ svn_ra_session_t *session,
+ svn_min__opt_state_t *opt_state,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ progress_t progress = { 0 };
+
+ int i;
+ progress.nodes_total = wc_mergeinfo->nelts;
+ for (i = wc_mergeinfo->nelts - 1; i >= 0; --i)
+ {
+ const char *parent_path;
+ const char *relpath;
+ svn_mergeinfo_t parent_mergeinfo;
+ svn_mergeinfo_t subtree_mergeinfo;
+ progress.nodes_todo = i;
+
+ if (svn_min__get_mergeinfo_pair(&parent_path, &relpath,
+ &parent_mergeinfo, &subtree_mergeinfo,
+ wc_mergeinfo, i))
+ {
+ svn_mergeinfo_t parent_mergeinfo_copy;
+ svn_mergeinfo_t subtree_mergeinfo_copy;
+
+ svn_pool_clear(iterpool);
+ parent_mergeinfo_copy = svn_mergeinfo_dup(parent_mergeinfo,
+ iterpool);
+ subtree_mergeinfo_copy = svn_mergeinfo_dup(subtree_mergeinfo,
+ iterpool);
+
+ SVN_ERR(remove_lines(log, relpath, parent_mergeinfo_copy,
+ subtree_mergeinfo_copy, iterpool));
+
+ if (apr_hash_count(subtree_mergeinfo_copy) == 0)
+ {
+ SVN_ERR(svn_mergeinfo_merge2(parent_mergeinfo,
+ parent_mergeinfo_copy,
+ apr_hash_pool_get(parent_mergeinfo),
+ iterpool));
+ apr_hash_clear(subtree_mergeinfo);
+ ++progress.nodes_removed;
+ }
+ }
+
+ if (!opt_state->quiet && i % 1000 == 0)
+ SVN_ERR(svn_cmdline_printf(iterpool, " %s.\n",
+ progress_string(&progress, opt_state,
+ iterpool, iterpool)));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_boolean_t
needs_log(svn_min__opt_state_t *opt_state)
{
return opt_state->combine_ranges || opt_state->remove_redundants;
@@ -91,8 +281,11 @@ svn_min__run_command(apr_getopt_t *os,
svn_min__cmd_baton_t *cmd_baton = baton;
apr_pool_t *iterpool = svn_pool_create(pool);
apr_pool_t *subpool = svn_pool_create(pool);
-
int i;
+
+ if (processor == NULL)
+ processor = default_processor;
+
for (i = 0; i < cmd_baton->opt_state->targets->nelts; i++)
{
apr_array_header_t *wc_mergeinfo;
Modified:
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c?rev=1688443&r1=1688442&r2=1688443&view=diff
==============================================================================
---
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
(original)
+++
subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/normalize-cmd.c
Tue Jun 30 12:54:15 2015
@@ -27,153 +27,11 @@
/*** Includes. ***/
-#include "svn_cmdline.h"
-#include "svn_dirent_uri.h"
-#include "svn_hash.h"
-#include "svn_path.h"
-#include "svn_pools.h"
-#include "private/svn_fspath.h"
-
#include "mergeinfo-normalizer.h"
-#include "svn_private_config.h"
-
/*** Code. ***/
-static svn_boolean_t
-all_positive_ranges(svn_rangelist_t *ranges)
-{
- int i;
- for (i = 0; i < ranges->nelts; ++i)
- {
- const svn_merge_range_t *range
- = APR_ARRAY_IDX(ranges, i, const svn_merge_range_t *);
-
- if (range->start > range->end)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static svn_error_t *
-remove_lines(svn_min__log_t *log,
- const char *relpath,
- svn_mergeinfo_t parent_mergeinfo,
- svn_mergeinfo_t subtree_mergeinfo,
- apr_pool_t *scratch_pool)
-{
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- apr_hash_index_t *hi;
- for (hi = apr_hash_first(scratch_pool, parent_mergeinfo);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *parent_path, *subtree_path;
- svn_rangelist_t *parent_ranges, *subtree_ranges;
- svn_rangelist_t *operative_outside_subtree, *operative_in_subtree;
-
- svn_pool_clear(iterpool);
-
- parent_path = apr_hash_this_key(hi);
- subtree_path = svn_fspath__join(parent_path, relpath, iterpool);
- parent_ranges = apr_hash_this_val(hi);
- subtree_ranges = svn_hash_gets(subtree_mergeinfo, subtree_path);
-
- if (subtree_ranges && all_positive_ranges(subtree_ranges))
- {
- svn_rangelist_t *subtree_only;
- svn_rangelist_t *parent_only;
-
- SVN_ERR(svn_rangelist_diff(&parent_only, &subtree_only,
- parent_ranges, subtree_ranges, FALSE,
- iterpool));
- subtree_only
- = svn_min__operative(log, subtree_path, parent_only, iterpool);
-
- operative_outside_subtree
- = svn_min__operative_outside_subtree(log, parent_path,
subtree_path,
- subtree_only, iterpool);
- operative_in_subtree
- = svn_min__operative(log, subtree_path, parent_only, iterpool);
-
- /* This will also work when subtree_only is empty. */
- if ( !operative_outside_subtree->nelts
- && !operative_in_subtree->nelts)
- {
- SVN_ERR(svn_rangelist_merge2(parent_ranges, subtree_only,
- parent_ranges->pool, iterpool));
- svn_hash_sets(subtree_mergeinfo, subtree_path, NULL);
- }
- }
- }
-
- /* TODO: Move subtree ranges to parent even if the parent has no entry
- * for the respective branches, yet. */
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-normalize(apr_array_header_t *wc_mergeinfo,
- svn_min__log_t *log,
- svn_ra_session_t *session,
- svn_min__opt_state_t *opt_state,
- apr_pool_t *scratch_pool)
-{
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- int i;
- int deleted = 0;
- for (i = wc_mergeinfo->nelts - 1; i >= 0; --i)
- {
- const char *parent_path;
- const char *relpath;
- svn_mergeinfo_t parent_mergeinfo;
- svn_mergeinfo_t subtree_mergeinfo;
-
- if (svn_min__get_mergeinfo_pair(&parent_path, &relpath,
- &parent_mergeinfo, &subtree_mergeinfo,
- wc_mergeinfo, i))
- {
- svn_mergeinfo_t parent_mergeinfo_copy;
- svn_mergeinfo_t subtree_mergeinfo_copy;
-
- svn_pool_clear(iterpool);
- parent_mergeinfo_copy = svn_mergeinfo_dup(parent_mergeinfo,
- iterpool);
- subtree_mergeinfo_copy = svn_mergeinfo_dup(subtree_mergeinfo,
- iterpool);
-
- SVN_ERR(remove_lines(log, relpath, parent_mergeinfo_copy,
- subtree_mergeinfo_copy, iterpool));
-
- if (apr_hash_count(subtree_mergeinfo_copy) == 0)
- {
- SVN_ERR(svn_mergeinfo_merge2(parent_mergeinfo,
- parent_mergeinfo_copy,
- apr_hash_pool_get(parent_mergeinfo),
- iterpool));
- apr_hash_clear(subtree_mergeinfo);
- ++deleted;
- }
- }
-
- if (!opt_state->quiet && i % 1000 == 0)
- SVN_ERR(svn_cmdline_printf(iterpool,
- _(" Processed %d nodes, eliminated mergeinfo on %d.\n"),
- wc_mergeinfo->nelts - i, deleted));
- }
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_min__normalize(apr_getopt_t *os,
@@ -182,7 +40,7 @@ svn_min__normalize(apr_getopt_t *os,
{
svn_min__cmd_baton_t *cmd_baton = baton;
cmd_baton->opt_state->remove_redundants = TRUE;
- SVN_ERR(svn_min__run_command(os, baton, normalize, pool));
+ SVN_ERR(svn_min__run_command(os, baton, NULL, pool));
return SVN_NO_ERROR;
}