You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ko...@apache.org on 2016/09/02 16:23:45 UTC

svn commit: r1758987 - in /subversion/trunk/subversion: include/private/svn_io_private.h libsvn_subr/stream.c libsvn_subr/subst.c

Author: kotkov
Date: Fri Sep  2 16:23:45 2016
New Revision: 1758987

URL: http://svn.apache.org/viewvc?rev=1758987&view=rev
Log:
Remove the "is buffered" (svn_stream__is_buffered_fn_t) handler for streams.

This handler allowed us to distinguish (in an inverted manner) APR file
or string-based streams that benefit from the chunky implementation of
svn_stream_readline().

Since we now have a custom readline handler and these streams have their
specific readline implementations, the svn_stream__is_buffered_fn_t isn't
required anymore.

* subversion/include/svn_io.h
  (svn_stream__is_buffered_fn_t, svn_stream__set_is_buffered,
   svn_stream__is_buffered): Remove.

* subversion/libsvn_subr/stream.c
  (svn_stream_t): Remove the 'is_buffered_fn' field.
  (svn_stream__set_is_buffered, svn_stream__is_buffered,
   is_buffered_handler_empty, is_buffered_handler_disown,
   is_buffered_handler_apr, is_buffered_handler_stringbuf,
   is_buffered_handler_string, is_buffered_lazyopen,
   stream_readline_chunky): Remove these functions.
  (svn_stream_empty, svn_stream_disown, make_stream_from_apr_file,
   svn_stream_from_stringbuf, svn_stream_from_string,
   svn_stream_lazyopen_create): Don't install the is_buffered handler.
  (stream_readline): Remove the special handling for buffered and seekable
   streams.  Then, inline this function ...
  (svn_stream_readline): ..here.
  (stream_readline_bytewise): Tweak the docstring to note that this is
   now the default (fallback) implementation.

* subversion/libsvn_subr/subst.c
  (translated_stream_is_buffered): Remove.
  (stream_translated): Don't install the is_buffered handler.  We don't
   provide a specific readline implementation (although it is possible) for
   these streams, because they already have internal buffering, and have an
   optimized code path for reading a single byte.

Modified:
    subversion/trunk/subversion/include/private/svn_io_private.h
    subversion/trunk/subversion/libsvn_subr/stream.c
    subversion/trunk/subversion/libsvn_subr/subst.c

Modified: subversion/trunk/subversion/include/private/svn_io_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_io_private.h?rev=1758987&r1=1758986&r2=1758987&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_io_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_io_private.h Fri Sep  2 16:23:45 2016
@@ -85,32 +85,6 @@ svn_io__file_lock_autocreate(const char
                              apr_pool_t *pool);
 
 
-/** Buffer test handler function for a generic stream. @see svn_stream_t
- * and svn_stream__is_buffered().
- *
- * @since New in 1.7.
- */
-typedef svn_boolean_t (*svn_stream__is_buffered_fn_t)(void *baton);
-
-/** Set @a stream's buffer test function to @a is_buffered_fn
- *
- * @since New in 1.7.
- */
-void
-svn_stream__set_is_buffered(svn_stream_t *stream,
-                            svn_stream__is_buffered_fn_t is_buffered_fn);
-
-/** Return whether this generic @a stream uses internal buffering.
- * This may be used to work around subtle differences between buffered
- * and non-buffered APR files.  A lazy-open stream cannot report the
- * true buffering state until after the lazy open: a stream that
- * initially reports as non-buffered may report as buffered later.
- *
- * @since New in 1.7.
- */
-svn_boolean_t
-svn_stream__is_buffered(svn_stream_t *stream);
-
 /** Return the underlying file, if any, associated with the stream, or
  * NULL if not available.  Accessing the file bypasses the stream.
  */

Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=1758987&r1=1758986&r2=1758987&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Fri Sep  2 16:23:45 2016
@@ -61,7 +61,6 @@ struct svn_stream_t {
   svn_stream_mark_fn_t mark_fn;
   svn_stream_seek_fn_t seek_fn;
   svn_stream_data_available_fn_t data_available_fn;
-  svn_stream__is_buffered_fn_t is_buffered_fn;
   svn_stream_readline_fn_t readline_fn;
   apr_file_t *file; /* Maybe NULL */
 };
@@ -140,13 +139,6 @@ svn_stream_set_data_available(svn_stream
 }
 
 void
