Author: philip
Date: Tue Jul 31 11:19:15 2012
New Revision: 1367498
URL: http://svn.apache.org/viewvc?rev=1367498&view=rev
Log:
Make FSFS revision files independent of APR's hash order.
* subversion/libsvn_fs_fs/fs_fs.c
(write_final_rev, write_final_changed_path_info): Output in a stable order.
Modified:
subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1367498&r1=1367497&r2=1367498&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Tue Jul 31 11:19:15 2012
@@ -7367,16 +7367,23 @@ write_final_rev(const svn_fs_id_t **new_
{
apr_pool_t *subpool;
apr_hash_t *entries, *str_entries;
- apr_hash_index_t *hi;
+ apr_array_header_t *sorted_entries;
+ int i;
/* This is a directory. Write out all the children first. */
subpool = svn_pool_create(pool);
SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, noderev, pool));
-
- for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
+ /* For the sake of the repository administrator sort the entries
+ so that the final file is deterministic and repeatable,
+ however the rest of the FSFS code doesn't require any
+ particular order here. */
+ sorted_entries = svn_sort__hash(entries,
svn_sort_compare_items_lexically,
+ pool);
+ for (i = 0; i < sorted_entries->nelts; ++i)
{
- svn_fs_dirent_t *dirent = svn__apr_hash_index_val(hi);
+ svn_fs_dirent_t *dirent = APR_ARRAY_IDX(sorted_entries, i,
+ svn_sort__item_t).value;
svn_pool_clear(subpool);
SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
@@ -7546,19 +7553,25 @@ write_final_changed_path_info(apr_off_t
{
apr_hash_t *changed_paths;
apr_off_t offset;
- apr_hash_index_t *hi;
apr_pool_t *iterpool = svn_pool_create(pool);
fs_fs_data_t *ffd = fs->fsap_data;
svn_boolean_t include_node_kinds =
ffd->format >= SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT;
+ apr_array_header_t *sorted_changed_paths;
+ int i;
SVN_ERR(get_file_offset(&offset, file, pool));
SVN_ERR(svn_fs_fs__txn_changes_fetch(&changed_paths, fs, txn_id, pool));
+ /* For the sake of the repository administrator sort the changes so
+ that the final file is deterministic and repeatable, however the
+ rest of the FSFS code doesn't require any particular order here. */
+ sorted_changed_paths = svn_sort__hash(changed_paths,
+ svn_sort_compare_items_lexically,
pool);
/* Iterate through the changed paths one at a time, and convert the
temporary node-id into a permanent one for each change entry. */
- for (hi = apr_hash_first(pool, changed_paths); hi; hi = apr_hash_next(hi))
+ for (i = 0; i < sorted_changed_paths->nelts; ++i)
{
node_revision_t *noderev;
const svn_fs_id_t *id;
@@ -7567,8 +7580,8 @@ write_final_changed_path_info(apr_off_t
svn_pool_clear(iterpool);
- change = svn__apr_hash_index_val(hi);
- path = svn__apr_hash_index_key(hi);
+ change = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).value;
+ path = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).key;
id = change->node_rev_id;