You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by iv...@apache.org on 2015/09/11 17:51:34 UTC

svn commit: r1702504 [11/19] - in /subversion/branches/reuse-ra-session: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ notes/ subversion/bindings/ctypes-python/csvn/ext/ subversion/bindings/javahl/native/ ...

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h Fri Sep 11 15:51:30 2015
@@ -20,10 +20,11 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS_TREE_H
-#define SVN_LIBSVN_FS_TREE_H
+#ifndef SVN_LIBSVN_FS_X_TREE_H
+#define SVN_LIBSVN_FS_X_TREE_H
 
 #include "fs.h"
+#include "dag.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -31,9 +32,13 @@ extern "C" {
 
 
 
-/* In RESULT_POOL, create an instance of a DAG node 1st level cache. */
-svn_fs_x__dag_cache_t*
-svn_fs_x__create_dag_cache(apr_pool_t *result_pool);
+/* Return the transaction ID to a given transaction ROOT. */
+svn_fs_x__txn_id_t
+svn_fs_x__root_txn_id(svn_fs_root_t *root);
+
+/* Return the change set to a given ROOT. */
+svn_fs_x__change_set_t
+svn_fs_x__root_change_set(svn_fs_root_t *root);
 
 /* Set *ROOT_P to the root directory of revision REV in filesystem FS.
    Allocate the structure in POOL. */
@@ -109,4 +114,4 @@ svn_fs_x__info_config_files(apr_array_he
 }
 #endif /* __cplusplus */
 
-#endif /* SVN_LIBSVN_FS_TREE_H */
+#endif /* SVN_LIBSVN_FS_X_TREE_H */

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c Fri Sep 11 15:51:30 2015
@@ -110,11 +110,24 @@ svn_fs_x__path_current(svn_fs_t *fs,
 }
 
 const char *
+svn_fs_x__path_next(svn_fs_t *fs,
+                       apr_pool_t *result_pool)
+{
+  return svn_dirent_join(fs->path, PATH_NEXT, result_pool);
+}
+
+const char *
 svn_fs_x__path_txn_current(svn_fs_t *fs,
                            apr_pool_t *result_pool)
 {
-  return svn_dirent_join(fs->path, PATH_TXN_CURRENT,
-                         result_pool);
+  return svn_dirent_join(fs->path, PATH_TXN_CURRENT, result_pool);
+}
+
+const char *
+svn_fs_x__path_txn_next(svn_fs_t *fs,
+                           apr_pool_t *result_pool)
+{
+  return svn_dirent_join(fs->path, PATH_TXN_NEXT, result_pool);
 }
 
 const char *
@@ -147,14 +160,12 @@ svn_fs_x__path_revprop_generation(svn_fs
 
 /* Return the full path of the file FILENAME within revision REV's shard in
  * FS.  If FILENAME is NULL, return the shard directory directory itself.
- * REVPROPS indicates the parent of the shard parent folder ("revprops" or
- * "revs").  PACKED says whether we want the packed shard's name.
+ * PACKED says whether we want the packed shard's name.
  *
  * Allocate the result in RESULT_POOL.
  */static const char*
 construct_shard_sub_path(svn_fs_t *fs,
                          svn_revnum_t rev,
-                         svn_boolean_t revprops,
                          svn_boolean_t packed,
                          const char *filename,
                          apr_pool_t *result_pool)
@@ -162,9 +173,6 @@ construct_shard_sub_path(svn_fs_t *fs,
   svn_fs_x__data_t *ffd = fs->fsap_data;
   char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_PACKED_SHARD)] = { 0 };
 
-  /* Select the appropriate parent path constant. */
-  const char *parent = revprops ? PATH_REVPROPS_DIR : PATH_REVS_DIR;
-
   /* String containing the shard number. */
   apr_size_t len = svn__i64toa(buffer, rev / ffd->max_files_per_dir);
 
@@ -173,7 +181,7 @@ construct_shard_sub_path(svn_fs_t *fs,
     strncpy(buffer + len, PATH_EXT_PACKED_SHARD, sizeof(buffer) - len - 1);
 
   /* This will also work for NULL FILENAME as well. */
-  return svn_dirent_join_many(result_pool, fs->path, parent, buffer,
+  return svn_dirent_join_many(result_pool, fs->path, PATH_REVS_DIR, buffer,
                               filename, SVN_VA_NULL);
 }
 
@@ -184,15 +192,15 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs,
                           apr_pool_t *result_pool)
 {
   assert(svn_fs_x__is_packed_rev(fs, rev));
-  return construct_shard_sub_path(fs, rev, FALSE, TRUE, kind, result_pool);
+  return construct_shard_sub_path(fs, rev, TRUE, kind, result_pool);
 }
 
 const char *
-svn_fs_x__path_rev_shard(svn_fs_t *fs,
-                         svn_revnum_t rev,
-                         apr_pool_t *result_pool)
+svn_fs_x__path_shard(svn_fs_t *fs,
+                     svn_revnum_t rev,
+                     apr_pool_t *result_pool)
 {
-  return construct_shard_sub_path(fs, rev, FALSE, FALSE, NULL, result_pool);
+  return construct_shard_sub_path(fs, rev, FALSE, NULL, result_pool);
 }
 
 const char *
@@ -200,11 +208,12 @@ svn_fs_x__path_rev(svn_fs_t *fs,
                    svn_revnum_t rev,
                    apr_pool_t *result_pool)
 {
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  svn__i64toa(buffer, rev);
+  char buffer[SVN_INT64_BUFFER_SIZE + 1];
+  buffer[0] = 'r';
+  svn__i64toa(buffer + 1, rev);
 
   assert(! svn_fs_x__is_packed_rev(fs, rev));
-  return construct_shard_sub_path(fs, rev, FALSE, FALSE, buffer, result_pool);
+  return construct_shard_sub_path(fs, rev, FALSE, buffer, result_pool);
 }
 
 const char *
@@ -218,19 +227,11 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs
 }
 
 const char *
-svn_fs_x__path_revprops_shard(svn_fs_t *fs,
-                              svn_revnum_t rev,
-                              apr_pool_t *result_pool)
-{
-  return construct_shard_sub_path(fs, rev, TRUE, FALSE, NULL, result_pool);
-}
-
-const char *
-svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
+svn_fs_x__path_pack_shard(svn_fs_t *fs,
                                    svn_revnum_t rev,
                                    apr_pool_t *result_pool)
 {
-  return construct_shard_sub_path(fs, rev, TRUE, TRUE, NULL, result_pool);
+  return construct_shard_sub_path(fs, rev, TRUE, NULL, result_pool);
 }
 
 const char *
@@ -238,11 +239,17 @@ svn_fs_x__path_revprops(svn_fs_t *fs,
                         svn_revnum_t rev,
                         apr_pool_t *result_pool)
 {
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  svn__i64toa(buffer, rev);
+  char buffer[SVN_INT64_BUFFER_SIZE + 1];
+  buffer[0] = 'p';
+  svn__i64toa(buffer + 1, rev);
 
   assert(! svn_fs_x__is_packed_revprop(fs, rev));
-  return construct_shard_sub_path(fs, rev, TRUE, FALSE, buffer, result_pool);
+
+  /* Revprops for packed r0 are not packed, yet stored in the packed shard.
+     Hence, the second flag must check for packed _rev_ - not revprop. */
+  return construct_shard_sub_path(fs, rev,
+                                  svn_fs_x__is_packed_rev(fs, rev) /* sic! */,
+                                  buffer, result_pool);
 }
 
 const char *
@@ -340,14 +347,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
   return construct_txn_path(fs, txn_id, PATH_TXN_PROPS, result_pool);
 }
 
-const char *
-svn_fs_x__path_txn_props_final(svn_fs_t *fs,
-                               svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *result_pool)
-{
-  return construct_txn_path(fs, txn_id, PATH_TXN_PROPS_FINAL, result_pool);
-}
-
 const char*
 svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