-svn_stream__set_is_buffered(svn_stream_t *stream,
-                            svn_stream__is_buffered_fn_t is_buffered_fn)
-{
-  stream->is_buffered_fn = is_buffered_fn;
-}
-
-void
 svn_stream_set_readline(svn_stream_t *stream,
                         svn_stream_readline_fn_t readline_fn)
 {
@@ -273,15 +265,6 @@ svn_stream_data_available(svn_stream_t *
                                                    data_available));
 }
 
-svn_boolean_t
-svn_stream__is_buffered(svn_stream_t *stream)
-{
-  if (stream->is_buffered_fn == NULL)
-    return FALSE;
-
-  return stream->is_buffered_fn(stream->baton);
-}
-
 svn_error_t *
 svn_stream_close(svn_stream_t *stream)
 {
@@ -336,7 +319,7 @@ svn_stream_printf_from_utf8(svn_stream_t
   return svn_error_trace(svn_stream_puts(stream, translated));
 }
 
-/* Guts of svn_stream_readline().
+/* Default implementation for svn_stream_readline().
  * Returns the line read from STREAM in *STRINGBUF, and indicates
  * end-of-file in *EOF.  If DETECT_EOL is TRUE, the end-of-line indicator
  * is detected automatically and returned in *EOL.
@@ -389,150 +372,6 @@ stream_readline_bytewise(svn_stringbuf_t
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-stream_readline_chunky(svn_stringbuf_t **stringbuf,
-                       svn_boolean_t *eof,
-                       const char *eol,
-                       svn_stream_t *stream,
-                       apr_pool_t *pool)
-{
-  /* Read larger chunks of data at once into this buffer and scan
-   * that for EOL. A good chunk size should be about 80 chars since
-   * most text lines will be shorter. However, don't use a much
-   * larger value because filling the buffer from the stream takes
-   * time as well.
-   */
-  char buffer[SVN__LINE_CHUNK_SIZE+1];
-
-  /* variables */
-  svn_stream_mark_t *mark;
-  apr_size_t numbytes;
-  const char *eol_pos;
-  apr_size_t total_parsed = 0;
-
-  /* invariant for this call */
-  const size_t eol_len = strlen(eol);
-
-  /* Remember the line start so this plus the line length will be
-   * the position to move to at the end of this function.
-   */
-  SVN_ERR(svn_stream_mark(stream, &mark, pool));
-
-  /* Read the first chunk. */
-  numbytes = SVN__LINE_CHUNK_SIZE;
-  SVN_ERR(svn_stream_read_full(stream, buffer, &numbytes));
-  buffer[numbytes] = '\0';
-
-  /* Look for the EOL in this first chunk. If we find it, we are done here.
-   */
-  eol_pos = strstr(buffer, eol);
-  if (eol_pos != NULL)
-    {
-      *stringbuf = svn_stringbuf_ncreate(buffer, eol_pos - buffer, pool);
-      total_parsed = eol_pos - buffer + eol_len;
-    }
-  else if (numbytes < SVN__LINE_CHUNK_SIZE)
-    {
-      /* We hit EOF but not EOL.
-       */
-      *stringbuf = svn_stringbuf_ncreate(buffer, numbytes, pool);
-      *eof = TRUE;
-      return SVN_NO_ERROR;
-     }
-  else
-    {
-      /* A larger buffer for the string is needed. */
-      svn_stringbuf_t *str;
-      str = svn_stringbuf_create_ensure(2*SVN__LINE_CHUNK_SIZE, pool);
-      svn_stringbuf_appendbytes(str, buffer, numbytes);
-      *stringbuf = str;
-
-      /* Loop reading chunks until an EOL was found. If we hit EOF, fall
-       * back to the standard implementation. */
-      do
-      {
-        /* Append the next chunk to the string read so far.
-         */
-        svn_stringbuf_ensure(str, str->len + SVN__LINE_CHUNK_SIZE);
-        numbytes = SVN__LINE_CHUNK_SIZE;
-        SVN_ERR(svn_stream_read_full(stream, str->data + str->len, &numbytes));
-        str->len += numbytes;
-        str->data[str->len] = '\0';
-
-        /* Look for the EOL in the new data plus the last part of the
-         * previous chunk because the EOL may span over the boundary
-         * between both chunks.
-         */
-        eol_pos = strstr(str->data + str->len - numbytes - (eol_len-1), eol);
-
-        if ((numbytes < SVN__LINE_CHUNK_SIZE) && (eol_pos == NULL))
-        {
-          /* We hit EOF instead of EOL. */
-          *eof = TRUE;
-          return SVN_NO_ERROR;
-        }
-      }
-      while (eol_pos == NULL);
-
-      /* Number of bytes we actually consumed (i.e. line + EOF).
-       * We need to "return" the rest to the stream by moving its
-       * read pointer.
-       */
-      total_parsed = eol_pos - str->data + eol_len;
-
-      /* Terminate the string at the EOL postion and return it. */
-      str->len = eol_pos - str->data;
-      str->data[str->len] = 0;
-    }
-
-  /* Move the stream read pointer to the first position behind the EOL.
-   */
-  SVN_ERR(svn_stream_seek(stream, mark));
-  return svn_error_trace(svn_stream_skip(stream, total_parsed));
-}
-
-/* Default implementation for svn_stream_readline().
- * Returns the line read from STREAM in *STRINGBUF, and indicates
- * end-of-file in *EOF.  EOL must point to the desired end-of-line
- * indicator.  STRINGBUF is allocated in POOL. */
-static svn_error_t *
-stream_readline(svn_stringbuf_t **stringbuf,
-                svn_boolean_t *eof,
-                const char *eol,
-                svn_stream_t *stream,
-                apr_pool_t *pool)
-{
-  *eof = FALSE;
-
-  /* Often, we operate on APR file or string-based streams and know what
-   * EOL we are looking for. Optimize that common case.
-   */
-  if (svn_stream_supports_mark(stream) &&
-      svn_stream__is_buffered(stream))
-    {
-      /* We can efficiently read chunks speculatively and reposition the
-       * stream pointer to the end of the line once we found that.
-       */
-      SVN_ERR(stream_readline_chunky(stringbuf,
-                                     eof,
-                                     eol,
-                                     stream,
-                                     pool));
-    }
-  else
-    {
-      /* Use the standard byte-byte implementation.
-       */
-      SVN_ERR(stream_readline_bytewise(stringbuf,
-                                       eof,
-                                       eol,
-                                       stream,
-                                       pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_stream_readline(svn_stream_t *stream,
                     svn_stringbuf_t **stringbuf,
@@ -548,7 +387,7 @@ svn_stream_readline(svn_stream_t *stream
   else
     {
       /* Use the default implementation. */
-      SVN_ERR(stream_readline(stringbuf, eof, eol, stream, pool));
+      SVN_ERR(stream_readline_bytewise(stringbuf, eof, eol, stream, pool));
     }
 
   return SVN_NO_ERROR;
@@ -682,11 +521,6 @@ seek_handler_empty(void *baton, const sv
   return SVN_NO_ERROR;
 }
 
-static svn_boolean_t
-is_buffered_handler_empty(void *baton)
-{
-  return FALSE;
-}
 
 
 svn_stream_t *
@@ -699,7 +533,6 @@ svn_stream_empty(apr_pool_t *pool)
   svn_stream_set_write(stream, write_handler_empty);
   svn_stream_set_mark(stream, mark_handler_empty);
   svn_stream_set_seek(stream, seek_handler_empty);
-  svn_stream__set_is_buffered(stream, is_buffered_handler_empty);
   return stream;
 }
 
@@ -806,12 +639,6 @@ data_available_disown(void *baton, svn_b
   return svn_error_trace(svn_stream_data_available(baton, data_available));
 }
 
-static svn_boolean_t
-is_buffered_handler_disown(void *baton)
-{
-  return svn_stream__is_buffered(baton);
-}
-
 static svn_error_t *
 readline_handler_disown(void *baton,
                         svn_stringbuf_t **stringbuf,
@@ -834,7 +661,6 @@ svn_stream_disown(svn_stream_t *stream,
   svn_stream_set_mark(s, mark_handler_disown);
   svn_stream_set_seek(s, seek_handler_disown);
   svn_stream_set_data_available(s, data_available_disown);
-  svn_stream__set_is_buffered(s, is_buffered_handler_disown);
   svn_stream_set_readline(s, readline_handler_disown);
 
   return s;
@@ -1027,13 +853,6 @@ data_available_handler_apr(void *baton,
 #endif
 }
 
-static svn_boolean_t
-is_buffered_handler_apr(void *baton)
-{
-  struct baton_apr *btn = baton;
-  return (apr_file_flags_get(btn->file) & APR_BUFFERED) != 0;
-}
-
 static svn_error_t *
 readline_handler_apr(void *baton,
                      svn_stringbuf_t **stringbuf,
@@ -1178,7 +997,6 @@ make_stream_from_apr_file(apr_file_t *fi
     }
 
   svn_stream_set_data_available(stream, data_available_handler_apr);
-  svn_stream__set_is_buffered(stream, is_buffered_handler_apr);
   stream->file = file;
 
   if (! disown)
@@ -1743,12 +1561,6 @@ data_available_handler_stringbuf(void *b
   return SVN_NO_ERROR;
 }
 
-static svn_boolean_t
-is_buffered_handler_stringbuf(void *baton)
-{
-  return TRUE;
-}
-
 static svn_error_t *
 readline_handler_stringbuf(void *baton,
                            svn_stringbuf_t **stringbuf,
@@ -1800,7 +1612,6 @@ svn_stream_from_stringbuf(svn_stringbuf_
   svn_stream_set_mark(stream, mark_handler_stringbuf);
   svn_stream_set_seek(stream, seek_handler_stringbuf);
   svn_stream_set_data_available(stream, data_available_handler_stringbuf);
-  svn_stream__set_is_buffered(stream, is_buffered_handler_stringbuf);
   svn_stream_set_readline(stream, readline_handler_stringbuf);
   return stream;
 }
@@ -1880,12 +1691,6 @@ data_available_handler_string(void *bato
   return SVN_NO_ERROR;
 }
 
-static svn_boolean_t
-is_buffered_handler_string(void *baton)
-{
-  return TRUE;
-}
-
 static svn_error_t *
 readline_handler_string(void *baton,
                         svn_stringbuf_t **stringbuf,
@@ -1936,7 +1741,6 @@ svn_stream_from_string(const svn_string_
   svn_stream_set_seek(stream, seek_handler_string);
   svn_stream_set_skip(stream, skip_handler_string);
   svn_stream_set_data_available(stream, data_available_handler_string);
-  svn_stream__set_is_buffered(stream, is_buffered_handler_string);
   svn_stream_set_readline(stream, readline_handler_string);
   return stream;
 }
@@ -2186,19 +1990,6 @@ data_available_handler_lazyopen(void *ba
                                                    data_available));
 }
 
-/* Implements svn_stream__is_buffered_fn_t */
-static svn_boolean_t
-is_buffered_lazyopen(void *baton)
-{
-  lazyopen_baton_t *b = baton;
-
-  /* No lazy open as we cannot handle an open error. */
-  if (!b->real_stream)
-    return FALSE;
-
-  return svn_stream__is_buffered(b->real_stream);
-}
-
 /* Implements svn_stream_readline_fn_t */
 static svn_error_t *
 readline_handler_lazyopen(void *baton,
@@ -2238,7 +2029,6 @@ svn_stream_lazyopen_create(svn_stream_la
   svn_stream_set_mark(stream, mark_handler_lazyopen);
   svn_stream_set_seek(stream, seek_handler_lazyopen);
   svn_stream_set_data_available(stream, data_available_handler_lazyopen);
-  svn_stream__set_is_buffered(stream, is_buffered_lazyopen);
   svn_stream_set_readline(stream, readline_handler_lazyopen);
 
   return stream;

Modified: subversion/trunk/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/subst.c?rev=1758987&r1=1758986&r2=1758987&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/subst.c (original)
+++ subversion/trunk/subversion/libsvn_subr/subst.c Fri Sep  2 16:23:45 2016
@@ -1431,14 +1431,6 @@ translated_stream_seek(void *baton, cons
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_stream__is_buffered_fn_t. */
-static svn_boolean_t
-translated_stream_is_buffered(void *baton)
-{
-  struct translated_stream_baton *b = baton;
-  return svn_stream__is_buffered(b->stream);
-}
-
 svn_error_t *
 svn_subst_read_specialfile(svn_stream_t **stream,
                            const char *path,
@@ -1548,7 +1540,6 @@ stream_translated(svn_stream_t *stream,
   svn_stream_set_close(s, translated_stream_close);
   svn_stream_set_mark(s, translated_stream_mark);
   svn_stream_set_seek(s, translated_stream_seek);
-  svn_stream__set_is_buffered(s, translated_stream_is_buffered);
 
   return s;
 }