Julian Foad wrote:
[...]
> * simplify implementation by using the existing
> svn_fs_fs__dump_index() API with a simple callback
Here's v2, functionally identical, with that simplification.
--
- Julian
Add an API and CLI to report a revision's size on disk.
### So far, this patch only works with FSFS logical addressing mode.
It reports the total size in bytes of the representation on disk of
a revision, excluding its indexes.
$ svnfsfs rev-size /path/to/repo -r1
1238 bytes in revision 1
* subversion/include/private/svn_fs_fs_private.h,
subversion/libsvn_fs_fs/stats.c
(svn_fs_fs__get_rev_size,
rev_size_index_entry_cb,
rev_size_baton_t): New.
* subversion/svnfsfs/svnfsfs.h,
subversion/svnfsfs/stats-cmd.c
(subcommand__rev_size): New.
* subversion/svnfsfs/svnfsfs.c
(cmd_table): Add and document the 'rev-size' command.
--This line, and those below, will be ignored--
Index: subversion/include/private/svn_fs_fs_private.h
===================================================================
--- subversion/include/private/svn_fs_fs_private.h (revision 1855386)
+++ subversion/include/private/svn_fs_fs_private.h (working copy)
@@ -268,12 +268,21 @@ svn_fs_fs__get_stats(svn_fs_fs__stats_t
void *progress_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Set *REV_SIZE to the total size of objects belonging to revision REVISION
+ * in FS.
+ */
+svn_error_t *
+svn_fs_fs__get_rev_size(apr_off_t *rev_size,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool);
+
/* A node-revision ID in FSFS consists of 3 sub-IDs ("parts") that consist
* of a creation REVISION number and some revision- / transaction-local
* counter value (NUMBER). Old-style ID parts use global counter values.
*
* The parts are: node_id, copy_id and txn_id for in-txn IDs as well as
* node_id, copy_id and rev_item for in-revision IDs. This struct is the
Index: subversion/libsvn_fs_fs/stats.c
===================================================================
--- subversion/libsvn_fs_fs/stats.c (revision 1855386)
+++ subversion/libsvn_fs_fs/stats.c (working copy)
@@ -1394,6 +1394,43 @@ svn_fs_fs__get_stats(svn_fs_fs__stats_t
scratch_pool));
SVN_ERR(read_revisions(query, scratch_pool, scratch_pool));
aggregate_stats(query->revisions, *stats);
return SVN_NO_ERROR;
}
+
+struct rev_size_baton_t {
+ svn_revnum_t revision;
+ apr_off_t rev_size;
+};
+
+/* Implements svn_fs_fs__dump_index_func_t, summing object sizes for
+ * revision BATON->revision into BATON->rev_size.
+ */
+static svn_error_t *
+rev_size_index_entry_cb(const svn_fs_fs__p2l_entry_t *entry,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ struct rev_size_baton_t *b = baton;
+
+ if (entry->item.revision == b->revision)
+ b->rev_size += entry->size;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__get_rev_size(apr_off_t *rev_size,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool)
+{
+ struct rev_size_baton_t b;
+
+ b.revision = revision;
+ b.rev_size = 0;
+ SVN_ERR(svn_fs_fs__dump_index(fs, revision,
+ rev_size_index_entry_cb, &b,
+ NULL, NULL, scratch_pool));
+ *rev_size = b.rev_size;
+ return SVN_NO_ERROR;
+}
Index: subversion/svnfsfs/stats-cmd.c
===================================================================
--- subversion/svnfsfs/stats-cmd.c (revision 1855386)
+++ subversion/svnfsfs/stats-cmd.c (working copy)
@@ -509,6 +509,30 @@ subcommand__stats(apr_getopt_t *os, void
check_cancel, NULL, pool, pool));
print_stats(stats, pool);
return SVN_NO_ERROR;
}
+
+/* This implements `svn_opt_subcommand_t'. */
+svn_error_t *
+subcommand__rev_size(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ svnfsfs__opt_state *opt_state = baton;
+ svn_revnum_t revision;
+ apr_off_t rev_size;
+ svn_fs_t *fs;
+
+ if (opt_state->start_revision.kind != svn_opt_revision_number
+ || opt_state->end_revision.kind != svn_opt_revision_unspecified)
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Invalid revision specifier"));
+ revision = opt_state->start_revision.value.number;
+
+ SVN_ERR(open_fs(&fs, opt_state->repository_path, pool));
+ SVN_ERR(svn_fs_fs__get_rev_size(&rev_size, fs, revision, pool));
+
+ printf("%"APR_OFF_T_FMT" bytes in revision %ld\n",
+ rev_size, revision);
+
+ return SVN_NO_ERROR;
+}
Index: subversion/svnfsfs/svnfsfs.c
===================================================================
--- subversion/svnfsfs/svnfsfs.c (revision 1855386)
+++ subversion/svnfsfs/svnfsfs.c (working copy)
@@ -166,12 +166,20 @@ static const svn_opt_subcommand_desc3_t
"usage: svnfsfs stats REPOS_PATH\n"
"\n"), N_(
"Write object size statistics to console.\n"
)},
{'M'} },
+ {"rev-size", subcommand__rev_size, {0}, {N_(
+ "usage: svnfsfs rev-size REPOS_PATH -r REVISION\n"
+ "\n"), N_(
+ "Write to console the total size in bytes of the representation on disk of\n"
+ "revision REVISION, excluding its indexes.\n"
+ )},
+ {'r', 'M'} },
+
{ NULL, NULL, {0}, {NULL}, {0} }
};
svn_error_t *
open_fs(svn_fs_t **fs,
Index: subversion/svnfsfs/svnfsfs.h
===================================================================
--- subversion/svnfsfs/svnfsfs.h (revision 1855386)
+++ subversion/svnfsfs/svnfsfs.h (working copy)
@@ -49,13 +49,14 @@ typedef struct svnfsfs__opt_state
/* Declare all the command procedures */
svn_opt_subcommand_t
subcommand__help,
subcommand__dump_index,
subcommand__load_index,
- subcommand__stats;
+ subcommand__stats,
+ subcommand__rev_size;
/* Check that the filesystem at PATH is an FSFS repository and then open it.
* Return the filesystem in *FS, allocated in POOL. */
svn_error_t *
open_fs(svn_fs_t **fs,