Denis Kovalchuk wrote on Wed, 18 Mar 2020 17:32 +0300:
> +++ subversion/include/private/svn_fs_fs_private.h    (working copy)
> @@ -353,6 +353,16 @@

Please use the -p option to diff.

> +typedef struct svn_fs_fs__ioctl_build_rep_cache_input_t
> +{
> +  svn_revnum_t start_rev;
> +  svn_revnum_t end_rev;
> +  svn_fs_progress_notify_func_t progress_func;
> +  void *progress_baton;
> +} svn_fs_fs__ioctl_build_rep_cache_input_t;
> +

Add:

   /* See svn_fs_fs__build_rep_cache(). */

> +SVN_FS_DECLARE_IOCTL_CODE(SVN_FS_FS__IOCTL_BUILD_REP_CACHE, 
> SVN_FS_TYPE_FSFS, 1004);

> +++ subversion/libsvn_fs_fs/fs_fs.c   (working copy)
> +static svn_error_t *
> +reindex_node(svn_fs_t *fs,
⋮
> +{
⋮
> +  if (noderev->data_rep && noderev->data_rep->revision == rev &&
> +      noderev->kind == svn_node_file)
> +    {
> +      SVN_ERR(ensure_representation_sha1(fs, noderev->data_rep, pool));
> +      SVN_ERR(svn_fs_fs__set_rep_reference(fs, noderev->data_rep, pool));

STMT_SET_REP uses «INSERT OR FAIL».  Therefore, this call will fail if
any of the reps in REV are in rep-cache.db.  In particular, I expect it
will fail in the common case that _all_ of the reps in REV are already
in the database (which can happen if enable-rep-sharing was toggled
during the filesystem's lifetime).  Shouldn't it silently succeed in
that case?  I.e., shouldn't the API be idempotent?

> +    }
> +
> +  if (noderev->prop_rep && noderev->prop_rep->revision == rev)
> +    {
> +      SVN_ERR(ensure_representation_sha1(fs, noderev->prop_rep, pool));
> +      SVN_ERR(svn_fs_fs__set_rep_reference(fs, noderev->prop_rep, pool));

Ditto.

> +    }
> +
> +  return SVN_NO_ERROR;
> +}

> +svn_fs_fs__build_rep_cache(svn_fs_t *fs,
⋮
> +{
> +  if (!ffd->rep_sharing_allowed)
> +    {
> +      return SVN_NO_ERROR;

Shouldn't this case be an error?  This isn't a case of "Nothing done,
nothing said" as above, but a case of "the precondition is unmet".

If need be, rep_sharing_allowed can be exposed via `svnadmin info`.

> +    }

> +  /* Do not build rep-cache for revision zero to match
> +   * svn_fs_fs__create() behavior. */
> +  for (rev = start_rev; rev <= end_rev; rev++)

This comment should be placed near the «start_rev = 1;» line (snipped),
rather than here.

> +    {
⋮
> +      SVN_ERR(svn_sqlite__begin_transaction(ffd->rep_cache_db));
> +      err = reindex_node(fs, root_id, rev, file, cancel_func, cancel_baton, 
> iterpool);
> +      SVN_ERR(svn_sqlite__finish_transaction(ffd->rep_cache_db, err));

Shouldn't this function take a write lock — at least, to prevent
«svnadmin upgrade» from running concurrently?

>  static const svn_opt_subcommand_desc3_t cmd_table[] =
>  {
> +  {"build-repcache", subcommand_build_repcache, {0}, {N_(
> +    "usage: svnadmin build-repcache REPOS_PATH [-r LOWER[:UPPER]]\n"
> +    "\n") N_(
> +    "Add missing entries to the representation cache for the repository\n"
> +    "at REPOS_PATH. Process data in revisions LOWER through UPPER.\n"
> +    "If no revision arguments are given, process all revisions. If only\n"
> +    "LOWER revision argument is given, process only that single revision.\n"
> +   )},

Why isn't there a comma between the two string literals, as in the other
array entries?

> +   {'r', 'q', 'M'} },

> +++ subversion/tests/cmdline/svnadmin_tests.py        (working copy)
> @@ -4036,7 +4036,28 @@
> +@SkipUnless(svntest.main.is_fs_type_fsfs)
> +@SkipUnless(svntest.main.fs_has_rep_sharing)

Sounds like we should have fs_has_rep_sharing() call is_fs_type_fsfs().

Cheers,

Daniel

Reply via email to