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/12/28 19:04:41 UTC
svn commit: r1648238 - /subversion/trunk/subversion/libsvn_fs_fs/tree.c
Author: stefan2
Date: Sun Dec 28 18:04:40 2014
New Revision: 1648238
URL: http://svn.apache.org/r1648238
Log:
In FSFS, make get_dag not lock the DAG node in cache unless requested.
The critical part is the call to open_path which would always lock the
node even if we only want to have a single node returned.
* subversion/libsvn_fs_fs/tree.c
(open_path_flags_t): Define a new flag.
(open_path): Don't lock the DAG node returned if return only the last
step in the path and don't explicitly ask for a lock.
The internal iteration along the path is fine with only
the lastest node being valid, i.e. at no point do we need
to access two DAG nodes.
(get_dag): Request a locked node only if we are told to do so.
Modified:
subversion/trunk/subversion/libsvn_fs_fs/tree.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/tree.c?rev=1648238&r1=1648237&r2=1648238&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/tree.c Sun Dec 28 18:04:40 2014
@@ -948,7 +948,12 @@ typedef enum open_path_flags_t {
/* The caller wants a NULL path object instead of an error if the
path cannot be found. */
- open_path_allow_null = 8
+ open_path_allow_null = 8,
+
+ /* The caller wants a DAG nodes returned to be locked in the cache,
+ i.e. they shall remain valid until the caller's pool gets cleared.
+ This flag is implied if open_path_node_only is not set. */
+ open_path_needs_lock = 16
} open_path_flags_t;
/* Try a short-cut for the open_path() function using the last node accessed.
@@ -1050,6 +1055,12 @@ open_path(parent_path_t **parent_path_p,
svn_stringbuf_t *path_so_far = svn_stringbuf_create(path, pool);
apr_size_t path_len = path_so_far->len;
+ /* We usually need to lock the DAG nodes returned in the cache because
+ there is more than one of them in the parent path returned. Only if
+ we want a single node, we may consider not locking it in cache. */
+ svn_boolean_t need_lock_cache = ( !(flags & open_path_node_only)
+ || (flags & open_path_needs_lock));
+
/* Callers often traverse the DAG in some path-based order or along the
history segments. That allows us to try a few guesses about where to
find the next item. This is only useful if the caller didn't request
@@ -1085,7 +1096,11 @@ open_path(parent_path_t **parent_path_p,
*parent_path_p = parent_path;
/* We did not use dag_node_cache_get(). Lock manually. */
- lock_cache(ffd->dag_node_cache, pool);
+ if (need_lock_cache)
+ {
+ fs_fs_data_t *ffd = fs->fsap_data;
+ lock_cache(ffd->dag_node_cache, pool);
+ }
return SVN_NO_ERROR;
}
@@ -1097,7 +1112,8 @@ open_path(parent_path_t **parent_path_p,
directory = svn_dirent_dirname(path, pool);
if (directory[1] != 0) /* root nodes are covered anyway */
{
- SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool));
+ SVN_ERR(dag_node_cache_get(&here, root, directory, need_lock_cache,
+ pool));
/* Did the shortcut work? */
if (here)
@@ -1164,7 +1180,7 @@ open_path(parent_path_t **parent_path_p,
complete path. */
if (next || !(flags & open_path_uncached))
SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far->data,
- TRUE, pool));
+ need_lock_cache, pool));
if (cached_node)
child = cached_node;
else
@@ -1374,11 +1390,13 @@ get_dag(dag_node_t **dag_node_p,
if (! node)
{
- /* Call open_path with no flags, as we want this to return an
- * error if the node for which we are searching doesn't exist. */
- SVN_ERR(open_path(&parent_path, root, path,
- open_path_uncached | open_path_node_only,
- FALSE, pool));
+ /* Select the options (optimizations) for open_path. */
+ int flags = ( needs_lock_cache
+ ? open_path_uncached | open_path_node_only
+ | open_path_needs_lock
+ : open_path_uncached | open_path_node_only);
+
+ SVN_ERR(open_path(&parent_path, root, path, flags, FALSE, pool));
node = parent_path->node;
/* No need to cache our find -- open_path() will do that for us. */