Author: stefan2
Date: Wed Aug  4 19:27:41 2010
New Revision: 982375

URL: http://svn.apache.org/viewvc?rev=982375&view=rev
Log:
Introduce a variant of svn_stream_from_aprfile2, that takes cached file handles
instead of APR file handles.

* subversion/include/svn_io.h
  (svn_stream_from_aprfile3): declare new API function
* subversion/libsvn_subr/stream.c
  (baton_apr): add cached_handle member
  (close_handler_cached_handle): new close() function
  (stream_from_aprfile): extract generic part from svn_stream_from_aprfile2
  (svn_stream_from_aprfile2): call stream_from_aprfile for most of the init code
  (svn_stream_from_aprfile3): implement new API function

Modified:
    subversion/branches/performance/subversion/include/svn_io.h
    subversion/branches/performance/subversion/libsvn_subr/stream.c

Modified: subversion/branches/performance/subversion/include/svn_io.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/performance/subversion/include/svn_io.h?rev=982375&r1=982374&r2=982375&view=diff
==============================================================================
--- subversion/branches/performance/subversion/include/svn_io.h (original)
+++ subversion/branches/performance/subversion/include/svn_io.h Wed Aug  4 
19:27:41 2010
@@ -923,6 +923,26 @@ svn_stream_from_aprfile2(apr_file_t *fil
                          svn_boolean_t disown,
                          apr_pool_t *pool);
 
+/* "forward-declare" svn_file_handle_cache__handle_t */
+struct svn_file_handle_cache__handle_t;
+
+/** Create a stream from a cached file handle.  For convenience, if @a file
+ * is @c NULL, an empty stream created by svn_stream_empty() is returned.
+ *
+ * This function should normally be called with @a disown set to FALSE,
+ * in which case closing the stream will also return the file handle to
+ * the respective cache object.
+ *
+ * If @a disown is TRUE, the stream will disown the file handle, meaning 
+ * that svn_stream_close() will not close the cached file handle.
+ *
+ * @since New in 1.7.
+ */
+svn_stream_t *
+svn_stream_from_aprfile3(struct svn_file_handle_cache__handle_t *file,
+                         svn_boolean_t disown,
+                         apr_pool_t *pool);
+
 /** Similar to svn_stream_from_aprfile2(), except that the file will
  * always be disowned.
  *

Modified: subversion/branches/performance/subversion/libsvn_subr/stream.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/stream.c?rev=982375&r1=982374&r2=982375&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/stream.c Wed Aug  4 
19:27:41 2010
@@ -43,7 +43,7 @@
 #include "svn_checksum.h"
 #include "svn_path.h"
 #include "private/svn_eol_private.h"
-
+#include "private/svn_file_handle_cache.h"
 
 struct svn_stream_t {
   void *baton;
@@ -579,6 +579,10 @@ struct baton_apr {
   apr_file_t *file;
   apr_pool_t *pool;
 
+  /* If not NULL, file is actually wrapped into this cached file handle
+   * and should be returned to the file handle cache asap. */
+  svn_file_handle_cache__handle_t *cached_handle;
+
   /* Offsets when reading from a range of the file.
    * When either of these is negative, no range has been specified. */
   apr_off_t start;
@@ -622,6 +626,17 @@ close_handler_apr(void *baton)
   return svn_io_file_close(btn->file, btn->pool);
 }
 
+/* Returns the cached file handle back to the respective cache object.
+ * This is call is allowed even for btn->cached_handle == NULL.
+ */
+static svn_error_t *
+close_handler_cached_handle(void *baton)
+{
+  struct baton_apr *btn = baton;
+
+  return svn_file_handle_cache__close(btn->cached_handle);
+}
+
 static svn_error_t *
 reset_handler_apr(void *baton)
 {
@@ -713,36 +728,83 @@ svn_stream_open_unique(svn_stream_t **st
   return SVN_NO_ERROR;
 }
 
+/* Common initialization code for svn_stream_from_aprfile2() and
+ * svn_stream_from_aprfile3().
+ */
+static svn_stream_t *
+stream_from_aprfile(struct baton_apr **baton,
+                    apr_file_t *file,
+                    apr_pool_t *pool)
+{
+  struct baton_apr *new_baton;
+  svn_stream_t *stream;
+
+  /* create and fully initialize the baton */
+  new_baton = apr_palloc(pool, sizeof(*new_baton));
+  new_baton->file = file;
+  new_baton->cached_handle = NULL; /* default */
+  new_baton->pool = pool;
+  new_baton->start = -1;
+  new_baton->end = -1;
+
+  /* construct the stream vtable, except for the close() function */
+  stream = svn_stream_create(new_baton, pool);
+  svn_stream_set_read(stream, read_handler_apr);
+  svn_stream_set_write(stream, write_handler_apr);
+  svn_stream_set_reset(stream, reset_handler_apr);
+  svn_stream_set_mark(stream, mark_handler_apr);
+  svn_stream_set_seek(stream, seek_handler_apr);
+
+  /* return structures */
+  *baton = new_baton;
+
+  return stream;
+}
 
 svn_stream_t *
 svn_stream_from_aprfile2(apr_file_t *file,
                          svn_boolean_t disown,
                          apr_pool_t *pool)
 {
+  /* having no file at all is a special case */
   struct baton_apr *baton;
-  svn_stream_t *stream;
-
   if (file == NULL)
     return svn_stream_empty(pool);
 
-  baton = apr_palloc(pool, sizeof(*baton));
-  baton->file = file;
-  baton->pool = pool;
-  baton->start = -1;
-  baton->end = -1;
-  stream = svn_stream_create(baton, pool);
-  svn_stream_set_read(stream, read_handler_apr);
-  svn_stream_set_write(stream, write_handler_apr);
-  svn_stream_set_reset(stream, reset_handler_apr);
-  svn_stream_set_mark(stream, mark_handler_apr);
-  svn_stream_set_seek(stream, seek_handler_apr);
+  /* construct and init the default stream structures */
+  svn_stream_t *stream = stream_from_aprfile(&baton, file, pool);
 
+  /* make sure to close the file handle after use if we own it */
   if (! disown)
     svn_stream_set_close(stream, close_handler_apr);
 
   return stream;
 }
 
+svn_stream_t *
+svn_stream_from_aprfile3(svn_file_handle_cache__handle_t *file,
+                         svn_boolean_t disown,
+                         apr_pool_t *pool)
+{
+  struct baton_apr *baton;
+
+  /* having no file at all is a special case (file == NULL is legal, too) */
+  apr_file_t *apr_file = svn_file_handle_cache__get_apr_handle(file);
+  if (apr_file == NULL)
+    return svn_stream_empty(pool);
+
+  /* construct and init the default stream structures */
+  svn_stream_t *stream = stream_from_aprfile(&baton, apr_file, pool);
+
+  /* store the cached file handle and return it to the cache after use,
+   * if we own it */
+  baton->cached_handle = file;
+  if (! disown)
+    svn_stream_set_close(stream, close_handler_cached_handle);
+
+  return stream;
+}
+
 /* A read handler (#svn_read_fn_t) that forwards to read_handler_apr()
    but only allows reading between BATON->start and BATON->end. */
 static svn_error_t *


Reply via email to