Author: stefan2
Date: Thu Sep 6 23:32:11 2012
New Revision: 1381800
URL: http://svn.apache.org/viewvc?rev=1381800&view=rev
Log:
Re-implement svn_io_read_length_line as this is one of the
most-called functions in SVN. Instead of reading data a byte
at a time, read 128 byte chunks and scan those.
* subversion/libsvn_subr/io.c
(svn_io_read_length_line): reimplement
Modified:
subversion/trunk/subversion/libsvn_subr/io.c
Modified: subversion/trunk/subversion/libsvn_subr/io.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?rev=1381800&r1=1381799&r2=1381800&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/io.c (original)
+++ subversion/trunk/subversion/libsvn_subr/io.c Thu Sep 6 23:32:11 2012
@@ -3427,30 +3427,60 @@ svn_error_t *
svn_io_read_length_line(apr_file_t *file, char *buf, apr_size_t *limit,
apr_pool_t *pool)
{
+ /* variables */
+ apr_size_t total_read = 0;
+ svn_boolean_t eof = FALSE;
const char *name;
svn_error_t *err;
- apr_size_t i;
- char c;
+ apr_size_t buf_size = *limit;
- for (i = 0; i < *limit; i++)
+ while (buf_size > 0)
{
- SVN_ERR(svn_io_file_getc(&c, file, pool));
- /* Note: this error could be APR_EOF, which
- is totally fine. The caller should be aware of
- this. */
-
- if (c == '\n')
+ /* read a fair chunk of data at once. But don't get too ambitious
+ * as that would result in too much waste. Also make sure we can
+ * put a NUL after the last byte read.
+ */
+ apr_size_t to_read = buf_size < 129 ? buf_size - 1 : 128;
+ apr_size_t bytes_read = 0;
+ char *eol;
+
+ /* read data block (or just a part of it) */
+ SVN_ERR(svn_io_file_read_full2(file, buf, to_read,
+ &bytes_read, &eof, pool));
+
+ /* look or a newline char */
+ buf[bytes_read] = 0;
+ eol = strchr(buf, '\n');
+ if (eol)
{
- buf[i] = '\0';
- *limit = i;
+ apr_off_t offset = (eol + 1 - buf) - bytes_read;
+
+ *eol = 0;
+ *limit = total_read + (eol - buf);
+
+ /* correct the file pointer:
+ * appear as though we just had read the newline char
+ */
+ SVN_ERR(svn_io_file_seek(file, APR_CUR, &offset, pool));
+
return SVN_NO_ERROR;
}
- else
+ else if (eof)
{
- buf[i] = c;
+ /* no EOL found but we hit the end of the file.
+ * Generate a nice EOF error object and return it.
+ */
+ char dummy;
+ SVN_ERR(svn_io_file_getc(&dummy, file, pool));
}
+
+ /* next data chunk */
+ buf_size -= bytes_read;
+ buf += bytes_read;
+ total_read += bytes_read;
}
+ /* buffer limit has been exceeded without finding the EOL */
err = svn_io_file_name_get(&name, file, pool);
if (err)
name = NULL;