[Schmitzm-commits] r2018 - trunk/schmitzm-core/src/main/java/de/schmitzm/regex

scm-commit at wald.intevation.org scm-commit at wald.intevation.org
Sun May 27 00:41:19 CEST 2012


Author: alfonx
Date: 2012-05-27 00:41:19 +0200 (Sun, 27 May 2012)
New Revision: 2018

Added:
   trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCacheOrig.java
Modified:
   trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache.java
Log:


Modified: trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache.java	2012-05-26 21:52:49 UTC (rev 2017)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache.java	2012-05-26 22:41:19 UTC (rev 2018)
@@ -1,13 +1,11 @@
 package de.schmitzm.regex;
 
-import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.MatchResult;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import de.schmitzm.lang.LimitedHashMap;
-import de.schmitzm.lang.LimitedHashMap.TRUNC_METHOD;
-
 /**
  * Cached compilierte Pattern und auch Ergebnisse von RegExes. Use the matchers methods to obtain cached result and add
  * regex to cache automatically.
@@ -18,41 +16,83 @@
 public class RegexCache {
 
 	/**
-	 * Diese Klasse dienst dazu, einen Eintrag im cache liegen zu haben, auch wenn keine match gefunden wurde. In dem
-	 * Falle ist das Feld {@link #matcherResult} dann <code>null</code>
-	 * 
-	 */
-	static class MyMatchResult {
+	 * TODO Ein String der länger ist als die hier angegebene Anzahl Zeichen wir nicht gecached. Die Wahrscheinlichkeit,
+	 * dass der selbe Sting nochmal auftaucht wird als zu gering eingeschätzt.
+	 **/
+	private static final int CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH = 1000;
 
-		final MatchResult matcherResult;
-
-		MyMatchResult(final MatchResult matcher) {
-			this.matcherResult = matcher;
-		}
-	}
-
 	/**
-	 * TODO Ein String der länger ist als die hier angegebene Anzahl Zeichen wir nicht gecached. Die Wahrscheinlichkeit,
-	 * dass der selbe Sting nochmal auftaucht wird als zu gering eingeschätzt. TODO
+	 * TODO Ein String der kürzer als die hier angegebene Anzahl Zeichen wir nicht gecached.
 	 **/
-	private static final int CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH = 200;
+	private static final int CACHE_VALUES_TO_RESULT_MIN_VALUE_LENGTH = 50;
 
-	private static final int CACHE_VALUES_TO_RESULT_SIZE = 500;
+	public static boolean matcherCache = false;
+	private final ConcurrentHashMap<String, ThreadLocal<Matcher>> matchersCachedThreadLocalPerRegex = new ConcurrentHashMap<String, ThreadLocal<Matcher>>();
 
+	public static boolean resultsCache = true;
+
 	private static RegexCache singletonInstance;
 
+	private final ConcurrentHashMap<String, Pattern> patterns = new ConcurrentHashMap<String, Pattern>(1000);
+
 	public static RegexCache getInstance() {
 		return singletonInstance != null ? singletonInstance : new RegexCache();
 	}
 
