Author: philip
Date: Tue Apr 23 13:04:42 2013
New Revision: 1470936

URL: http://svn.apache.org/r1470936
Log:
Significantly reduce the number of open files during a typical update
over ra_serf by using lazy-opening streams to delay opening until the
HTTP response is received.  This changes the new-in-1.8 lazy-open API.

* subversion/include/svn_io.h
  (svn_stream_lazyopen_create): Add open_on_close boolean parameter.

* subversion/libsvn_subr/stream.c
  (struct lazyopen_baton_t): Add open_on_close boolean member.
  (close_handler_lazyopen): Open if required.
  (svn_stream_lazyopen_create): Add open_on_close boolean parameter.

* subversion/libsvn_wc/update_editor.c
  (lazy_open_source, lazy_open_target, struct lazy_target_baton): New.
  (apply_textdelta): Use lazy-open streams for source and target.

* subversion/libsvn_wc/adm_ops.c
  (svn_wc__get_pristine_contents_by_checksum): Adjust call.

Modified:
    subversion/trunk/subversion/include/svn_io.h
    subversion/trunk/subversion/libsvn_subr/stream.c
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c

Modified: subversion/trunk/subversion/include/svn_io.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_io.h?rev=1470936&r1=1470935&r2=1470936&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_io.h (original)
+++ subversion/trunk/subversion/include/svn_io.h Tue Apr 23 13:04:42 2013
@@ -1387,14 +1387,15 @@ typedef svn_error_t *
  * invoked upon the first read of @a *stream which are used to open the
  * "real" source stream.
  *
- * @note If the only "access" the returned stream gets is to close it,
- * @a open_func will not be called.
+ * @note If the only "access" the returned stream gets is to close it
+ * then @a open_func will only be called if @a open_on_close is TRUE.
  *
  * @since New in 1.8.
  */
 svn_stream_t *
 svn_stream_lazyopen_create(svn_stream_lazyopen_func_t open_func,
                            void *open_baton,
+                           svn_boolean_t open_on_close,
                            apr_pool_t *result_pool);
 
 /** @} */

Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=1470936&r1=1470935&r2=1470936&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Tue Apr 23 13:04:42 2013
@@ -1676,6 +1676,9 @@ typedef struct lazyopen_baton_t {
   svn_stream_t *real_stream;
   apr_pool_t *pool;
 
+  /* Whether to open the wrapped stream on a close call. */
+  svn_boolean_t open_on_close;
+
 } lazyopen_baton_t;
 
 
@@ -1747,7 +1750,9 @@ close_handler_lazyopen(void *baton)
 {
   lazyopen_baton_t *b = baton;
 
-  if (b->real_stream != NULL)
+  if (b->open_on_close)
+    SVN_ERR(lazyopen_if_unopened(b));
+  if (b->real_stream)
     SVN_ERR(svn_stream_close(b->real_stream));
 
   return SVN_NO_ERROR;
@@ -1796,6 +1801,7 @@ is_buffered_lazyopen(void *baton)
 svn_stream_t *
 svn_stream_lazyopen_create(svn_stream_lazyopen_func_t open_func,
                            void *open_baton,
+                           svn_boolean_t open_on_close,
                            apr_pool_t *result_pool)
 {
   lazyopen_baton_t *lob = apr_pcalloc(result_pool, sizeof(*lob));
@@ -1805,6 +1811,7 @@ svn_stream_lazyopen_create(svn_stream_la
   lob->open_baton = open_baton;
   lob->real_stream = NULL;
   lob->pool = result_pool;
+  lob->open_on_close = open_on_close;
 
   stream = svn_stream_create(lob, result_pool);
   svn_stream_set_read(stream, read_handler_lazyopen);

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1470936&r1=1470935&r2=1470936&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Apr 23 13:04:42 2013
@@ -1155,7 +1155,7 @@ svn_wc__get_pristine_contents_by_checksu
       gpl_baton->checksum = checksum;
 
       *contents = svn_stream_lazyopen_create(get_pristine_lazyopen_func,
-                                             gpl_baton, result_pool);
+                                             gpl_baton, FALSE, result_pool);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1470936&r1=1470935&r2=1470936&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue Apr 23 13:04:42 
2013
@@ -3525,6 +3525,46 @@ open_file(const char *path,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+lazy_open_source(svn_stream_t **stream,
+                 void *baton,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct file_baton *fb = baton;
+
+  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, fb->edit_baton->db,
+                                   fb->local_abspath,
+                                   fb->original_checksum,
+                                   result_pool, scratch_pool));
+
+
+  return SVN_NO_ERROR;
+}
+
+struct lazy_target_baton {
+  struct file_baton *fb;
+  struct handler_baton *hb;
+  struct edit_baton *eb;
+};
+
+static svn_error_t *
+lazy_open_target(svn_stream_t **stream,
+                 void *baton,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct lazy_target_baton *tb = baton;
+
+  SVN_ERR(svn_wc__open_writable_base(stream, 
&tb->hb->new_text_base_tmp_abspath,
+                                     NULL, 
&tb->hb->new_text_base_sha1_checksum,
+                                     tb->fb->edit_baton->db,
+                                     tb->eb->wcroot_abspath,
+                                     result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* An svn_delta_editor_t function. */
 static svn_error_t *
 apply_textdelta(void *file_baton,
@@ -3537,10 +3577,10 @@ apply_textdelta(void *file_baton,
   apr_pool_t *handler_pool = svn_pool_create(fb->pool);
   struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
   struct edit_baton *eb = fb->edit_baton;
-  svn_error_t *err;
   const svn_checksum_t *recorded_base_checksum;
   svn_checksum_t *expected_base_checksum;
   svn_stream_t *source;
+  struct lazy_target_baton *tb;
   svn_stream_t *target;
 
   if (fb->skip_this)
@@ -3607,10 +3647,8 @@ apply_textdelta(void *file_baton,
       SVN_ERR_ASSERT(!fb->original_checksum
                      || fb->original_checksum->kind == svn_checksum_sha1);
 
-      SVN_ERR(svn_wc__db_pristine_read(&source, NULL, fb->edit_baton->db,
-                                       fb->local_abspath,
-                                       fb->original_checksum,
-                                       handler_pool, handler_pool));
+      source = svn_stream_lazyopen_create(lazy_open_source, fb, FALSE,
+                                          handler_pool);
     }
   else
     {
@@ -3636,16 +3674,11 @@ apply_textdelta(void *file_baton,
       hb->source_checksum_stream = source;
     }
 
-  /* Open the text base for writing (this will get us a temporary file).  */
-  err = svn_wc__open_writable_base(&target, &hb->new_text_base_tmp_abspath,
-                                   NULL, &hb->new_text_base_sha1_checksum,
-                                   fb->edit_baton->db, eb->wcroot_abspath,
-                                   handler_pool, pool);
-  if (err)
-    {
-      svn_pool_destroy(handler_pool);
-      return svn_error_trace(err);
-    }
+  tb = apr_palloc(handler_pool, sizeof(struct lazy_target_baton));
+  tb->hb = hb;
+  tb->fb = fb;
+  tb->eb = eb;
+  target = svn_stream_lazyopen_create(lazy_open_target, tb, TRUE, 
handler_pool);
 
   /* Prepare to apply the delta.  */
   svn_txdelta_apply(source, target,


Reply via email to