In ra_neon, cache starting props when first seen, to reduce round trips.

Patch by: Daniel Shahaf <d.s@daniel.shahaf.co.il>
(Tweaked by me.)

* subversion/libsvn_ra_neon/ra_neon.h
  (svn_ra_neon__session_t):  New member 'vcc'.
  (svn_ra_neon__get_starting_props,
   svn_ra_neon__search_for_starting_props): Document the caching
     behavior, because it's visible and we now depend on it.

* subversion/libsvn_ra_neon/props.c
  (svn_ra_neon__get_starting_props):  Cache VCC and UUID in the session.
  (svn_ra_neon__get_vcc):  Look in the cache first.
  (svn_ra_neon__get_baseline_props):
    Call __get_vcc() to get the VCC.
    Change local variable 'vcc' to 'const char *' from 'svn_string_t *'.
  (svn_ra_neon__get_baseline_info):
    Call __get_starting_props() instead of calling
    svn_ra_neon__get_props_resource() directly.

* subversion/libsvn_ra_neon/session.c
  (svn_ra_neon__open):  Initialize cached fields to NULL.
  (svn_ra_neon__do_get_uuid):  Rely on __get_starting_props() to cache
    the UUID.

* subversion/libsvn_ra_neon/commit.c (apply_revprops):
    Call __get_vcc() to get the VCC, to take advantage of the cache.


