On Sat, Aug 14, 2010 at 7:20 PM, <stefan2_at_apache.org> wrote:
> Author: stefan2
> Date: Sun Aug 15 00:20:34 2010
> New Revision: 985606
>
> URL: http://svn.apache.org/viewvc?rev=985606&view=rev
> Log:
> Increase the RA_SVN throughput by reducing the overhead in read_item for
> packing received data into various structures.
>
> * subversion/libsvn_ra_svn/marshal.c
> (readbuf_getchar): suggest inlining to the compiler
> (read_long_string): new fallback function containing the data receiving part
> of the former read_string
> (read_string): use special code that eliminates re-alloc operations for non-huge strings
> (read_item): ensure reasonable container sizes to minimize the number of re-allocs
>
> Modified:
> subversion/branches/performance/subversion/libsvn_ra_svn/marshal.c
>
> Modified: subversion/branches/performance/subversion/libsvn_ra_svn/marshal.c
> URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_svn/marshal.c?rev=985606&r1=985605&r2=985606&view=diff
> ==============================================================================
> --- subversion/branches/performance/subversion/libsvn_ra_svn/marshal.c (original)
> +++ subversion/branches/performance/subversion/libsvn_ra_svn/marshal.c Sun Aug 15 00:20:34 2010
> @@ -314,8 +314,8 @@ static svn_error_t *readbuf_fill(svn_ra_
> return SVN_NO_ERROR;
> }
>
> -static svn_error_t *readbuf_getchar(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
> - char *result)
> +static APR_INLINE svn_error_t *
> +readbuf_getchar(svn_ra_svn_conn_t *conn, apr_pool_t *pool, char *result)
> {
> if (conn->read_ptr == conn->read_end)
> SVN_ERR(readbuf_fill(conn, pool));
> @@ -558,12 +558,12 @@ svn_error_t *svn_ra_svn_write_tuple(svn_
> /* Read LEN bytes from CONN into already-allocated structure ITEM.
> * Afterwards, *ITEM is of type 'SVN_RA_SVN_STRING', and its string
> * data is allocated in POOL. */
Docstring now appears out-of-sync with the function parameter list.
> -static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
> - svn_ra_svn_item_t *item, apr_uint64_t len)
> +static svn_error_t *
> +read_long_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
> + svn_stringbuf_t *stringbuf, apr_uint64_t len)
> {
> char readbuf[4096];
> apr_size_t readbuf_len;
> - svn_stringbuf_t *stringbuf = svn_stringbuf_create("", pool);
>
> /* We can't store strings longer than the maximum size of apr_size_t,
> * so check for wrapping */
> @@ -583,6 +583,50 @@ static svn_error_t *read_string(svn_ra_s
> len -= readbuf_len;
> }
>
> + return SVN_NO_ERROR;
> +}
> +
> +/* Read LEN bytes from CONN into already-allocated structure ITEM.
> + * Afterwards, *ITEM is of type 'SVN_RA_SVN_STRING', and its string
> + * data is allocated in POOL. */
> +static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
> + svn_ra_svn_item_t *item, apr_uint64_t len)
> +{
> + svn_stringbuf_t *stringbuf;
> + if (len > 0x100000)
Magic number here. Was this value chosen arbitrarily, or via some
calculation? In either case, might be better to put it into a macro
and then use that.
> + {
> + /* This string might take a large amount of memory. Don't allocate
> + * the whole buffer at once, so to prevent OOM issues by corrupted
> + * network data.
> + */
> + stringbuf = svn_stringbuf_create("", pool);
> + SVN_ERR(read_long_string(conn, pool, stringbuf, len));
> + }
> + else
> + {
> + /* This is a reasonably sized string. So, provide a buffer large
> + * enough to prevent re-allocation as long as the data transmission
> + * is not flawed.
> + */
> + stringbuf = svn_stringbuf_create_ensure(len, pool);
> +
> + /* Read the string data directly into the string structure.
> + * Do it iteratively, if necessary.
> + */
> + while (len)
> + {
> + apr_size_t readbuf_len = (apr_size_t)len;
> + char *dest = stringbuf->data + stringbuf->len;
> + SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
> +
> + stringbuf->len += readbuf_len;
> + stringbuf->data[stringbuf->len] = '\0';
> + len -= readbuf_len;
> + }
> + }
> +
> + /* Return the string properly wrapped into an RA_SVN item.
> + */
> item->kind = SVN_RA_SVN_STRING;
> item->u.string = apr_palloc(pool, sizeof(*item->u.string));
> item->u.string->data = stringbuf->data;
> @@ -643,7 +687,8 @@ static svn_error_t *read_item(svn_ra_svn
> else if (apr_isalpha(c))
> {
> /* It's a word. */
> - str = svn_stringbuf_ncreate(&c, 1, pool);
> + str = svn_stringbuf_create_ensure(16, pool);
> + svn_stringbuf_appendbyte(str, c);
> while (1)
> {
> SVN_ERR(readbuf_getchar(conn, pool, &c));
> @@ -658,7 +703,7 @@ static svn_error_t *read_item(svn_ra_svn
> {
> /* Read in the list items. */
> item->kind = SVN_RA_SVN_LIST;
> - item->u.list = apr_array_make(pool, 0, sizeof(svn_ra_svn_item_t));
> + item->u.list = apr_array_make(pool, 4, sizeof(svn_ra_svn_item_t));
> while (1)
> {
> SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
>
>
>
Received on 2010-10-25 22:04:55 CEST