From 997e5d0d7b49c7426d16d46e44b494445f8c6865 Mon Sep 17 00:00:00 2001 From: markt Date: Tue, 16 Nov 2010 17:22:45 +0000 Subject: [PATCH] Session manager performance Switch to a queue of message digests rather than a single sync'd digest Small improvement but is part of removing the sync completely that should result in larger improvements git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1035701 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/session/ManagerBase.java | 57 +++++++++++++---------- test/org/apache/catalina/session/Benchmarks.java | 8 ++-- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/java/org/apache/catalina/session/ManagerBase.java b/java/org/apache/catalina/session/ManagerBase.java index 08c60faac..42cc409f8 100644 --- a/java/org/apache/catalina/session/ManagerBase.java +++ b/java/org/apache/catalina/session/ManagerBase.java @@ -36,8 +36,10 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Queue; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.catalina.Container; import org.apache.catalina.Context; @@ -99,7 +101,8 @@ public abstract class ManagerBase extends LifecycleMBeanBase * Return the MessageDigest implementation to be used when * creating session identifiers. */ - protected MessageDigest digest = null; + protected Queue digests = + new ConcurrentLinkedQueue(); /** @@ -341,33 +344,32 @@ public abstract class ManagerBase extends LifecycleMBeanBase * session identifiers. If none has been created yet, initialize * one the first time this method is called. */ - public synchronized MessageDigest getDigest() { + protected MessageDigest createDigest() { - if (this.digest == null) { - long t1=System.currentTimeMillis(); - if (log.isDebugEnabled()) - log.debug(sm.getString("managerBase.getting", algorithm)); + MessageDigest result; + + long t1=System.currentTimeMillis(); + if (log.isDebugEnabled()) + log.debug(sm.getString("managerBase.getting", algorithm)); + try { + result = MessageDigest.getInstance(algorithm); + } catch (NoSuchAlgorithmException e) { + log.error(sm.getString("managerBase.digest", algorithm), e); try { - this.digest = MessageDigest.getInstance(algorithm); - } catch (NoSuchAlgorithmException e) { - log.error(sm.getString("managerBase.digest", algorithm), e); - try { - this.digest = MessageDigest.getInstance(DEFAULT_ALGORITHM); - } catch (NoSuchAlgorithmException f) { - log.error(sm.getString("managerBase.digest", - DEFAULT_ALGORITHM), e); - this.digest = null; - } + result = MessageDigest.getInstance(DEFAULT_ALGORITHM); + } catch (NoSuchAlgorithmException f) { + log.error(sm.getString("managerBase.digest", + DEFAULT_ALGORITHM), e); + result = null; } - if (log.isDebugEnabled()) - log.debug(sm.getString("managerBase.gotten")); - long t2=System.currentTimeMillis(); - if( log.isDebugEnabled() ) - log.debug("getDigest() " + (t2-t1)); } + if (log.isDebugEnabled()) + log.debug(sm.getString("managerBase.gotten")); + long t2=System.currentTimeMillis(); + if( log.isDebugEnabled() ) + log.debug("getDigest() " + (t2-t1)); - return (this.digest); - + return result; } @@ -998,8 +1000,15 @@ public abstract class ManagerBase extends LifecycleMBeanBase while (resultLenBytes < this.sessionIdLength) { synchronized (this) { getRandomBytes(random); - random = getDigest().digest(random); } + MessageDigest md = digests.poll(); + if (md == null) { + // If this fails, NPEs will follow. This should never fail + // since if it falls back to the default digest + md = createDigest(); + } + random = md.digest(random); + digests.add(md); for (int j = 0; j < random.length && resultLenBytes < this.sessionIdLength; j++) { diff --git a/test/org/apache/catalina/session/Benchmarks.java b/test/org/apache/catalina/session/Benchmarks.java index 53d98f975..17019cc07 100644 --- a/test/org/apache/catalina/session/Benchmarks.java +++ b/test/org/apache/catalina/session/Benchmarks.java @@ -108,10 +108,10 @@ public class Benchmarks extends TestCase { /* * Results on markt's 4-core dev box - * 1 thread - ~2,400ms - * 2 threads - ~4,700ms - * 4 threads - ~12,600ms - * 16 threads - ~53,700ms + * 1 thread - ~2,300ms + * 2 threads - ~4,600ms + * 4 threads - ~12,300ms + * 16 threads - ~51,000ms */ public void testManagerBaseCreateSession() { doTestManagerBaseCreateSession(1, 100000); -- 2.11.0