git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@870740 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/subversion/libsvn_ra_neon/commit.c b/subversion/libsvn_ra_neon/commit.c
index c6d8acf..77e7d73 100644
--- a/subversion/libsvn_ra_neon/commit.c
+++ b/subversion/libsvn_ra_neon/commit.c
@@ -1371,7 +1371,7 @@
                                     apr_hash_t *revprop_table,
                                     apr_pool_t *pool)
 {
-  const svn_string_t *vcc;
+  const char *vcc;
   const svn_string_t *baseline_url;
   version_rsrc_t baseline_rsrc = { SVN_INVALID_REVNUM };
   svn_error_t *err = NULL;
@@ -1381,8 +1381,7 @@
      ### REPORT when that is available on the server. */
 
   /* fetch the DAV:version-controlled-configuration from the session's URL */
-  SVN_ERR(svn_ra_neon__get_one_prop(&vcc, cc->ras, cc->ras->root.path,
-                                    NULL, &svn_ra_neon__vcc_prop, pool));
+  SVN_ERR(svn_ra_neon__get_vcc(&vcc, cc->ras, cc->ras->root.path, pool));
 
   /* ### we should use DAV:apply-to-version on the CHECKOUT so we can skip
      ### retrieval of the baseline */
@@ -1394,7 +1393,7 @@
     /* Get the latest baseline from VCC's DAV:checked-in property.
        This should give us the HEAD revision of the moment. */
     SVN_ERR(svn_ra_neon__get_one_prop(&baseline_url, cc->ras,
-                                      vcc->data, NULL,
+                                      vcc, NULL,
                                       &svn_ra_neon__checked_in_prop, pool));
     baseline_rsrc.pool = pool;
     baseline_rsrc.vsn_url = baseline_url->data;
diff --git a/subversion/libsvn_ra_neon/props.c b/subversion/libsvn_ra_neon/props.c
index 7e63e84..1877f0f 100644
--- a/subversion/libsvn_ra_neon/props.c
+++ b/subversion/libsvn_ra_neon/props.c
@@ -638,8 +638,32 @@
                                               const char *label,
                                               apr_pool_t *pool)
 {
-  return svn_ra_neon__get_props_resource(rsrc, sess, url, label, starting_props,
-                                         pool);
+  svn_string_t *propval;
+
+  SVN_ERR(svn_ra_neon__get_props_resource(rsrc, sess, url, label,
+                                          starting_props, pool));
+
+  /* Cache some of the resource information. */
+
+  if (! sess->vcc)
+    {
+      propval = apr_hash_get((*rsrc)->propset,
+                             SVN_RA_NEON__PROP_VCC,
+                             APR_HASH_KEY_STRING);
+      if (propval)
+        sess->vcc = apr_pstrdup(sess->pool, propval->data);
+    }
+
+  if (! sess->uuid)
+    {
+      propval = apr_hash_get((*rsrc)->propset,
+                             SVN_RA_NEON__PROP_REPOSITORY_UUID,
+                             APR_HASH_KEY_STRING);
+      if (propval)
+        sess->uuid = apr_pstrdup(sess->pool, propval->data);
+    }
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -747,9 +771,13 @@
 {
   svn_ra_neon__resource_t *rsrc;
   const char *lopped_path;
-  const svn_string_t *vcc_s;
 
-  /* ### Someday, possibly look for memory-cached VCC in the RA session. */
+  /* Look for memory-cached VCC in the RA session. */
+  if (sess->vcc)
+    {
+      *vcc = sess->vcc;
+      return SVN_NO_ERROR;
+    }
 
   /* ### Someday, possibly look for disk-cached VCC via get_wcprop callback. */
 
@@ -757,14 +785,15 @@
   SVN_ERR(svn_ra_neon__search_for_starting_props(&rsrc, &lopped_path,
                                                  sess, url, pool));
 
-  vcc_s = apr_hash_get(rsrc->propset,
-                       SVN_RA_NEON__PROP_VCC, APR_HASH_KEY_STRING);
-  if (! vcc_s)
-    return svn_error_create(APR_EGENERAL, NULL,
-                             _("The VCC property was not found on the "
-                               "resource"));
+  if (! sess->vcc)
+    {
+      /* ### better error reporting... */
+      return svn_error_create(APR_EGENERAL, NULL,
+                              _("The VCC property was not found on the "
+                                "resource"));
+    }
 
-  *vcc = vcc_s->data;
+  *vcc = sess->vcc;
   return SVN_NO_ERROR;
 }
 
@@ -778,7 +807,7 @@
                                              apr_pool_t *pool)
 {
   svn_ra_neon__resource_t *rsrc;
-  const svn_string_t *vcc;
+  const char *vcc;
   const svn_string_t *relative_path;
   const char *my_bc_relative;
   const char *lopped_path;
@@ -809,7 +838,7 @@
   SVN_ERR(svn_ra_neon__search_for_starting_props(&rsrc, &lopped_path,
                                                  sess, url, pool));
 
-  vcc = apr_hash_get(rsrc->propset, SVN_RA_NEON__PROP_VCC, APR_HASH_KEY_STRING);
+  SVN_ERR(svn_ra_neon__get_vcc(&vcc, sess, url, pool));
   if (vcc == NULL)
     {
       /* ### better error reporting... */
@@ -881,7 +910,7 @@
       /* Get the Baseline from the DAV:checked-in value, then fetch its
          DAV:baseline-collection property. */
       /* ### should wrap this with info about rsrc==VCC */
-      SVN_ERR(svn_ra_neon__get_one_prop(&baseline, sess, vcc->data, NULL,
+      SVN_ERR(svn_ra_neon__get_one_prop(&baseline, sess, vcc, NULL,
                                         &svn_ra_neon__checked_in_prop, pool));
 
       /* ### do we want to optimize the props we fetch, based on what the
@@ -902,7 +931,7 @@
 
       /* ### do we want to optimize the props we fetch, based on what the
          ### user asked for? i.e. omit version-name if latest_rev is NULL */
-      SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, vcc->data, label,
+      SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, vcc, label,
                                               which_props, pool));
     }
 
@@ -982,8 +1011,8 @@
       const char *full_bc_url = svn_path_url_add_component(my_bc_url->data,
                                                            my_bc_rel.data,
                                                            pool);
-      SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, full_bc_url,
-                                              NULL, starting_props, pool));
+      SVN_ERR(svn_ra_neon__get_starting_props(&rsrc, sess, full_bc_url,
+                                              NULL, pool));
       *is_dir = rsrc->is_collection;
     }
 