-	private final LimitedHashMap<Pattern, LimitedHashMap<String, MyMatchResult>> matchers = new LimitedHashMap<Pattern, LimitedHashMap<String, MyMatchResult>>(
-			CACHE_VALUES_TO_RESULT_SIZE, LimitedHashMap.TRUNC_METHOD.OLDEST_GET);
-	private final HashMap<String, Pattern> patterns = new HashMap<String, Pattern>();
+	// TODO
+	// http://lucene.apache.org/solr/api/org/apache/solr/util/ConcurrentLRUCache.html#ConcurrentLRUCache%28int,%20int%29
+	private final ConcurrentHashMap<Pattern, ConcurrentHashMap<String, MyMatchResult>> matcherResults = new ConcurrentHashMap<Pattern, ConcurrentHashMap<String, MyMatchResult>>();
 
 	private RegexCache() {
 	}
 
 	/**
+	 * Diese Methode ist gedacht um die Erstellung von Matcher-Objekten in der JVM zu reduzieren. Es für bis zu 10000
+	 * RegEx ein Cache verwaltet. Jeder dieser Caches ist ein ThreadLocal-Cache von Matchern. Somit liefert diese Methde
+	 * für die selbe RegEx auf N Threads N unterschiedliche Matcher.<br/>
+	 * Die Matcher werden für die Regex gecached. Wird ein Matcher für eine gecachte Regex mit einem anderen TEXT
+	 * angeforderd, wird zuerst {@link Matcher#reset(CharSequence)} ausgeführt.
+	 */
+	public final Matcher getMatcher(final String regex, final String text) {
+
+		if (!matcherCache) {
+			return getPattern(regex).matcher(text);
+		}
+
+		ThreadLocal<Matcher> threadLocal = matchersCachedThreadLocalPerRegex.get(regex);
+
+		if (threadLocal == null) {
+
+			threadLocal = new ThreadLocal<Matcher>() {
+
+				@Override
+				protected Matcher initialValue() {
+					return getPattern(regex).matcher("");
+				}
+			};
+			matchersCachedThreadLocalPerRegex.putIfAbsent(regex, threadLocal);
+		}
+
+		return threadLocal.get().reset(text);
+	}
+
+	/**
+	 * Liefert eine compiliertes RegEx Pattern aus dem Cache. Wenn es vorher nicht existierte wird es erstellt.
+	 */
+	public final Pattern getPattern(final String regex) {
+		if (regex == null)
+			return null;
+		// synchronized (regex) {
+		Pattern p = patterns.get(regex);
+		if (p == null) {
+			p = Pattern.compile(regex);
+			patterns.putIfAbsent(regex, p);
+		}
+		return p;
+		// }
+	}
+
+	/**
 	 * Will throw java exceptions when pattern won't compile.
 	 * 
 	 * @param regex
@@ -64,26 +104,11 @@
 		if (object == null)
 			return false;
 		final String value = object instanceof String ? (String) object : object.toString();
-		return result(regex, value) != null;
-	}
 
-	/**
-	 * Liefert eine compiliertes RegEx Pattern aus dem Cache. Wenn es vorher nicht existierte wird es erstellt.
-	 */
-	public Pattern getPattern(final String regex) {
-		synchronized (patterns) {
-			Pattern p = patterns.get(regex);
-			if (p == null) {
-				p = Pattern.compile(regex);
-				patterns.put(regex, p);
-			}
-			return p;
-		}
-	}
+		// Matcher m = getMatcher(regex, value);
+		// return m.find();
 
