subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1726108 [2/4] - in /subversion/branches/parallel-put: ./ build/ac-macros/ notes/ notes/move-tracking/ subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/ subversion/bindings/swig/ subversion/bindings/swig/include/ subversio...
Date Thu, 21 Jan 2016 21:39:24 GMT
Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/caching.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/caching.c Thu Jan 21 21:39:22 2016
@@ -66,8 +66,9 @@ normalize_key_part(const char *original,
   return normalized->data;
 }
 
-/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS flags will be set according to
-   FS->CONFIG.  *CACHE_NAMESPACE receives the cache prefix to use.
+/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS, *CACHE_NODEPROPS flags will be set
+   according to FS->CONFIG. *CACHE_NAMESPACE receives the cache prefix to
+   use.
 
    Use FS->pool for allocating the memcache and CACHE_NAMESPACE, and POOL
    for temporary allocations. */
@@ -75,6 +76,7 @@ static svn_error_t *
 read_config(const char **cache_namespace,
             svn_boolean_t *cache_txdeltas,
             svn_boolean_t *cache_fulltexts,
+            svn_boolean_t *cache_nodeprops,
             svn_fs_t *fs,
             apr_pool_t *pool)
 {
@@ -117,6 +119,14 @@ read_config(const char **cache_namespace
                          SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
                          TRUE);
 
+  /* by default, cache nodeprops: this will match pre-1.10
+   * behavior where node properties caching was controlled
+   * by SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS configuration option.
+   */
+  *cache_nodeprops
+    = svn_hash__get_bool(fs->config,
+                         SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+                         TRUE);
   return SVN_NO_ERROR;
 }
 
@@ -353,6 +363,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
   svn_boolean_t no_handler = ffd->fail_stop;
   svn_boolean_t cache_txdeltas;
   svn_boolean_t cache_fulltexts;
+  svn_boolean_t cache_nodeprops;
   const char *cache_namespace;
   svn_boolean_t has_namespace;
 
@@ -360,6 +371,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
   SVN_ERR(read_config(&cache_namespace,
                       &cache_txdeltas,
                       &cache_fulltexts,
+                      &cache_nodeprops,
                       fs,
                       pool));
 
@@ -438,7 +450,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        svn_fs_fs__deserialize_dir_entries,
                        sizeof(pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "DIR", SVN_VA_NULL),
-                       SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        has_namespace,
                        fs,
                        no_handler,
@@ -538,21 +550,6 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            no_handler,
                            fs->pool, pool));
 
