Within the FSFS lib, switch directory representation from APR hash
to sorted APR array.  Since all directories get written to and read
from the cache, it is simply cheaper to use a similar container
outside the cache as we do in the cache serialized format.

To minimize parsing overhead, we write the directory entries in sorted
order to disk and skip sorting them in the reading code when we discover
that they are already properly ordered.  This is not only fully backward
compatible but also solves the hash ordering problem when deltifying
directories.

* subversion/include/private/svn_subr_private.h
  (svn_hash__entry_t,
   svn_hash__read_entry): New private API factored out from svn_hash_read2.
                          This allows us to read hashes as well as arrays
                          with little extra code.

* subversion/libsvn_subr/hash.c
  (svn_hash__read_entry): Implement using code taken from ...
  (hash_read): ... this function which is now much simpler.

* subversion/libsvn_fs_fs/cached_data.h
  (svn_fs_fs__rep_contents_dir): Return an array instead of a hash.
  (svn_fs_fs__find_dir_entry): New utility function since we can't use
                               hash lookup anymore on directories.

* subversion/libsvn_fs_fs/cached_data.c
  (sorted,
   compare_dirents,
   compare_dirent_name): New utility functions for sorting directories
                         and looking entries up.
  (read_dir_entries): New function to fully read (one pass) directories
                      and entries the data directly into svn_fs_dirent_t.
  (parse_dir_entries): Superseded by the above.
  (get_dir_contents): Call the new reader function and return an array
                      instead of a hash.
  (svn_fs_fs__rep_contents_dir): Update and simplify as no second parser
                                 stage is needed anymore.
  (svn_fs_fs__find_dir_entry): Implement.
  (svn_fs_fs__rep_contents_dir_entry): Update dir entry lookup.

* subversion/libsvn_fs_fs/transaction.c
  (unparse_dir_entry): Write a whole dirent directly to STREAM instead of
                       producing some intermediate string.
  (unparse_dir_entries): Write a whole directory to STREAM (implicitly in
                         sorted, stable order)
  (svn_fs_fs__set_entry): Simplify adapting to the new unparse_* code.
  (collection_writer_t,
   write_hash_to_stream,
   write_directory_to_stream): Callback functions that allow all container
                               types (hash, array, possibly others) to be
                               written in a uniform fashon.
  (write_hash_baton,
   write_hash_handler,
   write_hash_rep,
   write_hash_delta_rep): Rename to ...
  (write_container_baton,
   write_container_handler,
   write_container_rep,
   write_container_delta_rep): ... these and update the rep writers to
                               use the new collection_writer_t callback.
  (write_final_rev): Update caller and simplify code as the directory
                     order is already stable now.

* subversion/libsvn_fs_fs/temp_serializer.h
  (svn_fs_fs__serialize_dir_entries,
   svn_fs_fs__deserialize_dir_entries): Update docstrings to reflect the
                                        new directory container type.

* subversion/libsvn_fs_fs/temp_serializer.c
  (hash_data_t): Rename to ...
  (dir_data_t): ... this without any other change since the in-cache
                representation format remains unchanged.
  (compare_dirent_id_names): Drop obsolete function since the array
                             is already sorted.
  (serialize_dir,
   deserialize_dir): Switch from de-/serializing hashes to processing
                     already correctly ordered arrays.
  (return_serialized_dir_context,
   svn_fs_fs__serialize_dir_entries,
   svn_fs_fs__deserialize_dir_entries,
   svn_fs_fs__extract_dir_entry): Purely syntactically adapt to renames
                                  and changed types.
  (slowly_replace_dir_entry): Updating a sorted array is harder than
                              updating a hash.  Explicitly code the
                              different use-cases.
  (svn_fs_fs__replace_dir_entry): Purely syntactically adapt to renames
                                  and changed types.

* subversion/libsvn_fs_fs/dag.h
  (svn_fs_fs__dag_dir_entries): Return an array instead of a hash.

* subversion/libsvn_fs_fs/dag.c
  (svn_fs_fs__dag_dir_entries): Update and simplify as iteration over
                                arrays is straight-forward.

* subversion/libsvn_fs_fs/tree.c
  (merge): Keep the basic principle but instead of dir hash lookups
           use quasi-linear array scans; see svn_sort__array_lookup.
           Don't modify any one the directory arrays as that would
           be O(n^2).
  (fs_dir_entries): Convert the internal dir representation into the
                    FS API level hash.
  (crawl_directory_dag_for_mergeinfo,
   verify_node): Iterate over directory arrays instead of hashes.

git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@1554711 13f79535-47bb-0310-9956-ffa450edef68