-	public Matcher getMatcher(final String regex, final String text) {
-
-		return getPattern(regex).matcher(text);
+		return result(regex, value) != null;
 	}
 
 	/**
@@ -98,30 +123,50 @@
 	 */
 	public final MatchResult result(final String regex, final String value) {
 
+		// Wenn der value-String zu lang oder zu kurz ist, dann einfach so machten
+		if (!resultsCache || value.length() < CACHE_VALUES_TO_RESULT_MIN_VALUE_LENGTH
+				|| value.length() > CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH) {
+			final Matcher m = getMatcher(regex, value);
+			final boolean found = m.find();
+			return found ? m.toMatchResult() : null;
+		}
+
 		final Pattern pattern = getPattern(regex);
 
-		LimitedHashMap<String, MyMatchResult> m;
-		synchronized (matchers) {
-			m = matchers.get(pattern);
-			if (m == null) {
-				matchers.put(pattern, m = new LimitedHashMap<String, MyMatchResult>(CACHE_VALUES_TO_RESULT_SIZE,
-						TRUNC_METHOD.OLDEST_GET));
-			}
+		ConcurrentHashMap<String, MyMatchResult> m;
+		m = matcherResults.get(pattern);
+		if (m == null) {
+			matcherResults.put(pattern, m = new ConcurrentHashMap<String, MyMatchResult>());
 		}
 
-		MyMatchResult matcher;
-		synchronized (m) {
-			matcher = m.get(value);
-			if (matcher == null) {
-				final Matcher xm = pattern.matcher(value);
-				if (xm.find())
-					matcher = new MyMatchResult(xm.toMatchResult());
-				else
-					matcher = new MyMatchResult(null);
-			}
+		MyMatchResult mResult;
+		mResult = m.get(value);
+		if (mResult == null) {
+			final Matcher xm = getMatcher(regex, value);
+			if (xm.find())
+				mResult = new MyMatchResult(xm.toMatchResult());
+			else
+				mResult = new MyMatchResult(null);
+
+			m.put(value, mResult); // Hat die gefehlt?
 		}
 
-		return matcher.matcherResult;
+		return mResult.matcherResult;
 	}
 
+
+	/**
+	 * Diese Klasse dienst dazu, einen Eintrag im cache liegen zu haben, auch wenn keine match gefunden wurde. In dem
+	 * Falle ist das Feld {@link #matcherResult} dann <code>null</code>
+	 * 
+	 */
+	final static class MyMatchResult {
+
+		final MatchResult matcherResult;
+
+		MyMatchResult(final MatchResult matcher) {
+			this.matcherResult = matcher;
+		}
+	}
+
 }

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCacheOrig.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCacheOrig.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCacheOrig.java	2012-05-26 22:41:19 UTC (rev 2018)
@@ -0,0 +1,128 @@
+package de.schmitzm.regex;
+
+import java.util.HashMap;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import de.schmitzm.lang.LimitedHashMap;
+import de.schmitzm.lang.LimitedHashMap.TRUNC_METHOD;
+
+/**
+ * Cached compilierte Pattern und auch Ergebnisse von RegExes. Use the matchers methods to obtain cached result and add
+ * regex to cache automatically.
+ * 
+ * @author stranger
+ * @author stefan.tzeggai
+ */
+public class RegexCacheOrig {
+
+	/**
+	 * Diese Klasse dienst dazu, einen Eintrag im cache liegen zu haben, auch wenn keine match gefunden wurde. In dem
+	 * Falle ist das Feld {@link #matcherResult} dann <code>null</code>
+	 * 
+	 */
+	static class MyMatchResult {
+
+		final MatchResult matcherResult;
+
+		MyMatchResult(final MatchResult matcher) {
+			this.matcherResult = matcher;
+		}
+	}
+
+	/**
+	 * TODO Ein String der länger ist als die hier angegebene Anzahl Zeichen wir nicht gecached. Die Wahrscheinlichkeit,
+	 * dass der selbe Sting nochmal auftaucht wird als zu gering eingeschätzt. TODO
+	 **/
+	private static final int CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH = 200;
+
+	private static final int CACHE_VALUES_TO_RESULT_SIZE = 500;
+
+	private static RegexCacheOrig singletonInstance;
+
+	public static RegexCacheOrig getInstance() {
+		return singletonInstance != null ? singletonInstance : new RegexCacheOrig();
+	}
+
+	private final LimitedHashMap<Pattern, LimitedHashMap<String, MyMatchResult>> matchers = new LimitedHashMap<Pattern, LimitedHashMap<String, MyMatchResult>>(
+			CACHE_VALUES_TO_RESULT_SIZE, LimitedHashMap.TRUNC_METHOD.OLDEST_GET);
+	private final HashMap<String, Pattern> patterns = new HashMap<String, Pattern>();
+
+	private RegexCacheOrig() {
+	}
+
+	/**
+	 * Will throw java exceptions when pattern won't compile.
+	 * 
+	 * @param regex
+	 *            may not be null
+	 * @param value
+	 *            returns false is <code>null</code>
+	 */
+	public final boolean matches(final String regex, final Object object) {
+		if (object == null)
+			return false;
+		final String value = object instanceof String ? (String) object : object.toString();
+		return result(regex, value) != null;
+	}
+
+	/**
+	 * Liefert eine compiliertes RegEx Pattern aus dem Cache. Wenn es vorher nicht existierte wird es erstellt.
+	 */
+	public Pattern getPattern(final String regex) {
+		synchronized (patterns) {
+			Pattern p = patterns.get(regex);
+			if (p == null) {
+				p = Pattern.compile(regex);
+				patterns.put(regex, p);
+			}
+			return p;
+		}
+	}
+
+	public Matcher getMatcher(final String regex, final String text) {
+
+		return getPattern(regex).matcher(text);
+	}
+
+	/**
+	 * Will throw java exceptions when pattern won't compile.
+	 * 
+	 * @param regex
+	 *            may not be null
+	 * @param value
+	 *            may not be null
+	 * @return <code>null</code> if the pattern didn't match. A {@link MatchResult} otherwise which contains the groups
+	 *         etc.
+	 */
+	public final MatchResult result(final String regex, final String value) {
+
+		final Pattern pattern = getPattern(regex);
+
+		LimitedHashMap<String, MyMatchResult> m;
+		synchronized (matchers) {
+			m = matchers.get(pattern);
+			if (m == null) {
+				matchers.put(pattern, m = new LimitedHashMap<String, MyMatchResult>(CACHE_VALUES_TO_RESULT_SIZE,
+						TRUNC_METHOD.OLDEST_GET));
+			}
+		}
+
+		MyMatchResult matcher;
+		synchronized (m) {
+			matcher = m.get(value);
+			if (matcher == null) {
+				final Matcher xm = pattern.matcher(value);
+				if (xm.find())
+					matcher = new MyMatchResult(xm.toMatchResult());
+				else
+					matcher = new MyMatchResult(null);
+				// TODO?!
+			}
+		}
+
+		return matcher.matcherResult;
+	}
+
+}


Property changes on: trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCacheOrig.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain



More information about the Schmitzm-commits mailing list