@@ -583,15 +582,20 @@ svn_fs_x__write_current(svn_fs_t *fs,
 {
   char *buf;
   const char *tmp_name, *name;
+  apr_file_t *file;
 
   /* Now we can just write out this line. */
   buf = apr_psprintf(scratch_pool, "%ld\n", rev);
 
   name = svn_fs_x__path_current(fs, scratch_pool);
-  SVN_ERR(svn_io_write_unique(&tmp_name,
-                              svn_dirent_dirname(name, scratch_pool),
-                              buf, strlen(buf),
-                              svn_io_file_del_none, scratch_pool));
+  tmp_name = svn_fs_x__path_next(fs, scratch_pool);
+
+  SVN_ERR(svn_io_file_open(&file, tmp_name,
+                           APR_WRITE | APR_CREATE | APR_BUFFERED,
+                           APR_OS_DEFAULT, scratch_pool));
+  SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL,
+                                 scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   return svn_fs_x__move_into_place(tmp_name, name, name, scratch_pool);
 }
@@ -730,7 +734,7 @@ svn_fs_x__move_into_place(const char *ol
   SVN_ERR(svn_io_copy_perms(perms_reference, old_filename, scratch_pool));
 
   /* Move the file into place. */
-  err = svn_io_file_rename(old_filename, new_filename, scratch_pool);
+  err = svn_io_file_rename2(old_filename, new_filename, FALSE, scratch_pool);
   if (err && APR_STATUS_IS_EXDEV(err->apr_err))
     {
       apr_file_t *file;

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h Fri Sep 11 15:51:30 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__UTIL_H
-#define SVN_LIBSVN_FS__UTIL_H
+#ifndef SVN_LIBSVN_FS_X_UTIL_H
+#define SVN_LIBSVN_FS_X_UTIL_H
 
 #include "svn_fs.h"
 #include "id.h"
@@ -102,6 +102,12 @@ const char *
 svn_fs_x__path_current(svn_fs_t *fs,
                        apr_pool_t *result_pool);
 
+/* Return the path to the 'next' file in FS.
+   Perform allocation in RESULT_POOL. */
+const char *
+svn_fs_x__path_next(svn_fs_t *fs,
+                    apr_pool_t *result_pool);
+
 /* Return the full path of the "uuid" file in FS.
  * The result will be allocated in RESULT_POOL.
  */
@@ -116,6 +122,13 @@ const char *
 svn_fs_x__path_txn_current(svn_fs_t *fs,
                            apr_pool_t *result_pool);
 
+/* Return the full path of the "txn-next" file in FS.
+ * The result will be allocated in RESULT_POOL.
+ */
+const char *
+svn_fs_x__path_txn_next(svn_fs_t *fs,
+                        apr_pool_t *result_pool);
+
 /* Return the full path of the "txn-current-lock" file in FS.
  * The result will be allocated in RESULT_POOL.
  */
@@ -158,9 +171,9 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs,
  * revision REV in FS.  Allocate the result in RESULT_POOL.
  */
 const char *
-svn_fs_x__path_rev_shard(svn_fs_t *fs,
-                         svn_revnum_t rev,
-                         apr_pool_t *result_pool);
+svn_fs_x__path_shard(svn_fs_t *fs,
+                     svn_revnum_t rev,
+                     apr_pool_t *result_pool);
 
 /* Return the full path of the non-packed rev file containing revision REV
  * in FS.  Allocate the result in RESULT_POOL.
@@ -183,23 +196,13 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs
                             svn_revnum_t rev,
                             apr_pool_t *result_pool);
 
-/* Return the full path of the revision properties shard directory that
- * will contain the properties of revision REV in FS.
- * Allocate the result in RESULT_POOL.
- */
-const char *
-svn_fs_x__path_revprops_shard(svn_fs_t *fs,
-                              svn_revnum_t rev,
-                              apr_pool_t *result_pool);
-
-/* Return the full path of the revision properties pack shard directory
- * that will contain the packed properties of revision REV in FS.
- * Allocate the result in RESULT_POOL.
+/* Return the full path of the pack shard directory that will contain the
+ * packed revision REV in FS.  Allocate the result in RESULT_POOL.
  */
 const char *
-svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
-                                   svn_revnum_t rev,
-                                   apr_pool_t *result_pool);
+svn_fs_x__path_pack_shard(svn_fs_t *fs,
+                          svn_revnum_t rev,
+                          apr_pool_t *result_pool);
 
 /* Return the full path of the non-packed revision properties file that
  * contains the props for revision REV in FS.
@@ -287,15 +290,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
                          svn_fs_x__txn_id_t txn_id,
                          apr_pool_t *result_pool);
 
-/* Return the path of the file containing the "final" transaction
- * properties for the transaction identified by TXN_ID in FS.
- * The result will be allocated in RESULT_POOL.
- */
-const char *
-svn_fs_x__path_txn_props_final(svn_fs_t *fs,
-                               svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *result_pool);
-
 /* Return the path of the file containing the node and copy ID counters for
  * the transaction identified by TXN_ID in FS.
  * The result will be allocated in RESULT_POOL.

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c Fri Sep 11 15:51:30 2015
@@ -141,30 +141,27 @@ verify_rep_cache(svn_fs_t *fs,
  * indedx NAME in the error message.  Supports cancellation with CANCEL_FUNC
  * and CANCEL_BATON.  SCRATCH_POOL is for temporary allocations. */
 static svn_error_t *
-verify_index_checksum(apr_file_t *file,
+verify_index_checksum(svn_fs_x__revision_file_t *file,
                       const char *name,
-                      apr_off_t start,
-                      apr_off_t end,
-                      svn_checksum_t *expected,
+                      svn_fs_x__index_info_t *index_info,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
                       apr_pool_t *scratch_pool)
 {
   unsigned char buffer[SVN__STREAM_CHUNK_SIZE];
-  apr_off_t size = end - start;
+  apr_off_t size = index_info->end - index_info->start;
   svn_checksum_t *actual;
   svn_checksum_ctx_t *context
     = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
 
   /* Calculate the index checksum. */
-  SVN_ERR(svn_io_file_seek(file, APR_SET, &start, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(file, NULL, index_info->start));
   while (size > 0)
     {
       apr_size_t to_read = size > sizeof(buffer)
                          ? sizeof(buffer)
                          : (apr_size_t)size;
-      SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL,
-                                     scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read));
       SVN_ERR(svn_checksum_update(context, buffer, to_read));
       size -= to_read;
 
@@ -175,12 +172,13 @@ verify_index_checksum(apr_file_t *file,
   SVN_ERR(svn_checksum_final(&actual, context, scratch_pool));
 
   /* Verify that it matches the expected checksum. */
-  if (!svn_checksum_match(expected, actual))
+  if (!svn_checksum_match(index_info->checksum, actual))
     {
       const char *file_name;
 
-      SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
-      SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool,
+      SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
+      SVN_ERR(svn_checksum_mismatch_err(index_info->checksum, actual,
+                                        scratch_pool, 
                                         _("%s checksum mismatch in file %s"),
                                         name, file_name));
     }
@@ -201,20 +199,18 @@ verify_index_checksums(svn_fs_t *fs,
                        apr_pool_t *scratch_pool)
 {
   svn_fs_x__revision_file_t *rev_file;
+  svn_fs_x__index_info_t l2p_index_info;
+  svn_fs_x__index_info_t p2l_index_info;
 
   /* Open the rev / pack file and read the footer */
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start,
-                                          scratch_pool, scratch_pool));
-  SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
+  SVN_ERR(svn_fs_x__rev_file_p2l_info(&p2l_index_info, rev_file));
 
   /* Verify the index contents against the checksum from the footer. */
-  SVN_ERR(verify_index_checksum(rev_file->file, "L2P index",
-                                rev_file->l2p_offset, rev_file->p2l_offset,
-                                rev_file->l2p_checksum,
+  SVN_ERR(verify_index_checksum(rev_file, "L2P index", &l2p_index_info,
                                 cancel_func, cancel_baton, scratch_pool));
-  SVN_ERR(verify_index_checksum(rev_file->file, "P2L index",
-                                rev_file->p2l_offset, rev_file->footer_offset,
-                                rev_file->p2l_checksum,
+  SVN_ERR(verify_index_checksum(rev_file, "P2L index", &p2l_index_info,
                                 cancel_func, cancel_baton, scratch_pool));
 
   /* Done. */
@@ -242,8 +238,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
 
   /* common file access structure */
   svn_fs_x__revision_file_t *rev_file;
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
-                                          iterpool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
 
   /* determine the range of items to check for each revision */
   SVN_ERR(svn_fs_x__l2p_get_max_ids(&max_ids, fs, start, count, scratch_pool,
@@ -334,8 +329,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
 
   /* common file access structure */
   svn_fs_x__revision_file_t *rev_file;
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
-                                          iterpool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
 
   /* get the size of the rev / pack file as covered by the P2L index */
   SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start,
@@ -424,7 +418,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
  * exceed STREAM_THRESHOLD.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-expect_buffer_nul(apr_file_t *file,
+expect_buffer_nul(svn_fs_x__revision_file_t *file,
                   apr_off_t size,
                   apr_pool_t *scratch_pool)
 {
@@ -439,8 +433,7 @@ expect_buffer_nul(apr_file_t *file,
 
   /* read the whole data block; error out on failure */
   data.chunks[(size - 1)/ sizeof(apr_uint64_t)] = 0;
-  SVN_ERR(svn_io_file_read_full2(file, data.buffer, size, NULL, NULL,
-                                 scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_read(file, data.buffer, size));
 
   /* chunky check */
   for (i = 0; i < size / sizeof(apr_uint64_t); ++i)
@@ -454,8 +447,8 @@ expect_buffer_nul(apr_file_t *file,
         const char *file_name;
         apr_off_t offset;
 
-        SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
-        SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+        SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
+        SVN_ERR(svn_fs_x__rev_file_offset(&offset, file));
         offset -= size - i;
 
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
@@ -472,7 +465,7 @@ expect_buffer_nul(apr_file_t *file,
  * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-read_all_nul(apr_file_t *file,
+read_all_nul(svn_fs_x__revision_file_t *file,
              apr_off_t size,
              apr_pool_t *scratch_pool)
 {
@@ -490,7 +483,7 @@ read_all_nul(apr_file_t *file,
  * in error message.  Allocate temporary data in SCRATCH_POOL.
  */
 static svn_error_t *
-expected_checksum(apr_file_t *file,
+expected_checksum(svn_fs_x__revision_file_t *file,
                   svn_fs_x__p2l_entry_t *entry,
                   apr_uint32_t actual,
                   apr_pool_t *scratch_pool)
@@ -499,8 +492,7 @@ expected_checksum(apr_file_t *file,
     {
       const char *file_name;
 
-      SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
-      SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
       return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                _("Checksum mismatch in item at offset %s of "
                                  "length %s bytes in file %s"),
@@ -517,15 +509,14 @@ expected_checksum(apr_file_t *file,
  * exceed STREAM_THRESHOLD.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-expected_buffered_checksum(apr_file_t *file,
+expected_buffered_checksum(svn_fs_x__revision_file_t *file,
                            svn_fs_x__p2l_entry_t *entry,
                            apr_pool_t *scratch_pool)
 {
   unsigned char buffer[STREAM_THRESHOLD];
   SVN_ERR_ASSERT(entry->size <= STREAM_THRESHOLD);
 
-  SVN_ERR(svn_io_file_read_full2(file, buffer, (apr_size_t)entry->size,
-                                 NULL, NULL, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_read(file, buffer, (apr_size_t)entry->size));
   SVN_ERR(expected_checksum(file, entry,
                             svn__fnv1a_32x4(buffer, (apr_size_t)entry->size),
                             scratch_pool));
@@ -538,7 +529,7 @@ expected_buffered_checksum(apr_file_t *f
  * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-expected_streamed_checksum(apr_file_t *file,
+expected_streamed_checksum(svn_fs_x__revision_file_t *file,
                            svn_fs_x__p2l_entry_t *entry,
                            apr_pool_t *scratch_pool)
 {
@@ -553,8 +544,7 @@ expected_streamed_checksum(apr_file_t *f
       apr_size_t to_read = size > sizeof(buffer)
                          ? sizeof(buffer)
                          : (apr_size_t)size;
-      SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL,
-                                     scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read));
       SVN_ERR(svn_checksum_update(context, buffer, to_read));
       size -= to_read;
     }
@@ -588,28 +578,27 @@ compare_p2l_to_rev(svn_fs_t *fs,
   apr_off_t max_offset;
   apr_off_t offset = 0;
   svn_fs_x__revision_file_t *rev_file;
+  svn_fs_x__index_info_t l2p_index_info;
 
   /* open the pack / rev file that is covered by the p2l index */
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
-                                          iterpool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
 
   /* check file size vs. range covered by index */
-  SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+  SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
   SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start,
                                        scratch_pool));
 
-  if (rev_file->l2p_offset != max_offset)
+  if (l2p_index_info.start != max_offset)
     return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL,
                              _("File size of %s for revision r%ld does "
                                "not match p2l index size of %s"),
                              apr_off_t_toa(scratch_pool,
-                                           rev_file->l2p_offset),
+                                           l2p_index_info.start),
                              start,
                              apr_off_t_toa(scratch_pool,
                                            max_offset));
 
-  SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, NULL, 0,
-                                   scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, 0));
 
   /* for all offsets in the file, get the P2L index entries and check
      them against the L2P index */
@@ -627,8 +616,7 @@ compare_p2l_to_rev(svn_fs_t *fs,
 
       /* The above might have moved the file pointer.
        * Ensure we actually start reading at OFFSET.  */
-      SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size,
-                                       NULL, offset, iterpool));
+      SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset));
 
       /* process all entries (and later continue with the next block) */
       for (i = 0; i < entries->nelts; ++i)
@@ -661,15 +649,15 @@ compare_p2l_to_rev(svn_fs_t *fs,
             {
               /* skip filler entry at the end of the p2l index */
               if (entry->offset != max_offset)
-                SVN_ERR(read_all_nul(rev_file->file, entry->size, iterpool));
+                SVN_ERR(read_all_nul(rev_file, entry->size, iterpool));
             }
           else
             {
               if (entry->size < STREAM_THRESHOLD)
-                SVN_ERR(expected_buffered_checksum(rev_file->file, entry,
+                SVN_ERR(expected_buffered_checksum(rev_file, entry,
                                                    iterpool));
               else
-                SVN_ERR(expected_streamed_checksum(rev_file->file, entry,
+                SVN_ERR(expected_streamed_checksum(rev_file, entry,
                                                    iterpool));
             }
 

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h Fri Sep 11 15:51:30 2015
@@ -1,4 +1,4 @@
-/* verify.h : verification interface of the native filesystem layer
+/* verify.h : verification interface of the FSX filesystem
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__VERIFY_H
-#define SVN_LIBSVN_FS__VERIFY_H
+#ifndef SVN_LIBSVN_FS_X_VERIFY_H
+#define SVN_LIBSVN_FS_X_VERIFY_H
 
 #include "fs.h"
 

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c Fri Sep 11 15:51:30 2015
@@ -355,19 +355,16 @@ load_config(svn_ra_serf__session_t *sess
   session->timeout = apr_time_from_sec(DEFAULT_HTTP_TIMEOUT);
   if (timeout_str)
     {
-      char *endstr;
-      const long int timeout = strtol(timeout_str, &endstr, 10);
-
-      if (*endstr)
-        return svn_error_create(SVN_ERR_BAD_CONFIG_VALUE, NULL,
-                                _("Invalid config: illegal character in "
-                                  "timeout value"));
-      if (timeout < 0)
-        return svn_error_create(SVN_ERR_BAD_CONFIG_VALUE, NULL,
-                                _("Invalid config: negative timeout value"));
+      apr_int64_t timeout;
+      svn_error_t *err;
+      
+      err = svn_cstring_strtoi64(&timeout, timeout_str, 0, APR_INT64_MAX, 10);
+      if (err)
+        return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, err,
+                                _("invalid config: bad value for '%s' option"),
+                                SVN_CONFIG_OPTION_HTTP_TIMEOUT);
       session->timeout = apr_time_from_sec(timeout);
     }
-  SVN_ERR_ASSERT(session->timeout >= 0);
 
   /* Convert the proxy port value, if any. */
   if (port_str)
@@ -445,12 +442,13 @@ load_config(svn_ra_serf__session_t *sess
 #undef DEFAULT_HTTP_TIMEOUT
 
 static void
-svn_ra_serf__progress(void *progress_baton, apr_off_t read, apr_off_t written)
+svn_ra_serf__progress(void *progress_baton, apr_off_t bytes_read,
+                      apr_off_t bytes_written)
 {
   const svn_ra_serf__session_t *serf_sess = progress_baton;
   if (serf_sess->progress_func)
     {
-      serf_sess->progress_func(read + written, -1,
+      serf_sess->progress_func(bytes_read + bytes_written, -1,
                                serf_sess->progress_baton,
                                serf_sess->pool);
     }

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c Fri Sep 11 15:51:30 2015
@@ -1129,7 +1129,15 @@ handle_fetch(serf_request_t *request,
           /* Validate the delta base claimed by the server matches
              what we asked for! */
           val = serf_bucket_headers_get(hdrs, SVN_DAV_DELTA_BASE_HEADER);
-          if (val && (strcmp(val, fetch_ctx->delta_base) != 0))
+          if (val && fetch_ctx->delta_base == NULL)
+            {
+              /* We recieved response with delta base header while we didn't
+                 requested it -- report it as error. */
+              return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                                       _("GET request returned unexpected "
+                                         "delta base: %s"), val);
+            }
+          else if (val && (strcmp(val, fetch_ctx->delta_base) != 0))
             {
               return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                        _("GET request returned unexpected "

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c Fri Sep 11 15:51:30 2015
@@ -65,7 +65,9 @@ ssl_convert_serf_failures(int failures)
   apr_uint32_t svn_failures = 0;
   apr_size_t i;
 
-  for (i = 0; i < sizeof(serf_failure_map) / (2 * sizeof(apr_uint32_t)); ++i)
+  for (i = 0;
+       i < sizeof(serf_failure_map) / (sizeof(serf_failure_map[0]));
+       ++i)
     {
       if (failures & serf_failure_map[i][0])
         {

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c Fri Sep 11 15:51:30 2015
@@ -187,7 +187,7 @@ static svn_error_t *make_connection(cons
 
 /* Set *DIFFS to an array of svn_prop_t, allocated in POOL, based on the
    property diffs in LIST, received from the server. */
-static svn_error_t *parse_prop_diffs(const apr_array_header_t *list,
+static svn_error_t *parse_prop_diffs(const svn_ra_svn__list_t *list,
                                      apr_pool_t *pool,
                                      apr_array_header_t **diffs)
 {
@@ -198,21 +198,22 @@ static svn_error_t *parse_prop_diffs(con
   for (i = 0; i < list->nelts; i++)
     {
       svn_prop_t *prop;
-      svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t);
+      svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(list, i);
 
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Prop diffs element not a list"));
       prop = apr_array_push(*diffs);
-      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "c(?s)", &prop->name,
-                                      &prop->value));
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "c(?s)",
+                                      &prop->name, &prop->value));
     }
   return SVN_NO_ERROR;
 }
 
 /* Parse a lockdesc, provided in LIST as specified by the protocol into
    LOCK, allocated in POOL. */
-static svn_error_t *parse_lock(const apr_array_header_t *list, apr_pool_t *pool,
+static svn_error_t *parse_lock(const svn_ra_svn__list_t *list,
+                               apr_pool_t *pool,
                                svn_lock_t **lock)
 {
   const char *cdate, *edate;
@@ -240,7 +241,7 @@ static svn_error_t *handle_auth_request(
                                         apr_pool_t *pool)
 {
   svn_ra_svn_conn_t *conn = sess->conn;
-  apr_array_header_t *mechlist;
+  svn_ra_svn__list_t *mechlist;
   const char *realm;
 
   SVN_ERR(svn_ra_svn__read_cmd_response(conn, pool, "lc", &mechlist, &realm));
@@ -624,7 +625,7 @@ static svn_error_t *open_session(svn_ra_
   svn_ra_svn_conn_t *conn;
   apr_socket_t *sock;
   apr_uint64_t minver, maxver;
-  apr_array_header_t *mechlist, *server_caplist, *repos_caplist;
+  svn_ra_svn__list_t *mechlist, *server_caplist, *repos_caplist;
   const char *client_string = NULL;
   apr_pool_t *pool = result_pool;
 
@@ -726,7 +727,7 @@ static svn_error_t *open_session(svn_ra_
     return svn_error_createf(SVN_ERR_RA_SVN_BAD_VERSION, NULL,
                              _("Server only supports versions up to %d"),
                              (int) maxver);
-  SVN_ERR(svn_ra_svn_set_capabilities(conn, server_caplist));
+  SVN_ERR(svn_ra_svn__set_capabilities(conn, server_caplist));
 
   /* All released versions of Subversion support edit-pipeline,
    * so we do not support servers that do not. */
@@ -759,7 +760,7 @@ static svn_error_t *open_session(svn_ra_
   SVN_ERR(svn_ra_svn__read_cmd_response(conn, pool, "c?c?l", &conn->uuid,
                                         &conn->repos_root, &repos_caplist));
   if (repos_caplist)
-    SVN_ERR(svn_ra_svn_set_capabilities(conn, repos_caplist));
+    SVN_ERR(svn_ra_svn__set_capabilities(conn, repos_caplist));
 
   if (conn->repos_root)
     {
@@ -1032,7 +1033,7 @@ static svn_error_t *ra_svn_rev_proplist(
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
-  apr_array_header_t *proplist;
+  svn_ra_svn__list_t *proplist;
 
   SVN_ERR(svn_ra_svn__write_cmd_rev_proplist(conn, pool, rev));
   SVN_ERR(handle_auth_request(sess_baton, pool));
@@ -1179,12 +1180,12 @@ static svn_error_t *ra_svn_commit(svn_ra
   return SVN_NO_ERROR;
 }
 
-/* Parse IPROPLIST, an array of svn_ra_svn_item_t structures, as a list of
+/* Parse IPROPLIST, an array of svn_ra_svn__item_t structures, as a list of
    const char * repos relative paths and properties for those paths, storing
    the result as an array of svn_prop_inherited_item_t *items. */
 static svn_error_t *
 parse_iproplist(apr_array_header_t **inherited_props,
-                const apr_array_header_t *iproplist,
+                const svn_ra_svn__list_t *iproplist,
                 svn_ra_session_t *session,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
@@ -1213,14 +1214,13 @@ parse_iproplist(apr_array_header_t **inh
 
   for (i = 0; i < iproplist->nelts; i++)
     {
-      apr_array_header_t *iprop_list;
+      svn_ra_svn__list_t *iprop_list;
       char *parent_rel_path;
       apr_hash_t *iprops;
       apr_hash_index_t *hi;
       svn_prop_inherited_item_t *new_iprop =
         apr_palloc(result_pool, sizeof(*new_iprop));
-      svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(iproplist, i,
-                                              svn_ra_svn_item_t);
+      svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(iproplist, i);
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(
           SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -1228,7 +1228,7 @@ parse_iproplist(apr_array_header_t **inh
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool, "cl",
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, iterpool, "cl",
                                       &parent_rel_path, &iprop_list));
       SVN_ERR(svn_ra_svn__parse_proplist(iprop_list, iterpool, &iprops));
       new_iprop->path_or_url = svn_path_url_add_component2(repos_root_url,
@@ -1260,7 +1260,7 @@ static svn_error_t *ra_svn_get_file(svn_
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
-  apr_array_header_t *proplist;
+  svn_ra_svn__list_t *proplist;
   const char *expected_digest;
   svn_checksum_t *expected_checksum = NULL;
   svn_checksum_ctx_t *checksum_ctx;
@@ -1293,22 +1293,22 @@ static svn_error_t *ra_svn_get_file(svn_
   iterpool = svn_pool_create(pool);
   while (1)
     {
-      svn_ra_svn_item_t *item;
+      svn_ra_svn__item_t *item;
 
       svn_pool_clear(iterpool);
       SVN_ERR(svn_ra_svn__read_item(conn, iterpool, &item));
       if (item->kind != SVN_RA_SVN_STRING)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Non-string as part of file contents"));
-      if (item->u.string->len == 0)
+      if (item->u.string.len == 0)
         break;
 
       if (expected_checksum)
-        SVN_ERR(svn_checksum_update(checksum_ctx, item->u.string->data,
-                                    item->u.string->len));
+        SVN_ERR(svn_checksum_update(checksum_ctx, item->u.string.data,
+                                    item->u.string.len));
 
-      SVN_ERR(svn_stream_write(stream, item->u.string->data,
-                               &item->u.string->len));
+      SVN_ERR(svn_stream_write(stream, item->u.string.data,
+                               &item->u.string.len));
     }
   svn_pool_destroy(iterpool);
 
@@ -1339,7 +1339,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
-  apr_array_header_t *proplist, *dirlist;
+  svn_ra_svn__list_t *proplist, *dirlist;
   int i;
 
   SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(c(?r)bb(!", "get-dir", path,
@@ -1384,12 +1384,12 @@ static svn_error_t *ra_svn_get_dir(svn_r
       svn_dirent_t *dirent;
       apr_uint64_t size;
       svn_revnum_t crev;
-      svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(dirlist, i, svn_ra_svn_item_t);
+      svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(dirlist, i);
 
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Dirlist element not a list"));
-      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cwnbr(?c)(?c)",
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "cwnbr(?c)(?c)",
                                       &name, &kind, &size, &has_props,
                                       &crev, &cdate, &cauthor));
 
@@ -1451,8 +1451,8 @@ static svn_error_t *ra_svn_get_mergeinfo
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
   int i;
-  apr_array_header_t *mergeinfo_tuple;
-  svn_ra_svn_item_t *elt;
+  svn_ra_svn__list_t *mergeinfo_tuple;
+  svn_ra_svn__item_t *elt;
   const char *path;
 
   SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "get-mergeinfo"));
@@ -1477,11 +1477,11 @@ static svn_error_t *ra_svn_get_mergeinfo
           svn_mergeinfo_t for_path;
           const char *to_parse;
 
-          elt = &((svn_ra_svn_item_t *) mergeinfo_tuple->elts)[i];
+          elt = &SVN_RA_SVN__LIST_ITEM(mergeinfo_tuple, i);
           if (elt->kind != SVN_RA_SVN_LIST)
             return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                     _("Mergeinfo element is not a list"));
-          SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cc",
+          SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "cc",
                                           &path, &to_parse));
           SVN_ERR(svn_mergeinfo_parse(&for_path, to_parse, pool));
           /* Correct for naughty servers that send "relative" paths
@@ -1684,12 +1684,12 @@ perform_ra_svn_log(svn_error_t **outer_e
       apr_uint64_t has_children_param, invalid_revnum_param;
       apr_uint64_t has_subtractive_merge_param;
       svn_string_t *author, *date, *message;
-      apr_array_header_t *cplist, *rplist;
+      svn_ra_svn__list_t *cplist, *rplist;
       svn_log_entry_t *log_entry;
       svn_boolean_t has_children;
       svn_boolean_t subtractive_merge = FALSE;
       apr_uint64_t revprop_count;
-      svn_ra_svn_item_t *item;
+      svn_ra_svn__item_t *item;
       apr_hash_t *cphash;
       svn_revnum_t rev;
 
@@ -1700,7 +1700,7 @@ perform_ra_svn_log(svn_error_t **outer_e
       if (item->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Log entry not a list"));
-      SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, iterpool,
+      SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, iterpool,
                                       "lr(?s)(?s)(?s)?BBnl?B",
                                       &cplist, &rev, &author, &date,
                                       &message, &has_children_param,
@@ -1742,13 +1742,12 @@ perform_ra_svn_log(svn_error_t **outer_e
               const char *copy_path, *action, *kind_str;
               apr_uint64_t text_mods, prop_mods;
               svn_revnum_t copy_rev;
-              svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(cplist, i,
-                                                      svn_ra_svn_item_t);
+              svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(cplist, i);
 
               if (elt->kind != SVN_RA_SVN_LIST)
                 return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                         _("Changed-path entry not a list"));
-              SVN_ERR(svn_ra_svn__read_data_log_changed_entry(elt->u.list,
+              SVN_ERR(svn_ra_svn__read_data_log_changed_entry(&elt->u.list,
                                               &cpath, &action, &copy_path,
                                               &copy_rev, &kind_str,
                                               &text_mods, &prop_mods));
@@ -1897,7 +1896,7 @@ static svn_error_t *ra_svn_stat(svn_ra_s
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
-  apr_array_header_t *list = NULL;
+  svn_ra_svn__list_t *list = NULL;
   svn_dirent_t *the_dirent;
 
   SVN_ERR(svn_ra_svn__write_cmd_stat(conn, pool, path, rev));
@@ -1968,7 +1967,7 @@ static svn_error_t *ra_svn_get_locations
   *locations = apr_hash_make(pool);
   while (!is_done)
     {
-      svn_ra_svn_item_t *item;
+      svn_ra_svn__item_t *item;
       const char *ret_path;
 
       SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
@@ -1979,7 +1978,7 @@ static svn_error_t *ra_svn_get_locations
                                 _("Location entry not a list"));
       else
         {
-          SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, pool, "rc",
+          SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, pool, "rc",
                                           &revision, &ret_path));
           ret_path = svn_fspath__canonicalize(ret_path, pool);
           apr_hash_set(*locations, apr_pmemdup(pool, &revision,
@@ -2024,7 +2023,7 @@ perform_get_location_segments(svn_error_
   while (!is_done)
     {
       svn_revnum_t range_start, range_end;
-      svn_ra_svn_item_t *item;
+      svn_ra_svn__item_t *item;
       const char *ret_path;
 
       svn_pool_clear(iterpool);
@@ -2038,7 +2037,7 @@ perform_get_location_segments(svn_error_
         {
           svn_location_segment_t *segment = apr_pcalloc(iterpool,
                                                         sizeof(*segment));
-          SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, iterpool, "rr(?c)",
+          SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, iterpool, "rr(?c)",
                                           &range_start, &range_end, &ret_path));
           if (! (SVN_IS_VALID_REVNUM(range_start)
                  && SVN_IS_VALID_REVNUM(range_end)))
@@ -2118,10 +2117,10 @@ static svn_error_t *ra_svn_get_file_revs
 
   while (1)
     {
-      apr_array_header_t *rev_proplist, *proplist;
+      svn_ra_svn__list_t *rev_proplist, *proplist;
       apr_uint64_t merged_rev_param;
       apr_array_header_t *props;
-      svn_ra_svn_item_t *item;
+      svn_ra_svn__item_t *item;
       apr_hash_t *rev_props;
       svn_revnum_t rev;
       const char *p;
@@ -2140,7 +2139,7 @@ static svn_error_t *ra_svn_get_file_revs
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Revision entry not a list"));
 
-      SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, rev_pool,
+      SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, rev_pool,
                                       "crll?B", &p, &rev, &rev_proplist,
                                       &proplist, &merged_rev_param));
       p = svn_fspath__canonicalize(p, rev_pool);
@@ -2156,7 +2155,7 @@ static svn_error_t *ra_svn_get_file_revs
       if (item->kind != SVN_RA_SVN_STRING)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Text delta chunk not a string"));
-      has_txdelta = item->u.string->len > 0;
+      has_txdelta = item->u.string.len > 0;
 
       SVN_ERR(handler(handler_baton, p, rev, rev_props, merged_rev,
                       has_txdelta ? &d_handler : NULL, &d_baton,
@@ -2172,13 +2171,13 @@ static svn_error_t *ra_svn_get_file_revs
                                                rev_pool);
           else
             stream = NULL;
-          while (item->u.string->len > 0)
+          while (item->u.string.len > 0)
             {
               apr_size_t size;
 
-              size = item->u.string->len;
+              size = item->u.string.len;
               if (stream)
-                SVN_ERR(svn_stream_write(stream, item->u.string->data, &size));
+                SVN_ERR(svn_stream_write(stream, item->u.string.data, &size));
               svn_pool_clear(chunk_pool);
 
               SVN_ERR(svn_ra_svn__read_item(sess_baton->conn, chunk_pool,
@@ -2220,7 +2219,7 @@ static svn_error_t *ra_svn_lock_compat(s
 {
   svn_ra_svn__session_baton_t *sess = session->priv;
   svn_ra_svn_conn_t* conn = sess->conn;
-  apr_array_header_t *list;
+  svn_ra_svn__list_t *list;
   apr_hash_index_t *hi;
   apr_pool_t *iterpool = svn_pool_create(pool);
 
@@ -2291,7 +2290,7 @@ static svn_error_t *ra_svn_unlock_compat
       const void *key;
       const char *path;
       void *val;
-      const char *token;
+      const svn_string_t *token;
       svn_error_t *err, *callback_err = NULL;
 
       svn_pool_clear(iterpool);
@@ -2299,7 +2298,7 @@ static svn_error_t *ra_svn_unlock_compat
       apr_hash_this(hi, &key, NULL, &val);
       path = key;
       if (strcmp(val, "") != 0)
-        token = val;
+        token = svn_string_create(val, iterpool);
       else
         token = NULL;
 
@@ -2383,13 +2382,13 @@ static svn_error_t *ra_svn_lock(svn_ra_s
   /* Loop over responses to get lock information. */
   for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
     {
-      svn_ra_svn_item_t *elt;
+      svn_ra_svn__item_t *elt;
       const void *key;
       const char *path;
       svn_error_t *callback_err;
       const char *status;
       svn_lock_t *lock;
-      apr_array_header_t *list;
+      svn_ra_svn__list_t *list;
 
       apr_hash_this(hi, &key, NULL, NULL);
       path = key;
@@ -2408,7 +2407,7 @@ static svn_error_t *ra_svn_lock(svn_ra_s
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Lock response not a list"));
 
-      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool, "wl", &status,
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, iterpool, "wl", &status,
                                       &list));
 
       if (strcmp(status, "failure") == 0)
@@ -2439,7 +2438,7 @@ static svn_error_t *ra_svn_lock(svn_ra_s
      read the final "done" from the server. */
   if (!hi)
     {
-      svn_ra_svn_item_t *elt;
+      svn_ra_svn__item_t *elt;
 
       SVN_ERR(svn_ra_svn__read_item(conn, pool, &elt));
       if (elt->kind != SVN_RA_SVN_WORD || strcmp(elt->u.word, "done") != 0)
@@ -2512,11 +2511,11 @@ static svn_error_t *ra_svn_unlock(svn_ra
   /* Loop over responses to unlock files. */
   for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
     {
-      svn_ra_svn_item_t *elt;
+      svn_ra_svn__item_t *elt;
       const void *key;
       svn_error_t *callback_err;
       const char *status;
-      apr_array_header_t *list;
+      svn_ra_svn__list_t *list;
 
       svn_pool_clear(iterpool);
 
@@ -2536,7 +2535,7 @@ static svn_error_t *ra_svn_unlock(svn_ra
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Unlock response not a list"));
 
-      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool, "wl", &status,
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, iterpool, "wl", &status,
                                       &list));
 
       if (strcmp(status, "failure") == 0)
@@ -2566,7 +2565,7 @@ static svn_error_t *ra_svn_unlock(svn_ra
      read the final "done" from the server. */
   if (!hi)
     {
-      svn_ra_svn_item_t *elt;
+      svn_ra_svn__item_t *elt;
 
       SVN_ERR(svn_ra_svn__read_item(conn, pool, &elt));
       if (elt->kind != SVN_RA_SVN_WORD || strcmp(elt->u.word, "done") != 0)
@@ -2589,7 +2588,7 @@ static svn_error_t *ra_svn_get_lock(svn_
 {
   svn_ra_svn__session_baton_t *sess = session->priv;
   svn_ra_svn_conn_t* conn = sess->conn;
-  apr_array_header_t *list;
+  svn_ra_svn__list_t *list;
 
   SVN_ERR(svn_ra_svn__write_cmd_get_lock(conn, pool, path));
 
@@ -2634,7 +2633,7 @@ static svn_error_t *ra_svn_get_locks(svn
 {
   svn_ra_svn__session_baton_t *sess = session->priv;
   svn_ra_svn_conn_t* conn = sess->conn;
-  apr_array_header_t *list;
+  svn_ra_svn__list_t *list;
   const char *full_url, *abs_path;
   int i;
 
@@ -2657,12 +2656,12 @@ static svn_error_t *ra_svn_get_locks(svn
   for (i = 0; i < list->nelts; ++i)
     {
       svn_lock_t *lock;
-      svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t);
+      svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(list, i);
 
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Lock element not a list"));
-      SVN_ERR(parse_lock(elt->u.list, pool, &lock));
+      SVN_ERR(parse_lock(&elt->u.list, pool, &lock));
 
       /* Filter out unwanted paths.  Since Subversion only allows
          locks on files, we can treat depth=immediates the same as
@@ -2745,7 +2744,7 @@ ra_svn_replay_range(svn_ra_session_t *se
       void *edit_baton;
       apr_hash_t *rev_props;
       const char *word;
-      apr_array_header_t *list;
+      svn_ra_svn__list_t *list;
 
       svn_pool_clear(iterpool);
 
@@ -2877,7 +2876,7 @@ ra_svn_get_inherited_props(svn_ra_sessio
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
-  apr_array_header_t *iproplist;
+  svn_ra_svn__list_t *iproplist;
   svn_boolean_t iprop_capable;
 
   SVN_ERR(ra_svn_has_capability(session, &iprop_capable,

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c Fri Sep 11 15:51:30 2015
@@ -140,7 +140,7 @@ svn_error_t *svn_ra_svn_cram_server(svn_
   char hostbuf[APRMAXHOSTLEN + 1];
   unsigned char cdigest[APR_MD5_DIGESTSIZE], sdigest[APR_MD5_DIGESTSIZE];
   const char *challenge, *sep, *password;
-  svn_ra_svn_item_t *item;
+  svn_ra_svn__item_t *item;
   svn_string_t *resp;
 
   *success = FALSE;
@@ -160,7 +160,7 @@ svn_error_t *svn_ra_svn_cram_server(svn_
   SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
   if (item->kind != SVN_RA_SVN_STRING)  /* Very wrong; don't report failure */
     return SVN_NO_ERROR;
-  resp = item->u.string;
+  resp = &item->u.string;
   sep = strrchr(resp->data, ' ');
   if (!sep || resp->len - (sep + 1 - resp->data) != APR_MD5_DIGESTSIZE * 2
       || !hex_decode(cdigest, sep + 1))

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c Fri Sep 11 15:51:30 2015
@@ -828,7 +828,7 @@ svn_error_t *svn_ra_svn__get_addresses(c
 
 svn_error_t *
 svn_ra_svn__do_cyrus_auth(svn_ra_svn__session_baton_t *sess,
-                          const apr_array_header_t *mechlist,
+                          const svn_ra_svn__list_t *mechlist,
                           const char *realm, apr_pool_t *pool)
 {
   apr_pool_t *subpool;
@@ -856,7 +856,7 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se
       /* Create a string containing the list of mechanisms, separated by spaces. */
       for (i = 0; i < mechlist->nelts; i++)
         {
-          svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t);
+          svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(mechlist, i);
           mechstring = apr_pstrcat(pool,
                                    mechstring,
                                    i == 0 ? "" : " ",

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c Fri Sep 11 15:51:30 2015
@@ -110,7 +110,12 @@ svn_ra_svn_read_item(svn_ra_svn_conn_t *
                      apr_pool_t *pool,
                      svn_ra_svn_item_t **item)
 {
-  return svn_error_trace(svn_ra_svn__read_item(conn, pool, item));
+  svn_ra_svn__item_t *temp;
+  SVN_ERR(svn_ra_svn__read_item(conn, pool, &temp));
+  *item  = apr_pcalloc(pool, sizeof(**item));
+  svn_ra_svn__to_public_item(*item, temp, pool);
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -127,9 +132,10 @@ svn_ra_svn_parse_tuple(const apr_array_h
 {
   va_list va;
   svn_error_t *err;
+  svn_ra_svn__list_t *internal = svn_ra_svn__to_private_array(list, pool);
 
   va_start(va, fmt);
-  err = svn_ra_svn__parse_tuple(list, pool, fmt, va);
+  err = svn_ra_svn__parse_tuple(internal, pool, fmt, va);
   va_end(va);
 
   return svn_error_trace(err);
@@ -155,7 +161,9 @@ svn_ra_svn_parse_proplist(const apr_arra
                           apr_pool_t *pool,
                           apr_hash_t **props)
 {
-  return svn_error_trace(svn_ra_svn__parse_proplist(list, pool, props));
+  svn_ra_svn__list_t *internal
+    = svn_ra_svn__to_private_array(list, pool);
+  return svn_error_trace(svn_ra_svn__parse_proplist(internal, pool, props));
 }
 
 svn_error_t *
@@ -180,8 +188,23 @@ svn_ra_svn_handle_commands2(svn_ra_svn_c
                             void *baton,
                             svn_boolean_t error_on_disconnect)
 {
+  apr_size_t i, count = 0;
+  svn_ra_svn__cmd_entry_t *internal;
+
+  while (commands[count].cmdname)
+    count++;
+
+  internal = apr_pcalloc(pool, count * sizeof(*internal));
+  for (i = 0; i < count; ++i)
+    {
+      internal[i].cmdname = commands[i].cmdname;
+      internal[i].handler = NULL;
+      internal[i].deprecated_handler = commands[i].handler;
+      internal[i].terminate = commands[i].terminate;
+    }
+
   return svn_error_trace(svn_ra_svn__handle_commands2(conn, pool,
-                                                      commands, baton,
+                                                      internal, baton,
                                                       error_on_disconnect));
 }
 
@@ -191,9 +214,9 @@ svn_ra_svn_handle_commands(svn_ra_svn_co
                            const svn_ra_svn_cmd_entry_t *commands,
                            void *baton)
 {
-  return svn_error_trace(svn_ra_svn__handle_commands2(conn, pool,
-                                                      commands, baton,
-                                                      FALSE));
+  return svn_error_trace(svn_ra_svn_handle_commands2(conn, pool,
+                                                     commands, baton,
+                                                     FALSE));
 }
 
 svn_error_t *

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c Fri Sep 11 15:51:30 2015
@@ -39,8 +39,11 @@
 #include "svn_pools.h"
 #include "svn_private_config.h"
 
+#include "private/svn_atomic.h"
 #include "private/svn_fspath.h"
 #include "private/svn_editor.h"
+#include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
 
 #include "ra_svn.h"
 
@@ -57,7 +60,7 @@ typedef struct ra_svn_edit_baton_t {
   svn_ra_svn_conn_t *conn;
   svn_ra_svn_edit_callback callback;    /* Called on successful completion. */
   void *callback_baton;
-  int next_token;
+  apr_uint64_t next_token;
   svn_boolean_t got_status;
 } ra_svn_edit_baton_t;
 
@@ -66,13 +69,19 @@ typedef struct ra_svn_baton_t {
   svn_ra_svn_conn_t *conn;
   apr_pool_t *pool;
   ra_svn_edit_baton_t *eb;
-  const char *token;
+  svn_string_t *token;
 } ra_svn_baton_t;
 
+/* Forward declaration. */
+typedef struct ra_svn_token_entry_t ra_svn_token_entry_t;
+
 typedef struct ra_svn_driver_state_t {
   const svn_delta_editor_t *editor;
   void *edit_baton;
   apr_hash_t *tokens;
+
+  /* Entry for the last token seen.  May be NULL. */
+  ra_svn_token_entry_t *last_token;
   svn_boolean_t *aborted;
   svn_boolean_t done;
   apr_pool_t *pool;
@@ -90,26 +99,33 @@ typedef struct ra_svn_driver_state_t {
    field in this structure is vestigial for files, and we use it for a
    different purpose instead: at apply-textdelta time, we set it to a
    subpool of the file pool, which is destroyed in textdelta-end. */
-typedef struct ra_svn_token_entry_t {
+struct ra_svn_token_entry_t {
   svn_string_t *token;
   void *baton;
   svn_boolean_t is_file;
   svn_stream_t *dstream;  /* svndiff stream for apply_textdelta */
   apr_pool_t *pool;
-} ra_svn_token_entry_t;
+};
 
 /* --- CONSUMING AN EDITOR BY PASSING EDIT OPERATIONS OVER THE NET --- */
 
-static const char *make_token(char type, ra_svn_edit_baton_t *eb,
-                              apr_pool_t *pool)
-{
-  return apr_psprintf(pool, "%c%d", type, eb->next_token++);
+static svn_string_t *
+make_token(char type,
+           ra_svn_edit_baton_t *eb,
+           apr_pool_t *pool)
+{
+  apr_size_t len;
+  char buffer[1 + SVN_INT64_BUFFER_SIZE];
+  buffer[0] = type;
+  len = 1 + svn__ui64toa(&buffer[1], eb->next_token++);
+  
+  return svn_string_ncreate(buffer, len, pool);
 }
 
 static ra_svn_baton_t *ra_svn_make_baton(svn_ra_svn_conn_t *conn,
                                          apr_pool_t *pool,
                                          ra_svn_edit_baton_t *eb,
-                                         const char *token)
+                                         svn_string_t *token)
 {
   ra_svn_baton_t *b;
 
@@ -171,7 +187,7 @@ static svn_error_t *ra_svn_open_root(voi
                                      apr_pool_t *pool, void **root_baton)
 {
   ra_svn_edit_baton_t *eb = edit_baton;
-  const char *token = make_token('d', eb, pool);
+  svn_string_t *token = make_token('d', eb, pool);
 
   SVN_ERR(check_for_error(eb, pool));
   SVN_ERR(svn_ra_svn__write_cmd_open_root(eb->conn, pool, rev, token));
@@ -196,7 +212,7 @@ static svn_error_t *ra_svn_add_dir(const
                                    apr_pool_t *pool, void **child_baton)
 {
   ra_svn_baton_t *b = parent_baton;
-  const char *token = make_token('d', b->eb, pool);
+  svn_string_t *token = make_token('d', b->eb, pool);
 
   SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev))
                  || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));
@@ -212,7 +228,7 @@ static svn_error_t *ra_svn_open_dir(cons
                                     void **child_baton)
 {
   ra_svn_baton_t *b = parent_baton;
-  const char *token = make_token('d', b->eb, pool);
+  svn_string_t *token = make_token('d', b->eb, pool);
 
   SVN_ERR(check_for_error(b->eb, pool));
   SVN_ERR(svn_ra_svn__write_cmd_open_dir(b->conn, pool, path, b->token,
@@ -265,7 +281,7 @@ static svn_error_t *ra_svn_add_file(cons
                                     void **file_baton)
 {
   ra_svn_baton_t *b = parent_baton;
-  const char *token = make_token('c', b->eb, pool);
+  svn_string_t *token = make_token('c', b->eb, pool);
 
   SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev))
                  || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));
@@ -283,7 +299,7 @@ static svn_error_t *ra_svn_open_file(con
                                      void **file_baton)
 {
   ra_svn_baton_t *b = parent_baton;
-  const char *token = make_token('c', b->eb, pool);
+  svn_string_t *token = make_token('c', b->eb, pool);
 
   SVN_ERR(check_for_error(b->eb, b->pool));
   SVN_ERR(svn_ra_svn__write_cmd_open_file(b->conn, pool, path, b->token,
@@ -480,6 +496,7 @@ static ra_svn_token_entry_t *store_token
   entry->pool = pool;
 
   apr_hash_set(ds->tokens, entry->token->data, entry->token->len, entry);
+  ds->last_token = entry;
 
   return entry;
 }
@@ -489,17 +506,39 @@ static svn_error_t *lookup_token(ra_svn_
                                  svn_boolean_t is_file,
                                  ra_svn_token_entry_t **entry)
 {
-  *entry = apr_hash_get(ds->tokens, token->data, token->len);
+  if (ds->last_token && svn_string_compare(ds->last_token->token, token))
+    {
+      *entry = ds->last_token;
+    }
+  else
+    {
+      *entry = apr_hash_get(ds->tokens, token->data, token->len);
+      ds->last_token = *entry;
+    }
+
   if (!*entry || (*entry)->is_file != is_file)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("Invalid file or dir token during edit"));
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_target_rev(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const apr_array_header_t *params,
-                                             ra_svn_driver_state_t *ds)
+/* Remove a TOKEN entry from DS. */
+static void remove_token(ra_svn_driver_state_t *ds,
+                         svn_string_t *token)
+{
+  apr_hash_set(ds->tokens, token->data, token->len, NULL);
+
+  /* Reset this unconditionally.  In most cases, LAST_TOKEN->TOKEN will
+     match TOKEN anyway and if it doesn't, lookup_token() will suffer only
+     a minor performance hit. */
+  ds->last_token = NULL;
+}
+
+static svn_error_t *
+ra_svn_handle_target_rev(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_ra_svn__list_t *params,
+                         ra_svn_driver_state_t *ds)
 {
   svn_revnum_t rev;
 
@@ -508,10 +547,11 @@ static svn_error_t *ra_svn_handle_target
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_open_root(svn_ra_svn_conn_t *conn,
-                                            apr_pool_t *pool,
-                                            const apr_array_header_t *params,
-                                            ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_open_root(svn_ra_svn_conn_t *conn,
+                        apr_pool_t *pool,
+                        const svn_ra_svn__list_t *params,
+                        ra_svn_driver_state_t *ds)
 {
   svn_revnum_t rev;
   apr_pool_t *subpool;
@@ -526,10 +566,11 @@ static svn_error_t *ra_svn_handle_open_r
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_delete_entry(svn_ra_svn_conn_t *conn,
-                                               apr_pool_t *pool,
-                                               const apr_array_header_t *params,
-                                               ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_delete_entry(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           const svn_ra_svn__list_t *params,
+                           ra_svn_driver_state_t *ds)
 {
   const char *path;
   svn_string_t *token;
@@ -544,10 +585,11 @@ static svn_error_t *ra_svn_handle_delete
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_add_dir(svn_ra_svn_conn_t *conn,
-                                          apr_pool_t *pool,
-                                          const apr_array_header_t *params,
-                                          ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_add_dir(svn_ra_svn_conn_t *conn,
+                      apr_pool_t *pool,
+                      const svn_ra_svn__list_t *params,
+                      ra_svn_driver_state_t *ds)
 {
   const char *path, *copy_path;
   svn_string_t *token, *child_token;
@@ -578,10 +620,11 @@ static svn_error_t *ra_svn_handle_add_di
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_open_dir(svn_ra_svn_conn_t *conn,
-                                           apr_pool_t *pool,
-                                           const apr_array_header_t *params,
-                                           ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_open_dir(svn_ra_svn_conn_t *conn,
+                       apr_pool_t *pool,
+                       const svn_ra_svn__list_t *params,
+                       ra_svn_driver_state_t *ds)
 {
   const char *path;
   svn_string_t *token, *child_token;
@@ -601,10 +644,11 @@ static svn_error_t *ra_svn_handle_open_d
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_change_dir_prop(svn_ra_svn_conn_t *conn,
-                                                  apr_pool_t *pool,
-                                                  const apr_array_header_t *params,
-                                                  ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_change_dir_prop(svn_ra_svn_conn_t *conn,
+                              apr_pool_t *pool,
+                              const svn_ra_svn__list_t *params,
+                              ra_svn_driver_state_t *ds)
 {
   svn_string_t *token;
   const char *name;
@@ -619,10 +663,11 @@ static svn_error_t *ra_svn_handle_change
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_close_dir(svn_ra_svn_conn_t *conn,
-                                            apr_pool_t *pool,
-                                            const apr_array_header_t *params,
-                                            ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_close_dir(svn_ra_svn_conn_t *conn,
+                        apr_pool_t *pool,
+                        const svn_ra_svn__list_t *params,
+                        ra_svn_driver_state_t *ds)
 {
   svn_string_t *token;
   ra_svn_token_entry_t *entry;
@@ -633,15 +678,16 @@ static svn_error_t *ra_svn_handle_close_
 
   /* Close the directory and destroy the baton. */
   SVN_CMD_ERR(ds->editor->close_directory(entry->baton, pool));
-  apr_hash_set(ds->tokens, token->data, token->len, NULL);
+  remove_token(ds, token);
   svn_pool_destroy(entry->pool);
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_absent_dir(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const apr_array_header_t *params,
-                                             ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_absent_dir(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_ra_svn__list_t *params,
+                         ra_svn_driver_state_t *ds)
 {
   const char *path;
   svn_string_t *token;
@@ -656,10 +702,11 @@ static svn_error_t *ra_svn_handle_absent
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_add_file(svn_ra_svn_conn_t *conn,
-                                           apr_pool_t *pool,
-                                           const apr_array_header_t *params,
-                                           ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_add_file(svn_ra_svn_conn_t *conn,
+                       apr_pool_t *pool,
+                       const svn_ra_svn__list_t *params,
+                       ra_svn_driver_state_t *ds)
 {
   const char *path, *copy_path;
   svn_string_t *token, *file_token;
@@ -691,10 +738,11 @@ static svn_error_t *ra_svn_handle_add_fi
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_open_file(svn_ra_svn_conn_t *conn,
-                                            apr_pool_t *pool,
-                                            const apr_array_header_t *params,
-                                            ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_open_file(svn_ra_svn_conn_t *conn,
+                        apr_pool_t *pool,
+                        const svn_ra_svn__list_t *params,
+                        ra_svn_driver_state_t *ds)
 {
   const char *path;
   svn_string_t *token, *file_token;
@@ -716,10 +764,11 @@ static svn_error_t *ra_svn_handle_open_f
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_apply_textdelta(svn_ra_svn_conn_t *conn,
-                                                  apr_pool_t *pool,
-                                                  const apr_array_header_t *params,
-                                                  ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_apply_textdelta(svn_ra_svn_conn_t *conn,
+                              apr_pool_t *pool,
+                              const svn_ra_svn__list_t *params,
+                              ra_svn_driver_state_t *ds)
 {
   svn_string_t *token;
   ra_svn_token_entry_t *entry;
@@ -741,10 +790,11 @@ static svn_error_t *ra_svn_handle_apply_
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_textdelta_chunk(svn_ra_svn_conn_t *conn,
-                                                  apr_pool_t *pool,
-                                                  const apr_array_header_t *params,
-                                                  ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_textdelta_chunk(svn_ra_svn_conn_t *conn,
+                              apr_pool_t *pool,
+                              const svn_ra_svn__list_t *params,
+                              ra_svn_driver_state_t *ds)
 {
   svn_string_t *token;
   ra_svn_token_entry_t *entry;
@@ -760,10 +810,11 @@ static svn_error_t *ra_svn_handle_textde
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_textdelta_end(svn_ra_svn_conn_t *conn,
-                                                apr_pool_t *pool,
-                                                const apr_array_header_t *params,
-                                                ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_textdelta_end(svn_ra_svn_conn_t *conn,
+                            apr_pool_t *pool,
+                            const svn_ra_svn__list_t *params,
+                            ra_svn_driver_state_t *ds)
 {
   svn_string_t *token;
   ra_svn_token_entry_t *entry;
@@ -780,10 +831,11 @@ static svn_error_t *ra_svn_handle_textde
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_change_file_prop(svn_ra_svn_conn_t *conn,
-                                                   apr_pool_t *pool,
-                                                   const apr_array_header_t *params,
-                                                   ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_change_file_prop(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const svn_ra_svn__list_t *params,
+                               ra_svn_driver_state_t *ds)
 {
   const char *name;
   svn_string_t *token, *value;
@@ -796,10 +848,11 @@ static svn_error_t *ra_svn_handle_change
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_close_file(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const apr_array_header_t *params,
-                                             ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_close_file(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_ra_svn__list_t *params,
+                         ra_svn_driver_state_t *ds)
 {
   svn_string_t *token;
   ra_svn_token_entry_t *entry;
@@ -812,16 +865,17 @@ static svn_error_t *ra_svn_handle_close_
 
   /* Close the file and destroy the baton. */
   SVN_CMD_ERR(ds->editor->close_file(entry->baton, text_checksum, pool));
-  apr_hash_set(ds->tokens, token->data, token->len, NULL);
+  remove_token(ds, token);
   if (--ds->file_refs == 0)
     svn_pool_clear(ds->file_pool);
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_absent_file(svn_ra_svn_conn_t *conn,
-                                              apr_pool_t *pool,
-                                              const apr_array_header_t *params,
-                                              ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_absent_file(svn_ra_svn_conn_t *conn,
+                          apr_pool_t *pool,
+                          const svn_ra_svn__list_t *params,
+                          ra_svn_driver_state_t *ds)
 {
   const char *path;
   svn_string_t *token;
@@ -836,10 +890,11 @@ static svn_error_t *ra_svn_handle_absent
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *ra_svn_handle_close_edit(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const apr_array_header_t *params,
-                                             ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_close_edit(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_ra_svn__list_t *params,
+                         ra_svn_driver_state_t *ds)
 {
   SVN_CMD_ERR(ds->editor->close_edit(ds->edit_baton, pool));
   ds->done = TRUE;
@@ -856,10 +911,11 @@ static svn_error_t *ra_svn_handle_close_
   return svn_ra_svn__write_cmd_response(conn, pool, "");
 }
 
-static svn_error_t *ra_svn_handle_abort_edit(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const apr_array_header_t *params,
-                                             ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_abort_edit(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_ra_svn__list_t *params,
+                         ra_svn_driver_state_t *ds)
 {
   ds->done = TRUE;
   if (ds->aborted)
@@ -868,10 +924,11 @@ static svn_error_t *ra_svn_handle_abort_
   return svn_ra_svn__write_cmd_response(conn, pool, "");
 }
 
-static svn_error_t *ra_svn_handle_finish_replay(svn_ra_svn_conn_t *conn,
-                                                apr_pool_t *pool,
-                                                const apr_array_header_t *params,
-                                                ra_svn_driver_state_t *ds)
+static svn_error_t *
+ra_svn_handle_finish_replay(svn_ra_svn_conn_t *conn,
+                            apr_pool_t *pool,
+                            const svn_ra_svn__list_t *params,
+                            ra_svn_driver_state_t *ds)
 {
   if (!ds->for_replay)
     return svn_error_createf
@@ -883,11 +940,15 @@ static svn_error_t *ra_svn_handle_finish
   return SVN_NO_ERROR;
 }
 
+/* Common function signature for all editor command handlers. */
+typedef svn_error_t *(*cmd_handler_t)(svn_ra_svn_conn_t *conn,
+                                      apr_pool_t *pool,
+                                      const svn_ra_svn__list_t *params,
+                                      ra_svn_driver_state_t *ds);
+
 static const struct {
   const char *cmd;
-  svn_error_t *(*handler)(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                          const apr_array_header_t *params,
-                          ra_svn_driver_state_t *ds);
+  cmd_handler_t handler;
 } ra_svn_edit_cmds[] = {
   { "change-file-prop", ra_svn_handle_change_file_prop },
   { "open-file",        ra_svn_handle_open_file },
@@ -911,12 +972,98 @@ static const struct {
   { NULL }
 };
 
+/* All editor commands are kept in a collision-free hash table. */
+
+/* Hash table entry.
+   It is similar to ra_svn_edit_cmds but uses our SVN string type. */
+typedef struct cmd_t {
+  svn_string_t cmd;
+  cmd_handler_t handler;
+} cmd_t;
+
+/* The actual hash table.  It will be filled once before first usage.
+
+   If you add more commands, you may have to tweak the table size to
+   eliminate collisions.  Alternatively, you may modify the hash function.
+
+   Be sure to initialize all elements with 0 as the has conflict detection
+   will rely on it (see init_cmd_hash).
+ */
+#define CMD_HASH_SIZE 67
+static cmd_t cmd_hash[CMD_HASH_SIZE] = { { { NULL } } };
+
+/* Init flag that controls CMD_HASH's atomic initialization. */
+static volatile svn_atomic_t cmd_hash_initialized = FALSE;
+
+/* Super-fast hash function that works very well with the structure of our
+   command words.  It produces no conflicts for them.
+
+   Return the index within CMD_HASH that a command NAME of LEN chars would
+   be found.  LEN > 0.
+ */
+static apr_size_t
+cmd_hash_func(const char *name,
+              apr_size_t len)
+{
+  apr_size_t value =     (apr_byte_t)(name[0] - 'a') % 8
+                   + 1 * (apr_byte_t)(name[len - 1] - 'a') % 8
+                   + 10 * (len - 7);
+  return value % CMD_HASH_SIZE;
+}
+
+/* svn_atomic__init_once callback that fills the CMD_HASH table.  It will
+   error out on hash collisions.  BATON and POOL are not used. */
+static svn_error_t *
+init_cmd_hash(void *baton,
+              apr_pool_t *pool)
+{
+  int i;
+  for (i = 0; ra_svn_edit_cmds[i].cmd; i++)
+    {
+      apr_size_t len = strlen(ra_svn_edit_cmds[i].cmd);
+      apr_size_t value = cmd_hash_func(ra_svn_edit_cmds[i].cmd, len);
+      SVN_ERR_ASSERT(cmd_hash[value].cmd.data == NULL);
+
+      cmd_hash[value].cmd.data = ra_svn_edit_cmds[i].cmd;
+      cmd_hash[value].cmd.len = len;
+      cmd_hash[value].handler = ra_svn_edit_cmds[i].handler;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Return the command handler function for the command name CMD.
+   Return NULL if no such handler exists */
+static cmd_handler_t
+cmd_lookup(const char *cmd)
+{
+  apr_size_t value;
+  apr_size_t len = strlen(cmd);
+
+  /* Malicious data that our hash function may not like? */
+  if (len == 0)
+    return NULL;
+
+  /* Hash lookup. */
+  value = cmd_hash_func(cmd, len);
+
+  /* Hit? */
+  if (cmd_hash[value].cmd.len != len)
+    return NULL;
+
+  if (memcmp(cmd_hash[value].cmd.data, cmd, len))
+    return NULL;
+
+  /* Yes! */
+  return cmd_hash[value].handler;
+}
+
 static svn_error_t *blocked_write(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                   void *baton)
 {
   ra_svn_driver_state_t *ds = baton;
   const char *cmd;
-  apr_array_header_t *params;
+  svn_ra_svn__list_t *params;
 
   /* We blocked trying to send an error.  Read and discard an editing
    * command in order to avoid deadlock. */
@@ -939,13 +1086,16 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
   ra_svn_driver_state_t state;
   apr_pool_t *subpool = svn_pool_create(pool);
   const char *cmd;
-  int i;
   svn_error_t *err, *write_err;
-  apr_array_header_t *params;
+  svn_ra_svn__list_t *params;
+
+  SVN_ERR(svn_atomic__init_once(&cmd_hash_initialized, init_cmd_hash, NULL,
+                                pool));
 
   state.editor = editor;
   state.edit_baton = edit_baton;
-  state.tokens = apr_hash_make(pool);
+  state.tokens = svn_hash__make(pool);
+  state.last_token = NULL;
   state.aborted = aborted;
   state.done = FALSE;
   state.pool = pool;
@@ -958,13 +1108,12 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
       svn_pool_clear(subpool);
       if (editor)
         {
+          cmd_handler_t handler;
           SVN_ERR(svn_ra_svn__read_tuple(conn, subpool, "wl", &cmd, &params));
-          for (i = 0; ra_svn_edit_cmds[i].cmd; i++)
-              if (strcmp(cmd, ra_svn_edit_cmds[i].cmd) == 0)
-                break;
+          handler = cmd_lookup(cmd);
 
-          if (ra_svn_edit_cmds[i].cmd)
-            err = (*ra_svn_edit_cmds[i].handler)(conn, subpool, params, &state);
+          if (handler)
+            err = (*handler)(conn, subpool, params, &state);
           else if (strcmp(cmd, "failure") == 0)
             {
               /* While not really an editor command this can occur when

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c?rev=1702504&r1=1702503&r2=1702504&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c Fri Sep 11 15:51:30 2015
@@ -37,15 +37,15 @@
 
 #include "ra_svn.h"
 
-svn_boolean_t svn_ra_svn__find_mech(const apr_array_header_t *mechlist,
+svn_boolean_t svn_ra_svn__find_mech(const svn_ra_svn__list_t *mechlist,
                                     const char *mech)
 {
   int i;
-  svn_ra_svn_item_t *elt;
+  svn_ra_svn__item_t *elt;
 
   for (i = 0; i < mechlist->nelts; i++)
     {
-      elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t);
+      elt = &SVN_RA_SVN__LIST_ITEM(mechlist, i);
       if (elt->kind == SVN_RA_SVN_WORD && strcmp(elt->u.word, mech) == 0)
         return TRUE;
     }
@@ -69,7 +69,7 @@ static svn_error_t *read_success(svn_ra_
 
 svn_error_t *
 svn_ra_svn__do_internal_auth(svn_ra_svn__session_baton_t *sess,
-                             const apr_array_header_t *mechlist,
+                             const svn_ra_svn__list_t *mechlist,
                              const char *realm, apr_pool_t *pool)
 {
   svn_ra_svn_conn_t *conn = sess->conn;