diff --git a/subversion/libsvn_ra_neon/ra_neon.h b/subversion/libsvn_ra_neon/ra_neon.h
index 0e28703..39ff009 100644
--- a/subversion/libsvn_ra_neon/ra_neon.h
+++ b/subversion/libsvn_ra_neon/ra_neon.h
@@ -98,6 +98,10 @@
   svn_auth_iterstate_t *p11pin_iterstate; /* state of PKCS#11 pin retries */
 
   svn_boolean_t compression;            /* should we use http compression? */
+
+  /* Both of these function as caches, and are NULL when uninitialized
+     or cleared: */
+  const char *vcc;                      /* version-controlled-configuration */
   const char *uuid;                     /* repository UUID */
 
   svn_ra_progress_notify_func_t progress_func;
@@ -423,7 +427,10 @@
                                               const ne_propname *which_props,
                                               apr_pool_t *pool);
 
-/* fetch a single resource's starting props from the server. */
+/* fetch a single resource's starting props from the server.
+
+   Cache the version-controlled-configuration in SESS->vcc, and the
+   repository uuid in SESS->uuid. */
 svn_error_t * svn_ra_neon__get_starting_props(svn_ra_neon__resource_t **rsrc,
                                               svn_ra_neon__session_t *sess,
                                               const char *url,
@@ -437,7 +444,10 @@
 
    Also return *MISSING_PATH (allocated in POOL), which is the
    trailing portion of the URL that did not exist.  If an error
-   occurs, *MISSING_PATH isn't changed. */
+   occurs, *MISSING_PATH isn't changed. 
+
+   Cache the version-controlled-configuration in SESS->vcc, and the
+   repository uuid in SESS->uuid. */
 svn_error_t *
 svn_ra_neon__search_for_starting_props(svn_ra_neon__resource_t **rsrc,
                                        const char **missing_path,
diff --git a/subversion/libsvn_ra_neon/session.c b/subversion/libsvn_ra_neon/session.c
index e96760b..2e48a70 100644
--- a/subversion/libsvn_ra_neon/session.c
+++ b/subversion/libsvn_ra_neon/session.c
@@ -1143,6 +1143,8 @@
   ras->progress_baton = callbacks->progress_baton;
   ras->progress_func = callbacks->progress_func;
   ras->capabilities = apr_hash_make(ras->pool);
+  ras->vcc = NULL;
+  ras->uuid = NULL;
   /* save config and server group in the auth parameter hash */
   svn_auth_set_parameter(ras->callbacks->auth_baton,
                          SVN_AUTH_PARAM_CONFIG, cfg);
@@ -1323,31 +1325,24 @@
     {
       svn_ra_neon__resource_t *rsrc;
       const char *lopped_path;
-      const svn_string_t *uuid_propval;
 
       SVN_ERR(svn_ra_neon__search_for_starting_props(&rsrc, &lopped_path,
                                                      ras, ras->url->data,
                                                      pool));
       SVN_ERR(svn_ra_neon__maybe_store_auth_info(ras, pool));
 
-      uuid_propval = apr_hash_get(rsrc->propset,
-                                  SVN_RA_NEON__PROP_REPOSITORY_UUID,
-                                  APR_HASH_KEY_STRING);
-      if (uuid_propval == NULL)
-        /* ### better error reporting... */
-        return svn_error_create(APR_EGENERAL, NULL,
-                                _("The UUID property was not found on the "
-                                  "resource or any of its parents"));
-
-      if (uuid_propval && (uuid_propval->len > 0))
-        ras->uuid = apr_pstrdup(ras->pool, uuid_propval->data); /* cache */
-      else
-        return svn_error_create
-          (SVN_ERR_RA_NO_REPOS_UUID, NULL,
-           _("Please upgrade the server to 0.19 or later"));
+      if (! ras->uuid)
+        {
+          /* ### better error reporting... */
+          return svn_error_create(APR_EGENERAL, NULL,
+                                  _("The UUID property was not found on the "
+                                    "resource or any of its parents"));
+        }
     }
 
+  /* search_for_starting_props() filled it. */
   *uuid = ras->uuid;
+
   return SVN_NO_ERROR;
 }