Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_fs_fs/fs_fs.c view on Meta::CPAN
SVN_ERR(svn_stream_printf(tmp_stream, scratch_pool, "%ld\n", revnum));
SVN_ERR(svn_stream_close(tmp_stream));
SVN_ERR(move_into_place(tmp_path, final_path, final_path, scratch_pool));
return SVN_NO_ERROR;
}
/* Pack the revision SHARD containing exactly MAX_FILES_PER_DIR revisions
* from SHARD_PATH into the PACK_FILE_DIR, using POOL for allocations.
* CANCEL_FUNC and CANCEL_BATON are what you think they are.
*
* If for some reason we detect a partial packing already performed, we
* remove the pack file and start again.
*/
static svn_error_t *
pack_rev_shard(const char *pack_file_dir,
const char *shard_path,
apr_int64_t shard,
int max_files_per_dir,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
{
const char *pack_file_path, *manifest_file_path;
svn_stream_t *pack_stream, *manifest_stream;
svn_revnum_t start_rev, end_rev, rev;
apr_off_t next_offset;
apr_pool_t *iterpool;
/* Some useful paths. */
pack_file_path = svn_dirent_join(pack_file_dir, PATH_PACKED, pool);
manifest_file_path = svn_dirent_join(pack_file_dir, PATH_MANIFEST, pool);
/* Remove any existing pack file for this shard, since it is incomplete. */
SVN_ERR(svn_io_remove_dir2(pack_file_dir, TRUE, cancel_func, cancel_baton,
pool));
/* Create the new directory and pack and manifest files. */
SVN_ERR(svn_io_dir_make(pack_file_dir, APR_OS_DEFAULT, pool));
SVN_ERR(svn_stream_open_writable(&pack_stream, pack_file_path, pool,
pool));
SVN_ERR(svn_stream_open_writable(&manifest_stream, manifest_file_path,
pool, pool));
start_rev = (svn_revnum_t) (shard * max_files_per_dir);
end_rev = (svn_revnum_t) ((shard + 1) * (max_files_per_dir) - 1);
next_offset = 0;
iterpool = svn_pool_create(pool);
/* Iterate over the revisions in this shard, squashing them together. */
for (rev = start_rev; rev <= end_rev; rev++)
{
svn_stream_t *rev_stream;
apr_finfo_t finfo;
const char *path;
svn_pool_clear(iterpool);
/* Get the size of the file. */
path = svn_dirent_join(shard_path, apr_psprintf(iterpool, "%ld", rev),
iterpool);
SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, iterpool));
/* Update the manifest. */
SVN_ERR(svn_stream_printf(manifest_stream, iterpool, "%" APR_OFF_T_FMT
"\n", next_offset));
next_offset += finfo.size;
/* Copy all the bits from the rev file to the end of the pack file. */
SVN_ERR(svn_stream_open_readonly(&rev_stream, path, iterpool, iterpool));
SVN_ERR(svn_stream_copy3(rev_stream, svn_stream_disown(pack_stream,
iterpool),
cancel_func, cancel_baton, iterpool));
}
SVN_ERR(svn_stream_close(manifest_stream));
SVN_ERR(svn_stream_close(pack_stream));
SVN_ERR(svn_io_copy_perms(shard_path, pack_file_dir, iterpool));
SVN_ERR(svn_io_set_file_read_only(pack_file_path, FALSE, iterpool));
SVN_ERR(svn_io_set_file_read_only(manifest_file_path, FALSE, iterpool));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
/* Copy revprop files for revisions [START_REV, END_REV) from SHARD_PATH
* to the pack file at PACK_FILE_NAME in PACK_FILE_DIR.
*
* The file sizes have already been determined and written to SIZES.
* Please note that this function will be executed while the filesystem
* has been locked and that revprops files will therefore not be modified
* while the pack is in progress.
*
* COMPRESSION_LEVEL defines how well the resulting pack file shall be
* compressed or whether is shall be compressed at all. TOTAL_SIZE is
* a hint on which initial buffer size we should use to hold the pack file
* content.
*
* CANCEL_FUNC and CANCEL_BATON are used as usual. Temporary allocations
* are done in SCRATCH_POOL.
*/
static svn_error_t *
copy_revprops(const char *pack_file_dir,
const char *pack_filename,
const char *shard_path,
svn_revnum_t start_rev,
svn_revnum_t end_rev,
apr_array_header_t *sizes,
apr_size_t total_size,
int compression_level,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
svn_stream_t *pack_stream;
apr_file_t *pack_file;
svn_revnum_t rev;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
svn_stream_t *stream;
/* create empty data buffer and a write stream on top of it */
src/subversion/subversion/libsvn_fs_fs/fs_fs.c view on Meta::CPAN
* compressed or whether is shall be compressed at all. Individual pack
* file containing more than one revision will be limited to a size of
* MAX_PACK_SIZE bytes before compression.
*
* CANCEL_FUNC and CANCEL_BATON are used in the usual way. Temporary
* allocations are done in SCRATCH_POOL.
*/
static svn_error_t *
pack_revprops_shard(const char *pack_file_dir,
const char *shard_path,
apr_int64_t shard,
int max_files_per_dir,
apr_off_t max_pack_size,
int compression_level,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
const char *manifest_file_path, *pack_filename = NULL;
svn_stream_t *manifest_stream;
svn_revnum_t start_rev, end_rev, rev;
apr_off_t total_size;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_array_header_t *sizes;
/* Some useful paths. */
manifest_file_path = svn_dirent_join(pack_file_dir, PATH_MANIFEST,
scratch_pool);
/* Remove any existing pack file for this shard, since it is incomplete. */
SVN_ERR(svn_io_remove_dir2(pack_file_dir, TRUE, cancel_func, cancel_baton,
scratch_pool));
/* Create the new directory and manifest file stream. */
SVN_ERR(svn_io_dir_make(pack_file_dir, APR_OS_DEFAULT, scratch_pool));
SVN_ERR(svn_stream_open_writable(&manifest_stream, manifest_file_path,
scratch_pool, scratch_pool));
/* revisions to handle. Special case: revision 0 */
start_rev = (svn_revnum_t) (shard * max_files_per_dir);
end_rev = (svn_revnum_t) ((shard + 1) * (max_files_per_dir) - 1);
if (start_rev == 0)
++start_rev;
/* initialize the revprop size info */
sizes = apr_array_make(scratch_pool, max_files_per_dir, sizeof(apr_off_t));
total_size = 2 * SVN_INT64_BUFFER_SIZE;
/* Iterate over the revisions in this shard, determine their size and
* squashing them together into pack files. */
for (rev = start_rev; rev <= end_rev; rev++)
{
apr_finfo_t finfo;
const char *path;
svn_pool_clear(iterpool);
/* Get the size of the file. */
path = svn_dirent_join(shard_path, apr_psprintf(iterpool, "%ld", rev),
iterpool);
SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, iterpool));
/* if we already have started a pack file and this revprop cannot be
* appended to it, write the previous pack file. */
if (sizes->nelts != 0 &&
total_size + SVN_INT64_BUFFER_SIZE + finfo.size > max_pack_size)
{
SVN_ERR(copy_revprops(pack_file_dir, pack_filename, shard_path,
start_rev, rev-1, sizes, (apr_size_t)total_size,
compression_level, cancel_func, cancel_baton,
iterpool));
/* next pack file starts empty again */
apr_array_clear(sizes);
total_size = 2 * SVN_INT64_BUFFER_SIZE;
start_rev = rev;
}
/* Update the manifest. Allocate a file name for the current pack
* file if it is a new one */
if (sizes->nelts == 0)
pack_filename = apr_psprintf(scratch_pool, "%ld.0", rev);
SVN_ERR(svn_stream_printf(manifest_stream, iterpool, "%s\n",
pack_filename));
/* add to list of files to put into the current pack file */
APR_ARRAY_PUSH(sizes, apr_off_t) = finfo.size;
total_size += SVN_INT64_BUFFER_SIZE + finfo.size;
}
/* write the last pack file */
if (sizes->nelts != 0)
SVN_ERR(copy_revprops(pack_file_dir, pack_filename, shard_path,
start_rev, rev-1, sizes, (apr_size_t)total_size,
compression_level, cancel_func, cancel_baton,
iterpool));
/* flush the manifest file and update permissions */
SVN_ERR(svn_stream_close(manifest_stream));
SVN_ERR(svn_io_copy_perms(shard_path, pack_file_dir, iterpool));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
/* Delete the non-packed revprop SHARD at SHARD_PATH with exactly
* MAX_FILES_PER_DIR revprop files in it. If this is shard 0, keep the
* revprop file for revision 0.
*
* CANCEL_FUNC and CANCEL_BATON are used in the usual way. Temporary
* allocations are done in SCRATCH_POOL.
*/
static svn_error_t *
delete_revprops_shard(const char *shard_path,
apr_int64_t shard,
int max_files_per_dir,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *scratch_pool)
( run in 0.501 second using v1.01-cache-2.11-cpan-39bf76dae61 )