You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2014/06/23 22:15:25 UTC
svn commit: r1604925 -
/subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
Author: stsp
Date: Mon Jun 23 20:15:24 2014
New Revision: 1604925
URL: http://svn.apache.org/r1604925
Log:
Add more dual-pool usage to the FSFS caching code.
* subversion/libsvn_fs_fs/cached_data.c
(get_cached_window, read_delta_window): Switch to dual-pool and use
a scratch pool for temporary allocations.
(get_combined_window): Pass an iterpool as scratch pool.
(delta_read_next_window): Pass a scratch pool.
Modified:
subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/cached_data.c?rev=1604925&r1=1604924&r2=1604925&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/cached_data.c Mon Jun 23 20:15:24 2014
@@ -1171,8 +1171,8 @@ parse_raw_window(void **out,
* rep state RS from the current FSFS session's cache. This will be a
* no-op and IS_CACHED will be set to FALSE if no cache has been given.
* If a cache is available IS_CACHED will inform the caller about the
- * success of the lookup. Allocations (of the window in particualar) will
- * be made from POOL.
+ * success of the lookup. Allocations of the window in will be made
+ * from RESULT_POOL. Use SCRATCH_POOL for temporary allocations.
*
* If the information could be found, put RS to CHUNK_INDEX.
*/
@@ -1181,7 +1181,8 @@ get_cached_window(svn_txdelta_window_t *
rep_state_t *rs,
int chunk_index,
svn_boolean_t *is_cached,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
if (! rs->window_cache)
{
@@ -1199,7 +1200,7 @@ get_cached_window(svn_txdelta_window_t *
is_cached,
rs->window_cache,
&key,
- pool));
+ result_pool));
/* If we did not find a parsed txdelta window, we might have a raw
version of it in our cache. If so, read, parse and re-cache it. */
@@ -1207,10 +1208,10 @@ get_cached_window(svn_txdelta_window_t *
{
SVN_ERR(svn_cache__get_partial((void **) &cached_window, is_cached,
rs->raw_window_cache, &key,
- parse_raw_window, NULL, pool));
+ parse_raw_window, NULL, result_pool));
if (*is_cached)
SVN_ERR(svn_cache__set(rs->window_cache, &key, cached_window,
- pool));
+ scratch_pool));
}
/* Return cached information. */
@@ -1451,7 +1452,8 @@ rep_read_get_baton(struct rep_read_baton
than THIS_CHUNK + 1 when this function returns. */
static svn_error_t *
read_delta_window(svn_txdelta_window_t **nwin, int this_chunk,
- rep_state_t *rs, apr_pool_t *pool)
+ rep_state_t *rs, apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_boolean_t is_cached;
apr_off_t start_offset;
@@ -1461,10 +1463,11 @@ read_delta_window(svn_txdelta_window_t *
SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
SVN_ERR(dbg_log_access(rs->sfile->fs, rs->revision, rs->item_index,
- NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+ NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, scratch_pool));
/* Read the next window. But first, try to find it in the cache. */
- SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
+ SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached,
+ result_pool, scratch_pool));
if (is_cached)
return SVN_NO_ERROR;
@@ -1480,27 +1483,28 @@ read_delta_window(svn_txdelta_window_t *
&& rs->raw_window_cache)
{
SVN_ERR(block_read(NULL, rs->sfile->fs, rs->revision, rs->item_index,
- rs->sfile->rfile, pool, pool));
+ rs->sfile->rfile, result_pool, scratch_pool));
/* reading the whole block probably also provided us with the
desired txdelta window */
- SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
+ SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached,
+ result_pool, scratch_pool));
if (is_cached)
return SVN_NO_ERROR;
}
/* data is still not cached -> we need to read it.
Make sure we have all the necessary info. */
- SVN_ERR(auto_set_start_offset(rs, pool));
- SVN_ERR(auto_read_diff_version(rs, pool));
+ SVN_ERR(auto_set_start_offset(rs, scratch_pool));
+ SVN_ERR(auto_read_diff_version(rs, scratch_pool));
/* RS->FILE may be shared between RS instances -> make sure we point
* to the right data. */
start_offset = rs->start + rs->current;
- SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, pool));
+ SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, scratch_pool));
/* Skip windows to reach the current chunk if we aren't there yet. */
- iterpool = svn_pool_create(pool);
+ iterpool = svn_pool_create(scratch_pool);
while (rs->chunk_index < this_chunk)
{
svn_pool_clear(iterpool);
@@ -1519,8 +1523,8 @@ read_delta_window(svn_txdelta_window_t *
/* Actually read the next window. */
SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->rfile->stream,
- rs->ver, pool));
- SVN_ERR(get_file_offset(&end_offset, rs, pool));
+ rs->ver, result_pool));
+ SVN_ERR(get_file_offset(&end_offset, rs, scratch_pool));
rs->current = end_offset - rs->start;
if (rs->current > rs->size)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1530,7 +1534,7 @@ read_delta_window(svn_txdelta_window_t *
/* the window has not been cached before, thus cache it now
* (if caching is used for them at all) */
if (SVN_IS_VALID_REVNUM(rs->revision))
- SVN_ERR(set_cached_window(*nwin, rs, pool));
+ SVN_ERR(set_cached_window(*nwin, rs, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1538,22 +1542,23 @@ read_delta_window(svn_txdelta_window_t *
/* Read SIZE bytes from the representation RS and return it in *NWIN. */
static svn_error_t *
read_plain_window(svn_stringbuf_t **nwin, rep_state_t *rs,
- apr_size_t size, apr_pool_t *pool)
+ apr_size_t size, apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_off_t offset;
/* RS->FILE may be shared between RS instances -> make sure we point
* to the right data. */
SVN_ERR(auto_open_shared_file(rs->sfile));
- SVN_ERR(auto_set_start_offset(rs, pool));
+ SVN_ERR(auto_set_start_offset(rs, scratch_pool));
offset = rs->start + rs->current;
- SVN_ERR(rs_aligned_seek(rs, NULL, offset, pool));
+ SVN_ERR(rs_aligned_seek(rs, NULL, offset, scratch_pool));
/* Read the plain data. */
- *nwin = svn_stringbuf_create_ensure(size, pool);
+ *nwin = svn_stringbuf_create_ensure(size, result_pool);
SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, (*nwin)->data, size,
- NULL, NULL, pool));
+ NULL, NULL, result_pool));
(*nwin)->data[size] = 0;
/* Update RS. */
@@ -1574,6 +1579,7 @@ get_combined_window(svn_stringbuf_t **re
apr_array_header_t *windows;
svn_stringbuf_t *source, *buf = rb->base_window;
rep_state_t *rs;
+ apr_pool_t *iterpool;
/* Read all windows that we need to combine. This is fine because
the size of each window is relatively small (100kB) and skip-
@@ -1581,12 +1587,16 @@ get_combined_window(svn_stringbuf_t **re
Stop early if one of them does not depend on its predecessors. */
window_pool = svn_pool_create(rb->pool);
windows = apr_array_make(window_pool, 0, sizeof(svn_txdelta_window_t *));
+ iterpool = svn_pool_create(rb->pool);
for (i = 0; i < rb->rs_list->nelts; ++i)
{
svn_txdelta_window_t *window;
+ svn_pool_clear(iterpool);
+
rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
- SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool));
+ SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool,
+ iterpool));
APR_ARRAY_PUSH(windows, svn_txdelta_window_t *) = window;
if (window->src_ops == 0)
@@ -1602,6 +1612,8 @@ get_combined_window(svn_stringbuf_t **re
{
svn_txdelta_window_t *window;
+ svn_pool_clear(iterpool);
+
rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
window = APR_ARRAY_IDX(windows, i, svn_txdelta_window_t *);
@@ -1612,7 +1624,7 @@ get_combined_window(svn_stringbuf_t **re
source = buf;
if (source == NULL && rb->src_state != NULL)
SVN_ERR(read_plain_window(&source, rb->src_state, window->sview_len,
- pool));
+ pool, iterpool));
/* Combine this window with the current one. */
new_pool = svn_pool_create(rb->pool);
@@ -1639,6 +1651,7 @@ get_combined_window(svn_stringbuf_t **re
svn_pool_destroy(pool);
pool = new_pool;
}
+ svn_pool_destroy(iterpool);
svn_pool_destroy(window_pool);
@@ -2167,14 +2180,18 @@ delta_read_next_window(svn_txdelta_windo
apr_pool_t *pool)
{
struct delta_read_baton *drb = baton;
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
*window = NULL;
if (drb->rs->current < drb->rs->size)
{
- SVN_ERR(read_delta_window(window, drb->rs->chunk_index, drb->rs, pool));
+ SVN_ERR(read_delta_window(window, drb->rs->chunk_index, drb->rs, pool,
+ scratch_pool));
drb->rs->chunk_index++;
}
+ svn_pool_destroy(scratch_pool);
+
return SVN_NO_ERROR;
}