Author: brane
Date: Thu Feb 5 08:15:18 2015
New Revision: 1657491
URL: http://svn.apache.org/r1657491
Log:
On the reuse-ra-session branch: Add tools for tracking RA session cache usage.
In order to make the stats code self-contained, also move the
definition of the cache structure into the implementation file.
* subversion/libsvn_client/client.h
(svn_client__ra_cache_t): Remove definition. Keep forward declaration.
(svn_client__ra_session_t): Remove forward declaration.
(svn_client__private_ctx_t): Member ra_cache becomes a pointer.
* subversion/libsvn_client/ra_cache.c
(RA_CACHE_STATS): New diagnostics category/macro.
(svn_client__ra_cache_t): Define here and add optional stats members.
(svn_client__ra_cache_init): Allocate the cache structure.
(get_private_ra_cache): Adjust to the changed cache member type.
(cleanup_ra_cache, close_ra_session,
svn_client__ra_cache_open_session,
svn_client__ra_cache_release_session): Gather cache usage data.
* tools/dev/ra-cache-summary.py: New developer tool.
Summarizes RA cache usage across multiple client contexts.
Added:
subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py (with
props)
Modified:
subversion/branches/reuse-ra-session/subversion/libsvn_client/client.h
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_client/client.h
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/client.h?rev=1657491&r1=1657490&r2=1657491&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/client.h
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/client.h Thu
Feb 5 08:15:18 2015
@@ -47,29 +47,8 @@ extern "C" {
#endif /* __cplusplus */
-/* Forward declaration of the cached RA session structure. */
-struct svn_client__ra_session_t;
-
/* RA session cache */
-typedef struct svn_client__ra_cache_t
-{
- /* The pool that defines the lifetime of the cache. */
- apr_pool_t *pool;
-
- /* The config hash used to create new sessions. */
- apr_hash_t *config;
-
- /* Cached active RA sessions.
- Keys are RA_SESSION_T and values are CLIENT_RA_SESION_T pointers. */
- apr_hash_t *active;
-
- /* List of inactive sessions available for reuse. */
- APR_RING_HEAD(, svn_client__ra_session_t) freelist;
-
- /* Next ID for RA sessions. Used only for diagnostics purpose. */
- int next_id;
-} svn_client__ra_cache_t;
-
+typedef struct svn_client__ra_cache_t svn_client__ra_cache_t;
/* Private client context.
*
@@ -89,7 +68,7 @@ typedef struct svn_client__private_ctx_t
apr_off_t total_progress;
/* The RA session cache. */
- svn_client__ra_cache_t ra_cache;
+ svn_client__ra_cache_t *ra_cache;
/* The public context. */
svn_client_ctx_t public_ctx;
Modified:
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c?rev=1657491&r1=1657490&r2=1657491&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
Thu Feb 5 08:15:18 2015
@@ -35,18 +35,28 @@
* Debugging
*/
+/* Trace usage of svn_client__ra_session_t objects */
#if 0
#define RA_CACHE_LOG(x) SVN_DBG(x)
#else
#define RA_CACHE_LOG(x)
#endif
+/* Trace usage of svn_ra_session_t objects */
#if 0
#define RA_CACHE_DBG(x) SVN_DBG(x)
#else
#define RA_CACHE_DBG(x)
#endif
+/* Trace cache statistics */
+#if 0
+#define RA_CACHE_STATS(x) x
+#else
+#define RA_CACHE_STATS(x)
+#endif
+
+
#if APR_SIZEOF_VOIDP == 8
#define DBG_PTR_FMT "16"APR_UINT64_T_HEX_FMT
#else
@@ -55,9 +65,10 @@
/*
- * The session cache entry.
+ * The session cache.
*/
+/* Cache entry */
typedef struct svn_client__ra_session_t
{
/* The free-list link for this session. */
@@ -94,6 +105,35 @@ typedef struct svn_client__ra_session_t
} svn_client__ra_session_t;
+/* RA session cache */
+struct svn_client__ra_cache_t
+{
+ /* The pool that defines the lifetime of the cache. */
+ apr_pool_t *pool;
+
+ /* The config hash used to create new sessions. */
+ apr_hash_t *config;
+
+ /* Cached active RA sessions.
+ Keys are RA_SESSION_T and values are CLIENT_RA_SESION_T pointers. */
+ apr_hash_t *active;
+
+ /* List of inactive sessions available for reuse. */
+ APR_RING_HEAD(, svn_client__ra_session_t) freelist;
+
+ /* Next ID for RA sessions. Used only for diagnostics purpose. */
+ int next_id;
+
+ RA_CACHE_STATS(struct {
+ apr_uint64_t request; /* number of requests for a session */
+ apr_uint64_t open; /* number of calls to svn_ra_open */
+ apr_uint64_t close; /* number of calls to svn_ra__close */
+ apr_uint64_t release; /* number of releases to cache */
+ apr_uint64_t reuse; /* number of reuses from cache */
+ } stat;)
+};
+
+
/*
* Forwarding session callbacks.
*/
@@ -275,6 +315,18 @@ cleanup_ra_cache(void *data)
RA_CACHE_LOG(("RA_CACHE: Cleanup\n"));
+ RA_CACHE_STATS(SVN_DBG(("RA_CACHE_STATS:"
+ " request:%"APR_UINT64_T_FMT
+ " open:%"APR_UINT64_T_FMT
+ " close:%"APR_UINT64_T_FMT
+ " release:%"APR_UINT64_T_FMT
+ " reuse:%"APR_UINT64_T_FMT"\n",
+ ra_cache->stat.request,
+ ra_cache->stat.open,
+ ra_cache->stat.close,
+ ra_cache->stat.release,
+ ra_cache->stat.reuse)));
+
return APR_SUCCESS;
}
@@ -285,16 +337,17 @@ svn_client__ra_cache_init(svn_client__pr
{
RA_CACHE_LOG(("RA_CACHE: Init\n"));
- private_ctx->ra_cache.pool = pool;
- private_ctx->ra_cache.config = config;
- private_ctx->ra_cache.active = apr_hash_make(pool);
- APR_RING_INIT(&private_ctx->ra_cache.freelist,
+ private_ctx->ra_cache = apr_pcalloc(pool, sizeof(*private_ctx->ra_cache));
+ private_ctx->ra_cache->pool = pool;
+ private_ctx->ra_cache->config = config;
+ private_ctx->ra_cache->active = apr_hash_make(pool);
+ APR_RING_INIT(&private_ctx->ra_cache->freelist,
svn_client__ra_session_t, freelist);
/* This cleanup must be registered to run before the subpools (which
include pools of cached sessions) are destroyed, so that the
close_ra_session handler behaves correctly. */
- apr_pool_pre_cleanup_register(pool, &private_ctx->ra_cache,
+ apr_pool_pre_cleanup_register(pool, private_ctx->ra_cache,
cleanup_ra_cache);
}
@@ -326,6 +379,7 @@ close_ra_session(void *data)
svn_ra__close(session);
RA_CACHE_LOG(("SESSION(%d): Closed\n", cache_entry->id));
+ RA_CACHE_STATS(++ra_cache->stat.close);
}
else
{
@@ -333,6 +387,7 @@ close_ra_session(void *data)
sessions will have already been closed in the session pool
cleanup handlers by the time we get here. */
RA_CACHE_LOG(("SESSION(%d): Cleanup\n", cache_entry->id));
+ RA_CACHE_STATS(SVN_DBG(("RA_CACHE_STATS: cleanup:1\n")));
}
return APR_SUCCESS;
@@ -369,7 +424,7 @@ get_private_ra_cache(svn_client_ctx_t *p
{
svn_client__private_ctx_t *const private_ctx =
svn_client__get_private_ctx(public_ctx);
- return &private_ctx->ra_cache;
+ return private_ctx->ra_cache;
}
svn_error_t *
@@ -430,6 +485,7 @@ svn_client__ra_cache_open_session(svn_ra
APR_RING_ELEM_INIT(cache_entry, freelist);
RA_CACHE_LOG(("SESSION(%d): Reused\n", cache_entry->id));
+ RA_CACHE_STATS(++ra_cache->stat.reuse);
}
else
{
@@ -478,6 +534,7 @@ svn_client__ra_cache_open_session(svn_ra
ra_cache->pool));
RA_CACHE_LOG(("SESSION(%d): Open('%s')\n", cache_entry->id, base_url));
+ RA_CACHE_STATS(++ra_cache->stat.open);
++ra_cache->next_id;
}
@@ -499,6 +556,7 @@ svn_client__ra_cache_open_session(svn_ra
*session_p = cache_entry->session;
+ RA_CACHE_STATS(++ra_cache->stat.request);
return SVN_NO_ERROR;
}
@@ -545,4 +603,5 @@ svn_client__ra_cache_release_session(svn
cache_entry->cb_baton = NULL;
RA_CACHE_LOG(("SESSION(%d): Released\n", cache_entry->id));
+ RA_CACHE_STATS(++ra_cache->stat.release);
}
Added: subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py?rev=1657491&view=auto
==============================================================================
--- subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py (added)
+++ subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py Thu Feb
5 08:15:18 2015
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+# This is a stream filter that looks at RA session cache statistics
+# (see RA_CACHE_STATS in subversion/libsvn_subr/ra_cache.c) and prints
+# a summary of cache usage.
+#
+# Example:
+#
+# $ ./subversion/tests/cmdline/externals_tests.py \
+# | ./tools/rev/ra-cache-stats.py | tail -1
+# DBG: RA_CACHE_STATS: TOTAL: request:1005 open:597 close:5 release:996
reuse:408 cleanup:4
+
+
+import re
+import sys
+
+stat_rx = re.compile(r'^DBG:\s.+\sRA_CACHE_STATS:\s+(?:'
+ r'request:(?P<request>\d+)\s+'
+ r'open:(?P<open>\d+)\s+'
+ r'close:(?P<close>\d+)\s+'
+ r'release:(?P<release>\d+)\s+'
+ r'reuse:(?P<reuse>\d+)|'
+ r'cleanup:(?P<cleanup>\d+))\s*$')
+
+request = open = close = release = reuse = cleanup = 0
+
+for line in sys.stdin:
+ match = stat_rx.match(line)
+ if not match:
+ sys.stdout.write(line)
+ continue
+
+ if match.group('cleanup') is None:
+ request += int(match.group('request'))
+ open += int(match.group('open'))
+ close += int(match.group('close'))
+ release += int(match.group('release'))
+ reuse += int(match.group('reuse'))
+ else:
+ cleanup += int(match.group('cleanup'))
+
+sys.stdout.write('DBG: RA_CACHE_STATS: TOTAL:'
+ ' request:%d open:%d close:%d'
+ ' release:%d reuse:%d cleanup:%d\n'
+ % (request, open, close, release, reuse, cleanup))
Propchange: subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: subversion/branches/reuse-ra-session/tools/dev/ra-cache-summary.py
------------------------------------------------------------------------------
svn:executable = *