-      SVN_ERR(create_cache(&(ffd->properties_cache),
-                           NULL,
-                           membuffer,
-                           0, 0, /* Do not use the inprocess cache */
-                           svn_fs_fs__serialize_properties,
-                           svn_fs_fs__deserialize_properties,
-                           sizeof(pair_cache_key_t),
-                           apr_pstrcat(pool, prefix, "PROP",
-                                       SVN_VA_NULL),
-                           SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
-                           has_namespace,
-                           fs,
-                           no_handler,
-                           fs->pool, pool));
-
       SVN_ERR(create_cache(&(ffd->mergeinfo_cache),
                            NULL,
                            membuffer,
@@ -586,11 +583,33 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
   else
     {
       ffd->fulltext_cache = NULL;
-      ffd->properties_cache = NULL;
       ffd->mergeinfo_cache = NULL;
       ffd->mergeinfo_existence_cache = NULL;
     }
 
+  /* if enabled, cache node properties */
+  if (cache_nodeprops)
+    {
+      SVN_ERR(create_cache(&(ffd->properties_cache),
+                           NULL,
+                           membuffer,
+                           0, 0, /* Do not use the inprocess cache */
+                           svn_fs_fs__serialize_properties,
+                           svn_fs_fs__deserialize_properties,
+                           sizeof(pair_cache_key_t),
+                           apr_pstrcat(pool, prefix, "PROP",
+                                       SVN_VA_NULL),
+                           SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                           has_namespace,
+                           fs,
+                           no_handler,
+                           fs->pool, pool));
+    }
+  else
+    {
+      ffd->properties_cache = NULL;
+    }
+
   /* if enabled, cache text deltas and their combinations */
   if (cache_txdeltas)
     {
@@ -830,27 +849,37 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
 
   /* Transaction content needs to be carefully prefixed to virtually
      eliminate any chance for conflicts. The (repo, txn_id) pair
-     should be unique but if a transaction fails, it might be possible
-     to start a new transaction later that receives the same id.
-     Therefore, throw in a uuid as well - just to be sure. */
-  prefix = apr_pstrcat(pool,
-                       "fsfs:", fs->uuid,
-                       "/", fs->path,
-                       ":", txn_id,
-                       ":", svn_uuid_generate(pool),
-                       ":", "TXNDIR",
-                       SVN_VA_NULL);
+     should be unique but if the filesystem format doesn't store the
+     global transaction ID via the txn-current file, and a transaction
+     fails, it might be possible to start a new transaction later that
+     receives the same id.  For such older formats, throw in an uuid as
+     well -- just to be sure. */
+  if (ffd->format >= SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
+    prefix = apr_pstrcat(pool,
+                         "fsfs:", fs->uuid,
+                         "/", fs->path,
+                         ":", txn_id,
+                         ":", "TXNDIR",
+                         SVN_VA_NULL);
+  else
+    prefix = apr_pstrcat(pool,
+                         "fsfs:", fs->uuid,
+                         "/", fs->path,
+                         ":", txn_id,
+                         ":", svn_uuid_generate(pool),
+                         ":", "TXNDIR",
+                         SVN_VA_NULL);
 
   /* create a txn-local directory cache */
   SVN_ERR(create_cache(&ffd->txn_dir_cache,
                        NULL,
                        svn_cache__get_global_membuffer_cache(),
                        1024, 8,
-                       svn_fs_fs__serialize_dir_entries,
+                       svn_fs_fs__serialize_txndir_entries,
                        svn_fs_fs__deserialize_dir_entries,
                        APR_HASH_KEY_STRING,
                        prefix,
-                       0,
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        TRUE, /* The TXN-ID is our namespace. */
                        fs,
                        TRUE,

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/fs_fs.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/fs_fs.c Thu Jan 21 21:39:22 2016
@@ -492,6 +492,7 @@ read_format(int *pformat,
       svn_error_clear(err);
       *pformat = 1;
       *max_files_per_dir = 0;
+      *use_log_addressing = FALSE;
 
       return SVN_NO_ERROR;
     }

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.c Thu Jan 21 21:39:22 2016
@@ -788,16 +788,18 @@ svn_fs_fs__deserialize_node_revision(voi
 }
 
 /* Utility function that returns the directory serialized inside CONTEXT
- * to DATA and DATA_LEN. */
+ * to DATA and DATA_LEN.  If OVERPROVISION is set, allocate some extra
+ * room for future in-place changes by svn_fs_fs__replace_dir_entry. */
 static svn_error_t *
 return_serialized_dir_context(svn_temp_serializer__context_t *context,
                               void **data,
-                              apr_size_t *data_len)
+                              apr_size_t *data_len,
+                              svn_boolean_t overprovision)
 {
   svn_stringbuf_t *serialized = svn_temp_serializer__get(context);
 
   *data = serialized->data;
-  *data_len = serialized->blocksize;
+  *data_len = overprovision ? serialized->blocksize : serialized->len;
   ((dir_data_t *)serialized->data)->len = serialized->len;
 
   return SVN_NO_ERROR;
@@ -815,7 +817,24 @@ svn_fs_fs__serialize_dir_entries(void **
    * and return the serialized data */
   return return_serialized_dir_context(serialize_dir(dir, pool),
                                        data,
-                                       data_len);
+                                       data_len,
+                                       FALSE);
+}
+
+svn_error_t *
+svn_fs_fs__serialize_txndir_entries(void **data,
+                                    apr_size_t *data_len,
+                                    void *in,
+                                    apr_pool_t *pool)
+{
+  svn_fs_fs__dir_data_t *dir = in;
+
+  /* serialize the dir content into a new serialization context
+   * and return the serialized data */
+  return return_serialized_dir_context(serialize_dir(dir, pool),
+                                       data,
+                                       data_len,
+                                       TRUE);
 }
 
 svn_error_t *
@@ -916,7 +935,7 @@ svn_fs_fs__extract_dir_entry(void **out,
                              apr_pool_t *pool)
 {
   const dir_data_t *dir_data = data;
-  const extract_dir_entry_baton_t *entry_baton = baton;
+  extract_dir_entry_baton_t *entry_baton = baton;
   svn_boolean_t found;
 
   /* resolve the reference to the entries array */
@@ -935,8 +954,11 @@ svn_fs_fs__extract_dir_entry(void **out,
 
   /* de-serialize that entry or return NULL, if no match has been found.
    * Be sure to check that the directory contents is still up-to-date. */
+  entry_baton->out_of_date
+    = dir_data->txn_filesize != entry_baton->txn_filesize;
+
   *out = NULL;
-  if (found && dir_data->txn_filesize == entry_baton->txn_filesize)
+  if (found && !entry_baton->out_of_date)
     {
       const svn_fs_dirent_t *source =
           svn_temp_deserializer__ptr(entries, (const void *const *)&entries[pos]);
@@ -1097,9 +1119,7 @@ svn_fs_fs__replace_dir_entry(void **data
   serialize_dir_entry(context, &entries[pos], &length);
 
   /* return the updated serialized data */
-  SVN_ERR (return_serialized_dir_context(context,
-                                         data,
-                                         data_len));
+  SVN_ERR(return_serialized_dir_context(context, data, data_len, TRUE));
 
   /* since the previous call may have re-allocated the buffer, the lengths
    * pointer may no longer point to the entry in that buffer. Therefore,

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/temp_serializer.h Thu Jan 21 21:39:22 2016
@@ -221,6 +221,16 @@ svn_fs_fs__serialize_dir_entries(void **
                                  apr_pool_t *pool);
 
 /**
+ * Same as svn_fs_fs__serialize_dir_entries but allocates extra room for
+ * in-place modification.
+ */
+svn_error_t *
+svn_fs_fs__serialize_txndir_entries(void **data,
+                                    apr_size_t *data_len,
+                                    void *in,
+                                    apr_pool_t *pool);
+
+/**
  * Implements #svn_cache__deserialize_func_t for a #svn_fs_fs__dir_data_t
  */
 svn_error_t *
@@ -264,6 +274,12 @@ typedef struct extract_dir_entry_baton_t
   /** Current length of the in-txn in-disk representation of the directory.
    * SVN_INVALID_FILESIZE if unknown. */
   svn_filesize_t txn_filesize;
+
+  /** Will be set by the callback.  If FALSE, the cached data is out of date.
+   * We need this indicator because the svn_cache__t interface will always
+   * report the lookup as a success (FOUND==TRUE) if the generic lookup was
+   * successful -- regardless of what the entry extraction callback does. */
+  svn_boolean_t out_of_date;
 } extract_dir_entry_baton_t;
 
 

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_fs/tree.c Thu Jan 21 21:39:22 2016
@@ -1480,29 +1480,6 @@ fs_node_created_path(const char **create
   return SVN_NO_ERROR;
 }
 
-
-/* Set *KIND_P to the type of node located at PATH under ROOT.
-   Perform temporary allocations in POOL. */
-static svn_error_t *
-node_kind(svn_node_kind_t *kind_p,
-          svn_fs_root_t *root,
-          const char *path,
-          apr_pool_t *pool)
-{
-  const svn_fs_id_t *node_id;
-  dag_node_t *node;
-
-  /* Get the node id. */
-  SVN_ERR(svn_fs_fs__node_id(&node_id, root, path, pool));
-
-  /* Use the node id to get the real kind. */
-  SVN_ERR(svn_fs_fs__dag_get_node(&node, root->fs, node_id, pool));
-  *kind_p = svn_fs_fs__dag_node_kind(node);
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Set *KIND_P to the type of node present at PATH under ROOT.  If
    PATH does not exist under ROOT, set *KIND_P to svn_node_none.  Use
    POOL for temporary allocation. */
@@ -1512,17 +1489,23 @@ svn_fs_fs__check_path(svn_node_kind_t *k
                       const char *path,
                       apr_pool_t *pool)
 {
-  svn_error_t *err = node_kind(kind_p, root, path, pool);
+  dag_node_t *node;
+  svn_error_t *err;
+
+  err = get_dag(&node, root, path, pool);
   if (err &&
       ((err->apr_err == SVN_ERR_FS_NOT_FOUND)
        || (err->apr_err == SVN_ERR_FS_NOT_DIRECTORY)))
     {
       svn_error_clear(err);
-      err = SVN_NO_ERROR;
       *kind_p = svn_node_none;
+      return SVN_NO_ERROR;
     }
+  else if (err)
+    return svn_error_trace(err);
 
-  return svn_error_trace(err);
+  *kind_p = svn_fs_fs__dag_node_kind(node);
+  return SVN_NO_ERROR;
 }
 
 /* Set *VALUE_P to the value of the property named PROPNAME of PATH in

Propchange: subversion/branches/parallel-put/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jan 21 21:39:22 2016
@@ -94,5 +94,5 @@
 /subversion/branches/verify-at-commit/subversion/libsvn_fs_x:1462039-1462408
 /subversion/branches/verify-keep-going/subversion/libsvn_fs_x:1439280-1492639,1546002-1546110
 /subversion/branches/wc-collate-path/subversion/libsvn_fs_x:1402685-1480384
-/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
 4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1649590,
 1651567,1652068,1652076,1652441,1652451,1653608,1654932,1654934,1654937,1655635,1655649,1655651,1655664,1656176,1657525,1657972,1657978,1658482,1659212,1659217,1659314,1659509,1662668,1665318,1665854,1665894,1667090,1667101,1667538,1669743,1669746,1669749,1669945,1670139,1670953,1673170,1673197,1673202,1673204,1673445,1673454,1673685,1673689,1673875,1674165,1674341,1674400,1674404,1674631,1674669,1674673,1675396,1676667,1677431,1678149,1678151,1678718,1678725,1679169,1679907,1679920-1679924,1679926,1680347,1680460,1680464,1680476,1680819,1681949,1681966,1681974,1681994,1682008,1682076,1682086,1682093,1682259,1682265,1682739,1682864,1683311,1683330,1683378,1683544,1683553,1684047,1686232,1686542,1686546,1686554,1686557,1687061,1687064,1687070-1687071,1687074,1687078-1687079,1688270,1688425,1692650,1693886,1694489,1694848,1696171,1696185,1696627-1696628,1696630,1696758,1697372,1697381,1697387,1697393,1697403,1697405,1701017,1701053,1702600,1702922,1703069,1703142,1703237,1703240,17052
 66,1705638,1705643,1705646,1705724,1705730,1705739,1706612,1706615,1706617,1706619,1706675-1706676,1706679,1706979-1706980,1707308,1707971-1707973,1707986,1707988-1707989,1708004,1709799,1710017,1710359,1711582,1711672,1712927,1715793,1715947,1716047,1716067,1716784,1716973-1716974,1717332,1717334
-/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914
+/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
 4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1649590,
 1651567,1652068,1652076,1652441,1652451,1653608,1654932,1654934,1654937,1655635,1655649,1655651,1655664,1656176,1657525,1657972,1657978,1658482,1659212,1659217,1659314,1659509,1662668,1665318,1665854,1665894,1667090,1667101,1667538,1669743,1669746,1669749,1669945,1670139,1670953,1673170,1673197,1673202,1673204,1673445,1673454,1673685,1673689,1673875,1674165,1674341,1674400,1674404,1674631,1674669,1674673,1675396,1676667,1677431,1678149,1678151,1678718,1678725,1679169,1679907,1679920-1679924,1679926,1680347,1680460,1680464,1680476,1680819,1681949,1681966,1681974,1681994,1682008,1682076,1682086,1682093,1682259,1682265,1682739,1682864,1683311,1683330,1683378,1683544,1683553,1684047,1686232,1686542,1686546,1686554,1686557,1687061,1687064,1687070-1687071,1687074,1687078-1687079,1688270,1688425,1692650,1693886,1694489,1694848,1696171,1696185,1696627-1696628,1696630,1696758,1697372,1697381,1697387,1697393,1697403,1697405,1701017,1701053,1702600,1702922,1703069,1703142,1703237,1703240,17052
 66,1705638,1705643,1705646,1705724,1705730,1705739,1706612,1706615,1706617,1706619,1706675-1706676,1706679,1706979-1706980,1707308,1707971-1707973,1707986,1707988-1707989,1708004,1709388,1709799,1710017,1710359,1710368,1710370,1711507,1711582,1711672,1712927,1715793,1715947,1716047,1716067,1716784,1716973-1716974,1717332,1717334,1717864,1719269,1719336,1719413,1719730,1720015,1721285,1723715,1723720,1723834,1723839,1725179-1725180,1726004
+/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1719877-1726107

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/cached_data.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/cached_data.c Thu Jan 21 21:39:22 2016
@@ -1341,7 +1341,7 @@ read_delta_window(svn_txdelta_window_t *
       SVN_ERR(svn_fs_x__rev_file_get(&apr_file, file));
       SVN_ERR(svn_txdelta_skip_svndiff_window(apr_file, rs->ver, iterpool));
       rs->chunk_index++;
-      SVN_ERR(svn_fs_x__get_file_offset(&start_offset, apr_file, iterpool));
+      SVN_ERR(svn_io_file_get_offset(&start_offset, apr_file, iterpool));
 
       rs->current = start_offset - rs->start;
       if (rs->current >= rs->size)
@@ -2646,8 +2646,13 @@ svn_fs_x__rep_contents_dir(apr_array_hea
   SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
   *entries_p = dir->entries;
 
-  /* Update the cache, if we are to use one. */
-  SVN_ERR(svn_cache__set(cache, &key, dir, scratch_pool));
+  /* Update the cache, if we are to use one.
+   *
+   * Don't even attempt to serialize very large directories; it would cause
+   * an unnecessary memory allocation peak.  100 bytes/entry is about right.
+   */
+  if (svn_cache__is_cachable(cache, 100 * dir->entries->nelts))
+    SVN_ERR(svn_cache__set(cache, &key, dir, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2699,7 +2704,7 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
     *hint = baton.hint;
 
   /* fetch data from disk if we did not find it in the cache */
-  if (! found)
+  if (! found || baton.out_of_date)
     {
       svn_fs_x__dirent_t *entry;
       svn_fs_x__dirent_t *entry_copy = NULL;
@@ -2709,8 +2714,12 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
       SVN_ERR(get_dir_contents(&dir, fs, noderev, scratch_pool,
                                scratch_pool));
 
-      /* Update the cache, if we are to use one. */
-      if (cache)
+      /* Update the cache, if we are to use one.
+       *
+       * Don't even attempt to serialize very large directories; it would
+       * cause an unnecessary memory allocation peak.  150 bytes / entry is
+       * about right. */
+      if (cache && svn_cache__is_cachable(cache, 150 * dir.entries->nelts))
         SVN_ERR(svn_cache__set(cache, &key, &dir, scratch_pool));
 
       /* find desired entry and return a copy in POOL, if found */

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/caching.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/caching.c Thu Jan 21 21:39:22 2016
@@ -69,9 +69,9 @@ normalize_key_part(const char *original,
   return normalized->data;
 }
 
-/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS and *CACHE_REVPROPS flags will be set
-   according to FS->CONFIG.  *CACHE_NAMESPACE receives the cache prefix
-   to use.
+/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS, *CACHE_REVPROPS and *CACHE_NODEPROPS
+   flags will be set according to FS->CONFIG.  *CACHE_NAMESPACE receives
+   the cache prefix to use.
 
    Allocate CACHE_NAMESPACE in RESULT_POOL. */
 static svn_error_t *
@@ -79,6 +79,7 @@ read_config(const char **cache_namespace
             svn_boolean_t *cache_txdeltas,
             svn_boolean_t *cache_fulltexts,
             svn_boolean_t *cache_revprops,
+            svn_boolean_t *cache_nodeprops,
             svn_fs_t *fs,
             apr_pool_t *result_pool)
 {
@@ -137,6 +138,15 @@ read_config(const char **cache_namespace
   else
     *cache_revprops = TRUE;
 
+  /* by default, cache nodeprops: this will match pre-1.10
+   * behavior where node properties caching was controlled
+   * by SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS configuration option.
+   */
+  *cache_nodeprops
+    = svn_hash__get_bool(fs->config,
+                         SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+                         TRUE);
+
   return SVN_NO_ERROR;
 }
 
@@ -380,6 +390,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
   svn_boolean_t cache_txdeltas;
   svn_boolean_t cache_fulltexts;
   svn_boolean_t cache_revprops;
+  svn_boolean_t cache_nodeprops;
   const char *cache_namespace;
   svn_boolean_t has_namespace;
 
@@ -388,6 +399,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                       &cache_txdeltas,
                       &cache_fulltexts,
                       &cache_revprops,
+                      &cache_nodeprops,
                       fs,
                       scratch_pool));
 
@@ -430,7 +442,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        svn_fs_x__deserialize_dir_entries,
                        sizeof(svn_fs_x__id_t),
                        apr_pstrcat(scratch_pool, prefix, "DIR", SVN_VA_NULL),
-                       SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                       SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        has_namespace,
                        fs,
                        no_handler, FALSE,
@@ -512,7 +524,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
                        has_namespace,
                        fs,
-                       no_handler, !cache_fulltexts,
+                       no_handler, !cache_nodeprops,
                        fs->pool, scratch_pool));
 
   /* if enabled, cache revprops */

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/index.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/index.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/index.c Thu Jan 21 21:39:22 2016
@@ -231,7 +231,7 @@ stream_error_create(svn_fs_x__packed_num
   apr_off_t offset;
   SVN_ERR(svn_io_file_name_get(&file_name, stream->file,
                                stream->pool));
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, stream->file, stream->pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, stream->file, stream->pool));
 
   return svn_error_createf(err, NULL, message, file_name,
                            apr_psprintf(stream->pool,

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/pack.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/pack.c Thu Jan 21 21:39:22 2016
@@ -391,7 +391,7 @@ static svn_error_t *
 copy_file_data(pack_context_t *context,
                apr_file_t *dest,
                apr_file_t *source,
-               apr_off_t size,
+               svn_filesize_t size,
                apr_pool_t *scratch_pool)
 {
   /* most non-representation items will be small.  Minimize the buffer
@@ -478,8 +478,8 @@ copy_item_to_temp(pack_context_t *contex
   svn_fs_x__p2l_entry_t *new_entry
     = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
 
-  SVN_ERR(svn_fs_x__get_file_offset(&new_entry->offset, temp_file,
-                                    scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&new_entry->offset, temp_file,
+                                 scratch_pool));
   APR_ARRAY_PUSH(entries, svn_fs_x__p2l_entry_t *) = new_entry;
 
   SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
@@ -572,8 +572,8 @@ copy_rep_to_temp(pack_context_t *context
   /* create a copy of ENTRY, make it point to the copy destination and
    * store it in CONTEXT */
   entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
-  SVN_ERR(svn_fs_x__get_file_offset(&entry->offset, context->reps_file,
-                                    scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&entry->offset, context->reps_file,
+                                 scratch_pool));
   add_item_rep_mapping(context, entry);
 
   /* read & parse the representation header */
@@ -698,8 +698,8 @@ copy_node_to_temp(pack_context_t *contex
   /* create a copy of ENTRY, make it point to the copy destination and
    * store it in CONTEXT */
   entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
-  SVN_ERR(svn_fs_x__get_file_offset(&entry->offset, context->reps_file,
-                                    scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&entry->offset, context->reps_file,
+                                 scratch_pool));
   add_item_rep_mapping(context, entry);
 
   /* copy the noderev to our temp file */
@@ -821,7 +821,7 @@ sort_reps(pack_context_t *context)
 /* Return the remaining unused bytes in the current block in CONTEXT's
  * pack file.
  */
-static apr_ssize_t
+static apr_off_t
 get_block_left(pack_context_t *context)
 {
   svn_fs_x__data_t *ffd = context->fs->fsap_data;
@@ -1839,20 +1839,15 @@ append_revision(pack_context_t *context,
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_fs_x__revision_file_t *rev_file;
   apr_file_t *file;
-  apr_finfo_t finfo;
-
-  /* Get the size of the file. */
-  const char *path = svn_dirent_join(context->shard_dir,
-                                     apr_psprintf(iterpool, "%ld",
-                                                  context->start_rev),
-                                     scratch_pool);
-  SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, scratch_pool));
+  svn_filesize_t revfile_size;
 
   /* Copy all the bits from the rev file to the end of the pack file. */
   SVN_ERR(svn_fs_x__rev_file_init(&rev_file, context->fs, context->start_rev,
                                   scratch_pool));
   SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
-  SVN_ERR(copy_file_data(context, context->pack_file, file, finfo.size,
+
+  SVN_ERR(svn_io_file_size_get(&revfile_size, file, scratch_pool));
+  SVN_ERR(copy_file_data(context, context->pack_file, file, revfile_size,
                          iterpool));
 
   /* mark the start of a new revision */
@@ -1861,7 +1856,7 @@ append_revision(pack_context_t *context,
 
   /* read the phys-to-log index file until we covered the whole rev file.
    * That index contains enough info to build both target indexes from it. */
-  while (offset < finfo.size)
+  while (offset < revfile_size)
     {
       /* read one cluster */
       int i;
@@ -1883,7 +1878,7 @@ append_revision(pack_context_t *context,
 
           /* process entry while inside the rev file */
           offset = entry->offset;
-          if (offset < finfo.size)
+          if (offset < revfile_size)
             {
               /* there should be true containers */
               SVN_ERR_ASSERT(entry->item_count == 1);
@@ -1902,7 +1897,7 @@ append_revision(pack_context_t *context,
     }
 
   svn_pool_destroy(iterpool);
-  context->pack_offset += finfo.size;
+  context->pack_offset += revfile_size;
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/rev_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/rev_file.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/rev_file.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/rev_file.c Thu Jan 21 21:39:22 2016
@@ -490,8 +490,8 @@ svn_fs_x__rev_file_offset(apr_off_t *off
                           svn_fs_x__revision_file_t *file)
 {
   SVN_ERR(auto_open(file));
-  return svn_error_trace(svn_fs_x__get_file_offset(offset, file->file,
-                                                   file->pool));
+  return svn_error_trace(svn_io_file_get_offset(offset, file->file,
+                                                file->pool));
 }
 
 svn_error_t *

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.c Thu Jan 21 21:39:22 2016
@@ -259,6 +259,9 @@ serialize_dir(svn_fs_x__dir_data_t *dir,
                            * sizeof(svn_fs_x__dirent_t*);
   apr_size_t lengths_len = (count + over_provision) * sizeof(apr_uint32_t);
 
+  /* Estimate the size of a directory entry + its name. */
+  enum { ENTRY_SIZE = sizeof(svn_fs_x__dirent_t) + 32 };
+
   /* copy the hash entries to an auxiliary struct of known layout */
   dir_data.count = count;
   dir_data.txn_filesize = dir->txn_filesize;
@@ -274,7 +277,8 @@ serialize_dir(svn_fs_x__dir_data_t *dir,
    * estimate for the size of the buffer that we will need. */
   context = svn_temp_serializer__init(&dir_data,
                                       sizeof(dir_data),
-                                      50 + count * 200 + entries_len,
+                                      50 + count * ENTRY_SIZE
+                                         + entries_len + lengths_len,
                                       scratch_pool);
 
   /* serialize entries references */
@@ -675,16 +679,18 @@ svn_fs_x__deserialize_node_revision(void
 }
 
 /* Utility function that returns the directory serialized inside CONTEXT
- * to DATA and DATA_LEN. */
+ * to DATA and DATA_LEN.  If OVERPROVISION is set, allocate some extra
+ * room for future in-place changes by svn_fs_fs__replace_dir_entry. */
 static svn_error_t *
 return_serialized_dir_context(svn_temp_serializer__context_t *context,
                               void **data,
-                              apr_size_t *data_len)
+                              apr_size_t *data_len,
+                              svn_boolean_t overprovision)
 {
   svn_stringbuf_t *serialized = svn_temp_serializer__get(context);
 
   *data = serialized->data;
-  *data_len = serialized->blocksize;
+  *data_len = overprovision ? serialized->blocksize : serialized->len;
   ((dir_data_t *)serialized->data)->len = serialized->len;
 
   return SVN_NO_ERROR;
@@ -702,7 +708,8 @@ svn_fs_x__serialize_dir_entries(void **d
    * and return the serialized data */
   return return_serialized_dir_context(serialize_dir(dir, pool),
                                        data,
-                                       data_len);
+                                       data_len,
+                                       FALSE);
 }
 
 svn_error_t *
@@ -860,7 +867,9 @@ svn_fs_x__extract_dir_entry(void **out,
 
   /* de-serialize that entry or return NULL, if no match has been found.
    * Be sure to check that the directory contents is still up-to-date. */
-  if (found && dir_data->txn_filesize == b->txn_filesize)
+  b->out_of_date = dir_data->txn_filesize != b->txn_filesize;
+
+  if (found && !b->out_of_date)
     {
       const svn_fs_x__dirent_t *source =
           svn_temp_deserializer__ptr(entries, (const void *const *)&entries[pos]);
@@ -1020,9 +1029,7 @@ svn_fs_x__replace_dir_entry(void **data,
   serialize_dir_entry(context, &entries[pos], &length);
 
   /* return the updated serialized data */
-  SVN_ERR (return_serialized_dir_context(context,
-                                         data,
-                                         data_len));
+  SVN_ERR(return_serialized_dir_context(context, data, data_len, TRUE));
 
   /* since the previous call may have re-allocated the buffer, the lengths
    * pointer may no longer point to the entry in that buffer. Therefore,

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.h (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/temp_serializer.h Thu Jan 21 21:39:22 2016
@@ -182,6 +182,12 @@ typedef struct svn_fs_x__ede_baton_t
   /** Current length of the in-txn in-disk representation of the directory.
    * SVN_INVALID_FILESIZE if unknown. */
   svn_filesize_t txn_filesize;
+
+  /** Will be set by the callback.  If FALSE, the cached data is out of date.
+   * We need this indicator because the svn_cache__t interface will always
+   * report the lookup as a success (FOUND==TRUE) if the generic lookup was
+   * successful -- regardless of what the entry extraction callback does. */
+  svn_boolean_t out_of_date;
 } svn_fs_x__ede_baton_t;
 
 /**

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/transaction.c Thu Jan 21 21:39:22 2016
@@ -2290,7 +2290,7 @@ rep_write_get_baton(rep_write_baton_t **
                                                        b->local_pool),
                               b->local_pool);
 
-  SVN_ERR(svn_fs_x__get_file_offset(&b->rep_offset, file, b->local_pool));
+  SVN_ERR(svn_io_file_get_offset(&b->rep_offset, file, b->local_pool));
 
   /* Get the base for this delta. */
   SVN_ERR(choose_delta_base(&base_rep, fs, noderev, FALSE, b->local_pool));
@@ -2313,8 +2313,7 @@ rep_write_get_baton(rep_write_baton_t **
                                      b->local_pool));
 
   /* Now determine the offset of the actual svndiff data. */
-  SVN_ERR(svn_fs_x__get_file_offset(&b->delta_start, file,
-                                    b->local_pool));
+  SVN_ERR(svn_io_file_get_offset(&b->delta_start, file, b->local_pool));
 
   /* Cleanup in case something goes wrong. */
   apr_pool_cleanup_register(b->local_pool, b, rep_write_cleanup,
@@ -2526,7 +2525,7 @@ rep_write_contents_close(void *baton)
   SVN_ERR(svn_stream_close(b->delta_stream));
 
   /* Determine the length of the svndiff data. */
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->local_pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, b->file, b->local_pool));
   rep->size = offset - b->delta_start;
 
   /* Fill in the rest of the representation field. */
@@ -2578,7 +2577,7 @@ rep_write_contents_close(void *baton)
       noderev_id.number = rep->id.number;
 
       entry.offset = b->rep_offset;
-      SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->local_pool));
+      SVN_ERR(svn_io_file_get_offset(&offset, b->file, b->local_pool));
       entry.size = offset - b->rep_offset;
       entry.type = SVN_FS_X__ITEM_TYPE_FILE_REP;
       entry.item_count = 1;
@@ -2817,7 +2816,7 @@ write_container_delta_rep(svn_fs_x__repr
   SVN_ERR(choose_delta_base(&base_rep, fs, noderev, is_props, scratch_pool));
   SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, FALSE, scratch_pool));
 
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
 
   /* Write out the rep header. */
   if (base_rep)
@@ -2838,7 +2837,7 @@ write_container_delta_rep(svn_fs_x__repr
                                                            scratch_pool),
                                   scratch_pool);
   SVN_ERR(svn_fs_x__write_rep_header(&header, file_stream, scratch_pool));
-  SVN_ERR(svn_fs_x__get_file_offset(&delta_start, file, scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&delta_start, file, scratch_pool));
 
   /* Prepare to write the svndiff data. */
   svn_txdelta_to_svndiff3(&diff_wh,
@@ -2887,7 +2886,7 @@ write_container_delta_rep(svn_fs_x__repr
       svn_fs_x__id_t noderev_id;
 
       /* Write out our cosmetic end marker. */
-      SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, scratch_pool));
+      SVN_ERR(svn_io_file_get_offset(&rep_end, file, scratch_pool));
       SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
       SVN_ERR(svn_stream_close(file_stream));
 
@@ -2900,7 +2899,7 @@ write_container_delta_rep(svn_fs_x__repr
       noderev_id.number = rep->id.number;
 
       entry.offset = offset;
-      SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+      SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
       entry.size = offset - entry.offset;
       entry.type = item_type;
       entry.item_count = 1;
@@ -3154,7 +3153,7 @@ write_final_rev(svn_fs_x__id_t *new_id_p
   if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
     noderev->copyroot_rev = rev;
 
-  SVN_ERR(svn_fs_x__get_file_offset(&my_offset, file, scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&my_offset, file, scratch_pool));
 
   SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset,
                                 noderev->noderev_id.number, scratch_pool));
@@ -3213,7 +3212,7 @@ write_final_rev(svn_fs_x__id_t *new_id_p
   noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
 
   entry.offset = my_offset;
-  SVN_ERR(svn_fs_x__get_file_offset(&my_offset, file, scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&my_offset, file, scratch_pool));
   entry.size = my_offset - entry.offset;
   entry.type = SVN_FS_X__ITEM_TYPE_NODEREV;
   entry.item_count = 1;
@@ -3273,7 +3272,7 @@ write_final_changed_path_info(apr_off_t
   svn_fs_x__id_t rev_item
     = {SVN_INVALID_REVNUM, SVN_FS_X__ITEM_INDEX_CHANGES};
 
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
 
   /* write to target file & calculate checksum */
   stream = svn_checksum__wrap_write_stream_fnv1a_32x4(&entry.fnv1_checksum,
@@ -3287,7 +3286,7 @@ write_final_changed_path_info(apr_off_t
 
   /* reference changes from the indexes */
   entry.offset = offset;
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
   entry.size = offset - entry.offset;
   entry.type = SVN_FS_X__ITEM_TYPE_CHANGES;
   entry.item_count = 1;
@@ -3782,7 +3781,7 @@ commit_body(void *baton,
      ### not complete for any reason the transaction will be lost. */
   SVN_ERR(get_writable_final_rev(&proto_file, cb->fs, txn_id, new_rev,
                                  batch, subpool));
-  SVN_ERR(svn_fs_x__get_file_offset(&initial_offset, proto_file, subpool));
+  SVN_ERR(svn_io_file_get_offset(&initial_offset, proto_file, subpool));
   svn_pool_clear(subpool);
 
   /* Write out all the node-revisions and directory contents. */

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/tree.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/tree.c Thu Jan 21 21:39:22 2016
@@ -388,26 +388,6 @@ x_node_created_path(const char **created
 }
 
 
-/* Set *KIND_P to the type of node located at PATH under ROOT.
-   Perform temporary allocations in SCRATCH_POOL. */
-static svn_error_t *
-node_kind(svn_node_kind_t *kind_p,
-          svn_fs_root_t *root,
-          const char *path,
-          apr_pool_t *scratch_pool)
-{
-  dag_node_t *node;
-
-  /* Get the node id. */
-  SVN_ERR(svn_fs_x__get_temp_dag_node(&node, root, path, scratch_pool));
-
-  /* Use the node id to get the real kind. */
-  *kind_p = svn_fs_x__dag_node_kind(node);
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Set *KIND_P to the type of node present at PATH under ROOT.  If
    PATH does not exist under ROOT, set *KIND_P to svn_node_none.  Use
    SCRATCH_POOL for temporary allocation. */
@@ -417,7 +397,16 @@ svn_fs_x__check_path(svn_node_kind_t *ki
                      const char *path,
                      apr_pool_t *scratch_pool)
 {
-  svn_error_t *err = node_kind(kind_p, root, path, scratch_pool);
+  dag_node_t *node;
+
+  /* Get the node id. */
+  svn_error_t *err = svn_fs_x__get_temp_dag_node(&node, root, path,
+                                                 scratch_pool);
+
+  /* Use the node id to get the real kind. */
+  if (!err)
+    *kind_p = svn_fs_x__dag_node_kind(node);
+
   if (err &&
       ((err->apr_err == SVN_ERR_FS_NOT_FOUND)
        || (err->apr_err == SVN_ERR_FS_NOT_DIRECTORY)))

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/util.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/util.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/util.c Thu Jan 21 21:39:22 2016
@@ -644,22 +644,6 @@ svn_fs_x__try_stringbuf_from_file(svn_st
 
 /* Fetch the current offset of FILE into *OFFSET_P. */
 svn_error_t *
-svn_fs_x__get_file_offset(apr_off_t *offset_p,
-                          apr_file_t *file,
-                          apr_pool_t *scratch_pool)
-{
-  apr_off_t offset;
-
-  /* Note that, for buffered files, one (possibly surprising) side-effect
-     of this call is to flush any unwritten data to disk. */
-  offset = 0;
-  SVN_ERR(svn_io_file_seek(file, APR_CUR, &offset, scratch_pool));
-  *offset_p = offset;
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_fs_x__read_content(svn_stringbuf_t **content,
                        const char *fname,
                        apr_pool_t *result_pool)

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/util.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/util.h (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/util.h Thu Jan 21 21:39:22 2016
@@ -422,13 +422,6 @@ svn_fs_x__try_stringbuf_from_file(svn_st
                                   svn_boolean_t last_attempt,
                                   apr_pool_t *result_pool);
 
-/* Fetch the current offset of FILE into *OFFSET_P.
- * Perform temporary allocations in SCRATCH_POOL. */
-svn_error_t *
-svn_fs_x__get_file_offset(apr_off_t *offset_p,
-                          apr_file_t *file,
-                          apr_pool_t *scratch_pool);
-
 /* Read the file FNAME and store the contents in *BUF.
    Allocations are performed in RESULT_POOL. */
 svn_error_t *

Modified: subversion/branches/parallel-put/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_fs_x/verify.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_fs_x/verify.c Thu Jan 21 21:39:22 2016
@@ -448,8 +448,8 @@ expect_buffer_nul(svn_fs_x__revision_fil
         const char *file_name;
         apr_off_t offset;
 
-        SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
-        SVN_ERR(svn_fs_x__rev_file_offset(&offset, file));
+        SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
+        SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
         offset -= size - i;
 
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,

Modified: subversion/branches/parallel-put/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_ra_local/ra_plugin.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_ra_local/ra_plugin.c Thu Jan 21 21:39:22 2016
@@ -1362,7 +1362,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
           if (dirent_fields & SVN_DIRENT_SIZE)
             {
               /* size  */
-              if (entry->kind == svn_node_dir)
+              if (fs_entry->kind == svn_node_dir)
                 entry->size = 0;
               else
                 SVN_ERR(svn_fs_file_length(&(entry->size), root,

Modified: subversion/branches/parallel-put/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_ra_serf/commit.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_ra_serf/commit.c Thu Jan 21 21:39:22 2016
@@ -170,11 +170,11 @@ typedef struct file_context_t {
   const char *copy_path;
   svn_revnum_t copy_revision;
 
-  /* stream */
+  /* Stream for collecting the svndiff. */
   svn_stream_t *stream;
 
-  /* Temporary file containing the svndiff. */
-  apr_file_t *svndiff;
+  /* Buffer holding the svndiff (can spill to disk). */
+  svn_ra_serf__request_body_t *svndiff;
 
   /* Our base checksum as reported by the WC. */
   const char *base_checksum;
@@ -869,35 +869,6 @@ proppatch_resource(svn_ra_serf__session_
 
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
-create_put_body(serf_bucket_t **body_bkt,
-                void *baton,
-                serf_bucket_alloc_t *alloc,
-                apr_pool_t *pool /* request pool */,
-                apr_pool_t *scratch_pool)
-{
-  file_context_t *ctx = baton;
-  apr_off_t offset;
-
-  /* We need to flush the file, make it unbuffered (so that it can be
-   * zero-copied via mmap), and reset the position before attempting to
-   * deliver the file.
-   *
-   * N.B. If we have APR 1.3+, we can unbuffer the file to let us use mmap
-   * and zero-copy the PUT body.  However, on older APR versions, we can't
-   * check the buffer status; but serf will fall through and create a file
-   * bucket for us on the buffered svndiff handle.
-   */
-  SVN_ERR(svn_io_file_flush(ctx->svndiff, pool));
-  apr_file_buffer_set(ctx->svndiff, NULL, 0);
-  offset = 0;
-  SVN_ERR(svn_io_file_seek(ctx->svndiff, APR_SET, &offset, pool));
-
-  *body_bkt = serf_bucket_file_create(ctx->svndiff, alloc);
-  return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra_serf__request_body_delegate_t */
-static svn_error_t *
 create_empty_put_body(serf_bucket_t **body_bkt,
                       void *baton,
                       serf_bucket_alloc_t *alloc,
@@ -1877,23 +1848,6 @@ open_file(const char *path,
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_stream_lazyopen_func_t for apply_textdelta */
-static svn_error_t *
-delayed_commit_stream_open(svn_stream_t **stream,
-                           void *baton,
-                           apr_pool_t *result_pool,
-                           apr_pool_t *scratch_pool)
-{
-  file_context_t *file_ctx = baton;
-
-  SVN_ERR(svn_io_open_unique_file3(&file_ctx->svndiff, NULL, NULL,
-                                   svn_io_file_del_on_pool_cleanup,
-                                   file_ctx->pool, scratch_pool));
-
-  *stream = svn_stream_from_aprfile2(file_ctx->svndiff, TRUE, result_pool);
-  return SVN_NO_ERROR;
-}
-
 static svn_error_t *
 apply_textdelta(void *file_baton,
                 const char *base_checksum,
@@ -1905,12 +1859,12 @@ apply_textdelta(void *file_baton,
   int svndiff_version;
   int compression_level;
 
-  /* Store the stream in a temporary file; we'll give it to serf when we
+  /* Construct a holder for the request body; we'll give it to serf when we
    * close this file.
    *
    * TODO: There should be a way we can stream the request body instead of
-   * writing to a temporary file (ugh). A special svn stream serf bucket
-   * that returns EAGAIN until we receive the done call?  But, when
+   * possibly writing to a temporary file (ugh). A special svn stream serf
+   * bucket that returns EAGAIN until we receive the done call?  But, when
    * would we run through the serf context?  Grr.
    *
    * BH: If you wait to a specific event... why not use that event to
@@ -1923,8 +1877,10 @@ apply_textdelta(void *file_baton,
    *     for sure after the request is completely available.
    */
 
-  ctx->stream = svn_stream_lazyopen_create(delayed_commit_stream_open,
-                                           ctx, FALSE, ctx->pool);
+  ctx->svndiff =
+    svn_ra_serf__request_body_create(SVN_RA_SERF__REQUEST_BODY_IN_MEM_SIZE,
+                                     ctx->pool);
+  ctx->stream = svn_ra_serf__request_body_get_stream(ctx->svndiff);
 
   if (ctx->commit_ctx->session->supports_svndiff1 &&
       ctx->commit_ctx->session->using_compression)
@@ -1949,7 +1905,9 @@ apply_textdelta(void *file_baton,
       compression_level = SVN_DELTA_COMPRESSION_LEVEL_NONE;
     }
 
-  svn_txdelta_to_svndiff3(handler, handler_baton, ctx->stream,
+  /* Disown the stream; we'll close it explicitly in close_file(). */
+  svn_txdelta_to_svndiff3(handler, handler_baton,
+                          svn_stream_disown(ctx->stream, pool),
                           svndiff_version, compression_level, pool);
 
   if (base_checksum)
@@ -2016,8 +1974,11 @@ close_file(void *file_baton,
         }
       else
         {
-          handler->body_delegate = create_put_body;
-          handler->body_delegate_baton = ctx;
+          SVN_ERR(svn_stream_close(ctx->stream));
+
+          svn_ra_serf__request_body_get_delegate(&handler->body_delegate,
+                                                 &handler->body_delegate_baton,
+                                                 ctx->svndiff);
           handler->body_type = SVN_SVNDIFF_MIME_TYPE;
         }
 
@@ -2035,8 +1996,9 @@ close_file(void *file_baton,
         return svn_error_trace(svn_ra_serf__unexpected_status(handler));
     }
 
+  /* Don't keep open file handles longer than necessary. */
   if (ctx->svndiff)
-    SVN_ERR(svn_io_file_close(ctx->svndiff, scratch_pool));
+    SVN_ERR(svn_ra_serf__request_body_cleanup(ctx->svndiff, scratch_pool));
 
   /* If we had any prop changes, push them via PROPPATCH. */
   if (apr_hash_count(ctx->prop_changes))

Modified: subversion/branches/parallel-put/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_ra_serf/ra_serf.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/parallel-put/subversion/libsvn_ra_serf/ra_serf.h Thu Jan 21 21:39:22 2016
@@ -1570,6 +1570,39 @@ svn_ra_serf__uri_parse(apr_uri_t *uri,
                        apr_pool_t *result_pool);
 
 
+/* Default limit for in-memory size of a request body. */
+#define SVN_RA_SERF__REQUEST_BODY_IN_MEM_SIZE 256 * 1024
+
+/* An opaque structure used to prepare a request body. */
+typedef struct svn_ra_serf__request_body_t svn_ra_serf__request_body_t;
+
+/* Constructor for svn_ra_serf__request_body_t.  Creates a new writable
+   buffer for the request body.  Request bodies under IN_MEMORY_SIZE
+   bytes will be held in memory, otherwise, the body content will be
+   spilled to a temporary file. */
+svn_ra_serf__request_body_t *
+svn_ra_serf__request_body_create(apr_size_t in_memory_size,
+                                 apr_pool_t *result_pool);
+
+/* Get the writable stream associated with BODY. */
+svn_stream_t *
+svn_ra_serf__request_body_get_stream(svn_ra_serf__request_body_t *body);
+
+/* Get a svn_ra_serf__request_body_delegate_t and baton for BODY. */
+void
+svn_ra_serf__request_body_get_delegate(svn_ra_serf__request_body_delegate_t *del,
+                                       void **baton,
+                                       svn_ra_serf__request_body_t *body);
+
+/* Release intermediate resources associated with BODY.  These resources
+   (such as open file handles) will be automatically released when the
+   pool used to construct BODY is cleared or destroyed, but this optional
+   function allows doing that explicitly. */
+svn_error_t *
+svn_ra_serf__request_body_cleanup(svn_ra_serf__request_body_t *body,
+                                  apr_pool_t *scratch_pool);
+
+
 #if defined(SVN_DEBUG)
 /* Wrapper macros to collect file and line information */
 #define svn_ra_serf__wrap_err \

Modified: subversion/branches/parallel-put/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_ra_serf/update.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_ra_serf/update.c Thu Jan 21 21:39:22 2016
@@ -433,13 +433,11 @@ struct report_context_t {
   const svn_delta_editor_t *editor;
   void *editor_baton;
 
-  /* The file holding request body for the REPORT.
-   *
-   * ### todo: It will be better for performance to store small
-   * request bodies (like 4k) in memory and bigger bodies on disk.
-   */
+  /* Stream for collecting the request body. */
   svn_stream_t *body_template;
-  body_create_baton_t *body;
+
+  /* Buffer holding request body for the REPORT (can spill to disk). */
+  svn_ra_serf__request_body_t *body;
 
   /* number of pending GET requests */
   unsigned int num_active_fetches;
@@ -457,148 +455,6 @@ struct report_context_t {
   svn_boolean_t closed_root;
 };
 
-/* Baton for collecting REPORT body. Depending on the size this
-   work is backed by a memory buffer (via serf buckets) or by
-   a file */
-struct body_create_baton_t
-{
-  apr_pool_t *result_pool;
-  apr_size_t total_bytes;
-
-  apr_pool_t *scratch_pool;
-
-  serf_bucket_alloc_t *alloc;
-  serf_bucket_t *collect_bucket;
-
-  const void *all_data;
-  apr_file_t *file;
-};
-
-
-#define MAX_BODY_IN_RAM (256*1024)
-
-/* Fold all previously collected data in a single buffer allocated in
-   RESULT_POOL and clear all intermediate state */
-static const char *
-body_allocate_all(body_create_baton_t *body,
-                  apr_pool_t *result_pool)
-{
-  char *buffer = apr_pcalloc(result_pool, body->total_bytes);
-  const char *data;
-  apr_size_t sz;
-  apr_status_t s;
-  apr_size_t remaining = body->total_bytes;
-  char *next = buffer;
-
-  while (!(s = serf_bucket_read(body->collect_bucket, remaining, &data, &sz)))
-    {
-      memcpy(next, data, sz);
-      remaining -= sz;
-      next += sz;
-
-      if (! remaining)
-        break;
-    }
-
-  if (!SERF_BUCKET_READ_ERROR(s))
-    {
-      memcpy(next, data, sz);
-    }
-
-  serf_bucket_destroy(body->collect_bucket);
-  body->collect_bucket = NULL;
-
-  return (s != APR_EOF) ? NULL : buffer;
-}
-
-/* Noop function. Make serf take care of freeing in error situations */
-static void serf_free_no_error(void *unfreed_baton, void *block) {}
-
-/* Stream write function for body creation */
-static svn_error_t *
-body_write_fn(void *baton,
-              const char *data,
-              apr_size_t *len)
-{
-  body_create_baton_t *bcb = baton;
-
-  if (!bcb->scratch_pool)
-    bcb->scratch_pool = svn_pool_create(bcb->result_pool);
-
-  if (bcb->file)
-    {
-      SVN_ERR(svn_io_file_write_full(bcb->file, data, *len, NULL,
-                                     bcb->scratch_pool));
-      svn_pool_clear(bcb->scratch_pool);
-
-      bcb->total_bytes += *len;
-    }
-  else if (*len + bcb->total_bytes > MAX_BODY_IN_RAM)
-    {
-      SVN_ERR(svn_io_open_unique_file3(&bcb->file, NULL, NULL,
-                                       svn_io_file_del_on_pool_cleanup,
-                                       bcb->result_pool, bcb->scratch_pool));
-
-      if (bcb->total_bytes)
-        {
-          const char *all = body_allocate_all(bcb, bcb->scratch_pool);
-
-          SVN_ERR(svn_io_file_write_full(bcb->file, all, bcb->total_bytes,
-                                         NULL, bcb->scratch_pool));
-        }
-
-      SVN_ERR(svn_io_file_write_full(bcb->file, data, *len, NULL,
-                                     bcb->scratch_pool));
-      bcb->total_bytes += *len;
-    }
-  else
-    {
-      if (!bcb->alloc)
-        bcb->alloc = serf_bucket_allocator_create(bcb->scratch_pool,
-                                                  serf_free_no_error, NULL);
-
-      if (!bcb->collect_bucket)
-        bcb->collect_bucket = serf_bucket_aggregate_create(bcb->alloc);
-
-      serf_bucket_aggregate_append(bcb->collect_bucket,
-                                   serf_bucket_simple_copy_create(data, *len,
-                                                                  bcb->alloc));
-
-      bcb->total_bytes += *len;
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Stream close function for collecting body */
-static svn_error_t *
-body_done_fn(void *baton)
-{
-  body_create_baton_t *bcb = baton;
-  if (bcb->file)
-    {
-      /* We need to flush the file, make it unbuffered (so that it can be
-        * zero-copied via mmap), and reset the position before attempting
-        * to deliver the file.
-        *
-        * N.B. If we have APR 1.3+, we can unbuffer the file to let us use
-        * mmap and zero-copy the PUT body.  However, on older APR versions,
-        * we can't check the buffer status; but serf will fall through and
-        * create a file bucket for us on the buffered handle.
-        */
-
-      SVN_ERR(svn_io_file_flush(bcb->file, bcb->scratch_pool));
-      apr_file_buffer_set(bcb->file, NULL, 0);
-    }
-  else if (bcb->collect_bucket)
-    bcb->all_data = body_allocate_all(bcb, bcb->result_pool);
-
-  if (bcb->scratch_pool)
-    svn_pool_destroy(bcb->scratch_pool);
-
-  return SVN_NO_ERROR;
-}
-
 static svn_error_t *
 create_dir_baton(dir_baton_t **new_dir,
                  report_context_t *ctx,
@@ -2313,37 +2169,6 @@ link_path(void *report_baton,
   return APR_SUCCESS;
 }
 
-/* Serf callback to create update request body bucket.
-   Implements svn_ra_serf__request_body_delegate_t */
-static svn_error_t *
-create_update_report_body(serf_bucket_t **body_bkt,
-                          void *baton,
-                          serf_bucket_alloc_t *alloc,
-                          apr_pool_t *pool /* request pool */,
-                          apr_pool_t *scratch_pool)
-{
-  report_context_t *report = baton;
-  body_create_baton_t *body = report->body;
-
-  if (body->file)
-    {
-      apr_off_t offset;
-
-      offset = 0;
-      SVN_ERR(svn_io_file_seek(body->file, APR_SET, &offset, pool));
-
-      *body_bkt = serf_bucket_file_create(report->body->file, alloc);
-    }
-  else
-    {
-      *body_bkt = serf_bucket_simple_create(body->all_data,
-                                            body->total_bytes,
-                                            NULL, NULL, alloc);
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* Serf callback to setup update request headers. */
 static svn_error_t *
 setup_update_report_headers(serf_bucket_t *headers,
@@ -2684,10 +2509,11 @@ finish_report(void *report_baton,
   handler = svn_ra_serf__create_expat_handler(sess, xmlctx, NULL,
                                               scratch_pool);
 
+  svn_ra_serf__request_body_get_delegate(&handler->body_delegate,
+                                         &handler->body_delegate_baton,
+                                         report->body);
   handler->method = "REPORT";
   handler->path = report_target;
-  handler->body_delegate = create_update_report_body;
-  handler->body_delegate_baton = report;
   handler->body_type = "text/xml";
   handler->custom_accept_encoding = TRUE;
   handler->header_delegate = setup_update_report_headers;
@@ -2802,11 +2628,10 @@ make_update_reporter(svn_ra_session_t *r
   *reporter = &ra_serf_reporter;
   *report_baton = report;
 
-  report->body = apr_pcalloc(report->pool, sizeof(*report->body));
-  report->body->result_pool = report->pool;
-  report->body_template = svn_stream_create(report->body, report->pool);
-  svn_stream_set_write(report->body_template, body_write_fn);
-  svn_stream_set_close(report->body_template, body_done_fn);
+  report->body =
+    svn_ra_serf__request_body_create(SVN_RA_SERF__REQUEST_BODY_IN_MEM_SIZE,
+                                     report->pool);
+  report->body_template = svn_ra_serf__request_body_get_stream(report->body);
 
   if (sess->bulk_updates == svn_tristate_true)
     {

Modified: subversion/branches/parallel-put/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_repos/commit.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_repos/commit.c Thu Jan 21 21:39:22 2016
@@ -210,15 +210,16 @@ invoke_commit_cb(svn_commit_callback2_t
   /* const */ svn_string_t *date;
   /* const */ svn_string_t *author;
   svn_commit_info_t *commit_info;
+  apr_hash_t *revprops;
 
   if (commit_cb == NULL)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_fs_revision_prop2(&date, fs, revision, SVN_PROP_REVISION_DATE,
-                                TRUE, scratch_pool, scratch_pool));
-  SVN_ERR(svn_fs_revision_prop2(&author, fs, revision,
-                                SVN_PROP_REVISION_AUTHOR,
-                                TRUE, scratch_pool, scratch_pool));
+  SVN_ERR(svn_fs_revision_proplist2(&revprops, fs, revision,
+                                    TRUE, scratch_pool, scratch_pool));
+
+  date = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+  author = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
 
   commit_info = svn_create_commit_info(scratch_pool);
 

Modified: subversion/branches/parallel-put/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_repos/delta.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_repos/delta.c Thu Jan 21 21:39:22 2016
@@ -603,19 +603,6 @@ send_text_delta(struct context *c,
     }
 }
 
-svn_error_t *
-svn_repos__compare_files(svn_boolean_t *changed_p,
-                         svn_fs_root_t *root1,
-                         const char *path1,
-                         svn_fs_root_t *root2,
-                         const char *path2,
-                         apr_pool_t *pool)
-{
-  return svn_error_trace(svn_fs_contents_different(changed_p, root1, path1,
-                                                   root2, path2, pool));
-}
-
-
 /* Make the appropriate edits on FILE_BATON to change its contents and
    properties from those in SOURCE_PATH to those in TARGET_PATH. */
 static svn_error_t *

Modified: subversion/branches/parallel-put/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_repos/reporter.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_repos/reporter.c Thu Jan 21 21:39:22 2016
@@ -522,19 +522,13 @@ delta_proplists(report_baton_t *b, svn_r
 {
   svn_fs_root_t *s_root;
   apr_hash_t *s_props = NULL, *t_props;
-  apr_array_header_t *prop_diffs;
-  int i;
   svn_revnum_t crev;
-  revision_info_t *revision_info;
-  svn_boolean_t changed;
-  const svn_prop_t *pc;
-  svn_lock_t *lock;
-  apr_hash_index_t *hi;
 
   /* Fetch the created-rev and send entry props. */
   SVN_ERR(svn_fs_node_created_rev(&crev, b->t_root, t_path, pool));
   if (SVN_IS_VALID_REVNUM(crev))
     {
+      revision_info_t *revision_info;
       /* convert committed-rev to  string */
       char buf[SVN_INT64_BUFFER_SIZE];
       svn_string_t cr_str;
@@ -565,6 +559,7 @@ delta_proplists(report_baton_t *b, svn_r
   /* Update lock properties. */
   if (lock_token)
     {
+      svn_lock_t *lock;
       SVN_ERR(svn_fs_get_lock(&lock, b->repos->fs, t_path, pool));
 
       /* Delete a defunct lock. */
@@ -575,6 +570,7 @@ delta_proplists(report_baton_t *b, svn_r
 
   if (s_path)
     {
+      svn_boolean_t changed;
       SVN_ERR(get_source_root(b, &s_root, s_rev));
 
       /* Is this deltification worth our time? */
@@ -592,16 +588,20 @@ delta_proplists(report_baton_t *b, svn_r
 
   if (s_props && apr_hash_count(s_props))
     {
+      apr_array_header_t *prop_diffs;
+      int i;
+
       /* Now transmit the differences. */
       SVN_ERR(svn_prop_diffs(&prop_diffs, t_props, s_props, pool));
       for (i = 0; i < prop_diffs->nelts; i++)
         {
-          pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
+          const svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
           SVN_ERR(change_fn(b, object, pc->name, pc->value, pool));
         }
     }
   else if (apr_hash_count(t_props))
     {
+      apr_hash_index_t *hi;
       /* So source, i.e. all new.  Transmit all target props. */
       for (hi = apr_hash_first(pool, t_props); hi; hi = apr_hash_next(hi))
         {
@@ -671,7 +671,6 @@ delta_files(report_baton_t *b, void *fil
             const char *s_path, const char *t_path, const char *lock_token,
             apr_pool_t *pool)
 {
-  svn_boolean_t changed;
   svn_fs_root_t *s_root = NULL;
   svn_txdelta_stream_t *dstream = NULL;
   svn_checksum_t *s_checksum;
@@ -685,14 +684,15 @@ delta_files(report_baton_t *b, void *fil
 
   if (s_path)
     {
+      svn_boolean_t changed;
       SVN_ERR(get_source_root(b, &s_root, s_rev));
 
       /* We're not interested in the theoretical difference between "has
          contents which have not changed with respect to" and "has the same
          actual contents as" when sending text-deltas.  If we know the
          delta is an empty one, we avoiding sending it in either case. */
-      SVN_ERR(svn_repos__compare_files(&changed, b->t_root, t_path,
-                                       s_root, s_path, pool));
+      SVN_ERR(svn_fs_contents_different(&changed, b->t_root, t_path,
+                                        s_root, s_path, pool));
 
       if (!changed)
         return SVN_NO_ERROR;

Modified: subversion/branches/parallel-put/subversion/libsvn_repos/repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_repos/repos.h?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_repos/repos.h (original)
+++ subversion/branches/parallel-put/subversion/libsvn_repos/repos.h Thu Jan 21 21:39:22 2016
@@ -390,17 +390,6 @@ svn_repos__authz_validate(svn_authz_t *a
 
 /*** Utility Functions ***/
 
-/* Set *CHANGED_P to TRUE if ROOT1/PATH1 and ROOT2/PATH2 have
-   different contents, FALSE if they have the same contents.
-   Use POOL for temporary allocation. */
-svn_error_t *
-svn_repos__compare_files(svn_boolean_t *changed_p,
-                         svn_fs_root_t *root1,
-                         const char *path1,
-                         svn_fs_root_t *root2,
-                         const char *path2,
-                         apr_pool_t *pool);
-
 /* Set *PREV_PATH and *PREV_REV to the path and revision which
    represent the location at which PATH in FS was located immediately
    prior to REVISION iff there was a copy operation (to PATH or one of

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/cache-membuffer.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/cache-membuffer.c Thu Jan 21 21:39:22 2016
@@ -147,6 +147,10 @@
 #endif
 
 /* For more efficient copy operations, let's align all data items properly.
+ * Since we can't portably align pointers, this is rather the item size
+ * granularity which ensures *relative* alignment within the cache - still
+ * giving us decent copy speeds on most machines.
+ *
  * Must be a power of 2.
  */
 #define ITEM_ALIGNMENT 16
@@ -814,10 +818,6 @@ struct svn_membuffer_t
  */
 #define ALIGN_VALUE(value) (((value) + ITEM_ALIGNMENT-1) & -ITEM_ALIGNMENT)
 
-/* Align POINTER value to the next ITEM_ALIGNMENT boundary.
- */
-#define ALIGN_POINTER(pointer) ((void*)ALIGN_VALUE((apr_size_t)(char*)(pointer)))
-
 /* If locking is supported for CACHE, acquire a read lock for it.
  */
 static svn_error_t *
@@ -1827,28 +1827,6 @@ ensure_data_insertable_l1(svn_membuffer_
    * right answer. */
 }
 
-/* Mimic apr_pcalloc in APR_POOL_DEBUG mode, i.e. handle failed allocations
- * (e.g. OOM) properly: Allocate at least SIZE bytes from POOL and zero
- * the content of the allocated memory if ZERO has been set. Return NULL
- * upon failed allocations.
- *
- * Also, satisfy our buffer alignment needs for performance reasons.
- */
-static void* secure_aligned_alloc(apr_pool_t *pool,
-                                  apr_size_t size,
-                                  svn_boolean_t zero)
-{
-  void* memory = apr_palloc(pool, size + ITEM_ALIGNMENT);
-  if (memory != NULL)
-    {
-      memory = ALIGN_POINTER(memory);
-      if (zero)
-        memset(memory, 0, size);
-    }
-
-  return memory;
-}
-
 svn_error_t *
 svn_cache__membuffer_cache_create(svn_membuffer_t **cache,
                                   apr_size_t total_size,
@@ -2017,10 +1995,11 @@ svn_cache__membuffer_cache_create(svn_me
       c[seg].l2.last = NO_INDEX;
       c[seg].l2.next = NO_INDEX;
       c[seg].l2.start_offset = c[seg].l1.size;
-      c[seg].l2.size = data_size - c[seg].l1.size;
+      c[seg].l2.size = ALIGN_VALUE(data_size) - c[seg].l1.size;
       c[seg].l2.current_data = c[seg].l2.start_offset;
 
-      c[seg].data = secure_aligned_alloc(pool, (apr_size_t)data_size, FALSE);
+      /* This cast is safe because DATA_SIZE <= MAX_SEGMENT_SIZE. */
+      c[seg].data = apr_palloc(pool, (apr_size_t)ALIGN_VALUE(data_size));
       c[seg].data_used = 0;
       c[seg].max_entry_size = max_entry_size;
 
@@ -2219,18 +2198,13 @@ membuffer_cache_set_internal(svn_membuff
   /* first, look for a previous entry for the given key */
   entry_t *entry = find_entry(cache, group_index, to_find, FALSE);
 
-  /* Quick size check to make sure arithmetics will work further down
-   * the road. */
-  if (   cache->max_entry_size >= item_size
-      && cache->max_entry_size - item_size >= to_find->entry_key.key_len)
-    {
-      size = item_size + to_find->entry_key.key_len;
-    }
-  else
-    {
-      /* The combination of serialized ITEM and KEY does not fit, so the
-       * the insertion attempt will fail and simply remove any old entry
-       * if that exists. */
+  /* Quick check make sure arithmetics will work further down the road. */
+  size = item_size + to_find->entry_key.key_len;
+  if (size < item_size)
+    {
+      /* Arithmetic overflow, so combination of serialized ITEM and KEY
+       * cannot not fit into the cache.  Setting BUFFER to NULL will cause
+       * the removal of any entry if that exists without writing new data. */
       buffer = NULL;
     }
 
@@ -2414,7 +2388,7 @@ membuffer_cache_get_internal(svn_membuff
     }
 
   size = ALIGN_VALUE(entry->size) - entry->key.key_len;
-  *buffer = ALIGN_POINTER(apr_palloc(result_pool, size + ITEM_ALIGNMENT-1));
+  *buffer = apr_palloc(result_pool, size);
   memcpy(*buffer, cache->data + entry->offset + entry->key.key_len, size);
 
 #ifdef SVN_DEBUG_CACHE_MEMBUFFER

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/eol.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/eol.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/eol.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/eol.c Thu Jan 21 21:39:22 2016
@@ -33,43 +33,32 @@
 char *
 svn_eol__find_eol_start(char *buf, apr_size_t len)
 {
-#if !SVN_UNALIGNED_ACCESS_IS_OK
-
-  /* On some systems, we need to make sure that BUF is properly aligned
-   * for chunky data access. This overhead is still justified because
-   * only lines tend to be tens of chars long.
-   */
-  for (; (len > 0) && ((apr_uintptr_t)buf) & (sizeof(apr_uintptr_t)-1)
-       ; ++buf, --len)
-  {
-    if (*buf == '\n' || *buf == '\r')
-      return buf;
-  }
-
-#endif
+#if SVN_UNALIGNED_ACCESS_IS_OK
 
   /* Scan the input one machine word at a time. */
   for (; len > sizeof(apr_uintptr_t)
        ; buf += sizeof(apr_uintptr_t), len -= sizeof(apr_uintptr_t))
-  {
-    /* This is a variant of the well-known strlen test: */
-    apr_uintptr_t chunk = *(const apr_uintptr_t *)buf;
-
-    /* A byte in SVN__R_TEST is \0, iff it was \r in *BUF.
-     * Similarly, SVN__N_TEST is an indicator for \n. */
-    apr_uintptr_t r_test = chunk ^ SVN__R_MASK;
-    apr_uintptr_t n_test = chunk ^ SVN__N_MASK;
-
-    /* A byte in SVN__R_TEST can only be < 0x80, iff it has been \0 before
-     * (i.e. \r in *BUF). Ditto for SVN__N_TEST. */
-    r_test |= (r_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
-    n_test |= (n_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
-
-    /* Check whether at least one of the words contains a byte <0x80
-     * (if one is detected, there was a \r or \n in CHUNK). */
-    if ((r_test & n_test & SVN__BIT_7_SET) != SVN__BIT_7_SET)
-      break;
-  }
+    {
+      /* This is a variant of the well-known strlen test: */
+      apr_uintptr_t chunk = *(const apr_uintptr_t *)buf;
+
+      /* A byte in SVN__R_TEST is \0, iff it was \r in *BUF.
+       * Similarly, SVN__N_TEST is an indicator for \n. */
+      apr_uintptr_t r_test = chunk ^ SVN__R_MASK;
+      apr_uintptr_t n_test = chunk ^ SVN__N_MASK;
+
+      /* A byte in SVN__R_TEST can only be < 0x80, iff it has been \0 before
+       * (i.e. \r in *BUF). Ditto for SVN__N_TEST. */
+      r_test |= (r_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
+      n_test |= (n_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
+
+      /* Check whether at least one of the words contains a byte <0x80
+       * (if one is detected, there was a \r or \n in CHUNK). */
+      if ((r_test & n_test & SVN__BIT_7_SET) != SVN__BIT_7_SET)
+        break;
+    }
+
+#endif
 
   /* The remaining odd bytes will be examined the naive way: */
   for (; len > 0; ++buf, --len)

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/io.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/io.c Thu Jan 21 21:39:22 2016
@@ -1568,8 +1568,14 @@ get_default_file_perms(apr_fileperms_t *
 
         Using svn_io_open_uniquely_named() here because other tempfile
         creation functions tweak the permission bits of files they create.
+
+        Note that APR pool structures are allocated as the first item
+        in their first memory page (with e.g. 4kB granularity), i.e. the
+        lower bits tend to be identical between pool instances.  That is
+        particularly true for the MMAPed allocator.
       */
       randomish = ((apr_uint32_t)(apr_uintptr_t)scratch_pool
+                   + (apr_uint32_t)((apr_uintptr_t)scratch_pool / 4096)
                    + (apr_uint32_t)apr_time_now());
       fname_base = apr_psprintf(scratch_pool, "svn-%08x", randomish);
 

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/path.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/path.c Thu Jan 21 21:39:22 2016
@@ -506,7 +506,7 @@ get_path_ancestor_length(const char *pat
   else
     if (last_dirsep == 0 && path1[0] == '/' && path2[0] == '/')
       return 1;
-    return last_dirsep;
+  return last_dirsep;
 }
 
 

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/pool.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/pool.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/pool.c Thu Jan 21 21:39:22 2016
@@ -54,6 +54,13 @@ abort_on_pool_failure(int retcode)
   /* Don't translate this string! It requires memory allocation to do so!
      And we don't have any of it... */
   printf("libsvn: Out of memory - terminating application.\n");
+
+#ifdef WIN32
+  /* Provide a way to distinguish the out-of-memory error from abort(). */
+  if (retcode == APR_ENOMEM)
+    RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, NULL);
+#endif
+
   abort();
   return 0; /* not reached */
 }

Modified: subversion/branches/parallel-put/subversion/libsvn_subr/utf_validate.c
URL: http://svn.apache.org/viewvc/subversion/branches/parallel-put/subversion/libsvn_subr/utf_validate.c?rev=1726108&r1=1726107&r2=1726108&view=diff
==============================================================================
--- subversion/branches/parallel-put/subversion/libsvn_subr/utf_validate.c (original)
+++ subversion/branches/parallel-put/subversion/libsvn_subr/utf_validate.c Thu Jan 21 21:39:22 2016
@@ -258,24 +258,7 @@ static const char machine [9][14] = {
 static const char *
 first_non_fsm_start_char(const char *data, apr_size_t max_len)
 {
-#if !SVN_UNALIGNED_ACCESS_IS_OK
-
-  /* On some systems, we need to make sure that buf is properly aligned
-   * for chunky data access.
-   */
-  if ((apr_uintptr_t)data & (sizeof(apr_uintptr_t)-1))
-    {
-      apr_size_t len = (~(apr_uintptr_t)data) & (sizeof(apr_uintptr_t)-1);
-      if (len > max_len)
-        len = max_len;
-      max_len -= len;
-
-      for (; len > 0; ++data, --len)
-        if ((unsigned char)*data >= 0x80)
-          return data;
-    }
-
-#endif
+#if SVN_UNALIGNED_ACCESS_IS_OK
 
   /* Scan the input one machine word at a time. */
   for (; max_len > sizeof(apr_uintptr_t)
@@ -283,55 +266,11 @@ first_non_fsm_start_char(const char *dat
     if (*(const apr_uintptr_t *)data & SVN__BIT_7_SET)
       break;
 
-  /* The remaining odd bytes will be examined the naive way: */
-  for (; max_len > 0; ++data, --max_len)
-    if ((unsigned char)*data >= 0x80)
-      break;
-
-  return data;
-}
-
-/* Scan the C string in *DATA for chars that are not in the octet
- * category 0 (FSM_START).  Return the position of either the such
- * char or of the terminating NUL.
- */
-static const char *
-first_non_fsm_start_char_cstring(const char *data)
-{
-  /* We need to make sure that BUF is properly aligned for chunky data
-   * access because we don't know the string's length. Unaligned chunk
-   * read access beyond the NUL terminator could therefore result in a
-   * segfault.
-   */
-  for (; (apr_uintptr_t)data & (sizeof(apr_uintptr_t)-1); ++data)
-    if (*data == 0 || (unsigned char)*data >= 0x80)
-      return data;
-
-  /* Scan the input one machine word at a time. */
-#ifndef SVN_UTF_NO_UNINITIALISED_ACCESS
-  /* This may read allocated but uninitialised bytes beyond the
-     terminating null.  Any such bytes are always readable and this
-     code operates correctly whatever the uninitialised values happen
-     to be.  However memory checking tools such as valgrind and GCC
-     4.8's address santitizer will object so this bit of code can be
-     disabled at compile time. */
-  for (; ; data += sizeof(apr_uintptr_t))
-    {
-      /* Check for non-ASCII chars: */
-      apr_uintptr_t chunk = *(const apr_uintptr_t *)data;
-      if (chunk & SVN__BIT_7_SET)
-        break;
-
-      /* This is the well-known strlen test: */
-      chunk |= (chunk & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
-      if ((chunk & SVN__BIT_7_SET) != SVN__BIT_7_SET)
-        break;
-    }
 #endif
 
   /* The remaining odd bytes will be examined the naive way: */
-  for (; ; ++data)
-    if (*data == 0 || (unsigned char)*data >= 0x80)
+  for (; max_len > 0; ++data, --max_len)
+    if ((unsigned char)*data >= 0x80)
       break;
 
   return data;
@@ -359,20 +298,10 @@ svn_utf__last_valid(const char *data, ap
 svn_boolean_t
 svn_utf__cstring_is_valid(const char *data)
 {
-  int state = FSM_START;
-
   if (!data)
     return FALSE;
 
-  data = first_non_fsm_start_char_cstring(data);
-
-  while (*data)
-    {
-      unsigned char octet = *data++;
-      int category = octet_category[octet];
-      state = machine[state][category];
-    }
-  return state == FSM_START;
+  return svn_utf__is_valid(data, strlen(data));
 }
 
 svn_boolean_t




Mime
View raw message