Author: stefan2
Date: Tue May 17 11:27:25 2011
New Revision: 1104160

URL: http://svn.apache.org/viewvc?rev=1104160&view=rev
Log:
Speed up UTF8 conversion, especially if APR_HAS_THREADS.
Provide global

* subversion/libsvn_subr/utf.c
  (SVN_UTF_NTOU_XLATE_HANDLE, SVN_UTF_UTON_XLATE_HANDLE):
   make them identifiable by address
  (xlat_ntou_static_handle, xlat_uton_static_handle): 
   introduce global translation map pointers as 1st level cache
  (get_xlate_handle_node): match standard xlat types by address;
   try global map pointers first before falling back to the hash
  (put_xlate_handle_node): match standard xlat types by address;
   push old global maps to hash

Modified:
    subversion/trunk/subversion/libsvn_subr/utf.c

Modified: subversion/trunk/subversion/libsvn_subr/utf.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/utf.c?rev=1104160&r1=1104159&r2=1104160&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/utf.c (original)
+++ subversion/trunk/subversion/libsvn_subr/utf.c Tue May 17 11:27:25 2011
@@ -29,6 +29,7 @@
 #include <apr_strings.h>
 #include <apr_lib.h>
 #include <apr_xlate.h>
+#include <apr_atomic.h>
 
 #include "svn_string.h"
 #include "svn_error.h"
@@ -42,9 +43,13 @@
 
 
 
-#define SVN_UTF_NTOU_XLATE_HANDLE "svn-utf-ntou-xlate-handle"
-#define SVN_UTF_UTON_XLATE_HANDLE "svn-utf-uton-xlate-handle"
-#define SVN_APR_UTF8_CHARSET "UTF-8"
+/* Use these static strings to maximize performance on standard conversions.
+ * Any strings on other locations are still valid, however.
+ */
+static const char *SVN_UTF_NTOU_XLATE_HANDLE = "svn-utf-ntou-xlate-handle";
+static const char *SVN_UTF_UTON_XLATE_HANDLE = "svn-utf-uton-xlate-handle";
+
+static const char *SVN_APR_UTF8_CHARSET = "UTF-8";
 
 #if APR_HAS_THREADS
 static apr_thread_mutex_t *xlate_handle_mutex = NULL;
@@ -79,6 +84,13 @@ typedef struct xlate_handle_node_t {
    memory leak. */
 static apr_hash_t *xlate_handle_hash = NULL;
 
+/* "1st level cache" to standard conversion maps. We may access these
+ * using atomic xchange ops, i.e. without further thread synchronization.
+ * If the respective item is NULL, fallback to hash lookup.
+ */
+static volatile void *xlat_ntou_static_handle = NULL;
+static volatile void *xlat_uton_static_handle = NULL;
+
 /* Clean up the xlate handle cache. */
 static apr_status_t
 xlate_cleanup(void *arg)
@@ -91,6 +103,10 @@ xlate_cleanup(void *arg)
 #endif
   xlate_handle_hash = NULL;
 
+  /* ensure no stale objects get accessed */
+  xlat_ntou_static_handle = NULL;
+  xlat_uton_static_handle = NULL;
+
   return APR_SUCCESS;
 }
 
@@ -183,6 +199,19 @@ get_xlate_handle_node(xlate_handle_node_
     {
       if (xlate_handle_hash)
         {
+          /* 1st level: global, static items */
+          if (userdata_key == SVN_UTF_NTOU_XLATE_HANDLE)
+            old_node = apr_atomic_xchgptr(&xlat_ntou_static_handle, NULL);
+          else if (userdata_key == SVN_UTF_UTON_XLATE_HANDLE)
+            old_node = apr_atomic_xchgptr(&xlat_uton_static_handle, NULL);
+
+          if (old_node && old_node->valid)
+            {
+              *ret = old_node;
+              return SVN_NO_ERROR;
+            }
+          
+          /* 2nd level: hash lookup */
 #if APR_HAS_THREADS
           apr_err = apr_thread_mutex_lock(xlate_handle_mutex);
           if (apr_err != APR_SUCCESS)
@@ -321,9 +350,20 @@ put_xlate_handle_node(xlate_handle_node_
   assert(node->next == NULL);
   if (!userdata_key)
     return;
+
+  /* push previous global node to the hash */
   if (xlate_handle_hash)
     {
       xlate_handle_node_t **node_p;
+
+      /* 1st level: global, static items */
+      if (userdata_key == SVN_UTF_NTOU_XLATE_HANDLE)
+        node = apr_atomic_xchgptr(&xlat_ntou_static_handle, node);
+      else if (userdata_key == SVN_UTF_UTON_XLATE_HANDLE)
+        node = apr_atomic_xchgptr(&xlat_uton_static_handle, node);
+      if (node == NULL)
+        return;
+
 #if APR_HAS_THREADS
       if (apr_thread_mutex_lock(xlate_handle_mutex) != APR_SUCCESS)
         SVN_ERR_MALFUNCTION_NO_RETURN();


Reply via email to