[Schmitzm-commits] r2017 - in trunk: schmitzm-adresses/src/main/java/de/schmitzm/adresses schmitzm-core/src/main/java/de/schmitzm/regex
scm-commit at wald.intevation.org
scm-commit at wald.intevation.org
Sat May 26 23:52:49 CEST 2012
Author: alfonx
Date: 2012-05-26 23:52:49 +0200 (Sat, 26 May 2012)
New Revision: 2017
Added:
trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache2.java
Modified:
trunk/schmitzm-adresses/src/main/java/de/schmitzm/adresses/AddrStringUtil.java
trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache.java
Log:
Modified: trunk/schmitzm-adresses/src/main/java/de/schmitzm/adresses/AddrStringUtil.java
===================================================================
--- trunk/schmitzm-adresses/src/main/java/de/schmitzm/adresses/AddrStringUtil.java 2012-05-26 21:19:49 UTC (rev 2016)
+++ trunk/schmitzm-adresses/src/main/java/de/schmitzm/adresses/AddrStringUtil.java 2012-05-26 21:52:49 UTC (rev 2017)
@@ -62,8 +62,7 @@
hn = hn.replaceAll("^0+", "");
- Pattern p = RegexCache.getInstance().getPattern("(\\d+)\\s+\\1");
- Matcher matcher = p.matcher(hn);
+ Matcher matcher = RegexCache.getInstance().getMatcher("(\\d+)\\s+\\1", hn);
if (matcher.find())
return matcher.group(1);
@@ -460,11 +459,11 @@
strasse = strasse.replaceAll("x{2,}$", "");
strasse = strasse.replaceAll("\\sx+$", "");
-
+
strasse = strasse.replaceAll("wegx$", "weg");
strasse = strasse.replaceAll("strassex$", "strasse");
strasse = strasse.replaceAll("alleex$", "allee");
-
+
strasse = strasse.replaceAll("str[\\.\\s]", "strasse");
strasse = strasse.replaceAll("strase", "strasse");
strasse = strasse.replaceAll("ßtrase", "strasse");
@@ -523,27 +522,27 @@
ort = ort.replaceAll("^maria[-\\s].", "");
ort = ort.replaceAll("\\bi(\\.?\\s|\\s)Sa(\\.|\\s)", "insachsen"); // neu
-
+
ort = ort.replaceAll(".\\bauf\\b", "xx"); // NEU 10.5.2012 "Bergen auf Rügen"
- ort = ort.replaceAll(".\\ban[\\.\\s]der\\b", "xx");
+ ort = ort.replaceAll(".\\ban[\\.\\s]der\\b", "xx");
ort = ort.replaceAll(".\\ban[\\.\\s]d[\\.\\s]\\b", "xx"); // neuneu
-
+
ort = ort.replaceAll(".\\bin[\\.\\s]der\\b", "xx"); // neuneu
ort = ort.replaceAll(".\\bin[\\.\\s]d[\\.\\s]\\b", "xx"); // neuneu
-
+
ort = ort.replaceAll(".\\bi[\\.\\s]der\\b", "xx"); // neuneu
ort = ort.replaceAll(".\\bi[\\.\\s]d[\\.\\s]\\b", "xx"); // neuneu
-
+
ort = ort.replaceAll(".\\bin\\b", "xx"); // neu
ort = ort.replaceAll(".\\bin\\b", "xx"); // neu
ort = ort.replaceAll(".\\bim\\b", "xx"); // neu
ort = ort.replaceAll(".\\bam\\b", "xx"); // neu
ort = ort.replaceAll(".\\ban\\b", "xx"); // neu
ort = ort.replaceAll(".\\bbei\\b", "xx"); // neu
-
- //ort = ort.replaceAll(".\\ba[\\.\\s]\\s?d[\\.\\s]", "xx"); // neu
+
+ // ort = ort.replaceAll(".\\ba[\\.\\s]\\s?d[\\.\\s]", "xx"); // neu
ort = ort.replaceAll(".\\ba[\\.\\s]\\s?d[\\.\\s]", "xx"); // Bad Neustadt a. d. Saale
-
+
ort = ort.replaceAll(".\\bi[\\.\\s]", "xx"); // neu
ort = ort.replaceAll(".\\ba[\\.\\s]", "xx"); // neu
ort = ort.replaceAll(".\\bb[\\.\\s]", "xx"); // neu
@@ -577,7 +576,7 @@
String strasse = LangUtil.removeTags(orginal).toLowerCase();
strasse = strasse.replaceAll("str\\.ße", "str.");
-
+
strasse = strasse.replaceAll("\\+", " ");
strasse = strasse.replaceAll("\\s\\s+", " ");
strasse = strasse.replaceAll("(\\d)\\s", "$1");
@@ -588,16 +587,15 @@
strasse = strasse.replaceAll("str[^\\.]\\b", "str.");
strasse = strasse.replaceAll("([^\\d^\\s])(\\d)", "$1 $2");
strasse = strasse.replaceAll("str$", "str.");
-
+
strasse = strasse.replaceAll("^Str\\.$", "");
{
// Großschreibung aller Anfangsbuchstaben, AUSSER in den Hausnummerzusätzen
// Wo ist die erste Zahl?
- Pattern firstNumP = RegexCache.getInstance().getPattern("\\b\\d");
int firstNumIdx = -1;
- Matcher firstNumM = firstNumP.matcher(strasse);
+ Matcher firstNumM = RegexCache.getInstance().getMatcher("\\b\\d", strasse);
if (firstNumM.find()) {
firstNumIdx = firstNumM.start();
boolean moreFound = true;
@@ -618,7 +616,7 @@
strasse = WordUtils.capitalize(strasse, new char[] { ' ', '-' });
strasse = strasse + s2;
}
-
+
strasse = strasse.replaceAll(" Dem ", " dem ");
strasse = strasse.replaceAll(" Der ", " der ");
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:19:49 UTC (rev 2016)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache.java 2012-05-26 21:52:49 UTC (rev 2017)
@@ -1,12 +1,13 @@
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.
@@ -32,9 +33,9 @@
/**
* 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.
+ * dass der selbe Sting nochmal auftaucht wird als zu gering eingeschätzt. TODO
**/
- private static final int CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH = 500;
+ private static final int CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH = 200;
private static final int CACHE_VALUES_TO_RESULT_SIZE = 500;
@@ -44,14 +45,8 @@
return singletonInstance != null ? singletonInstance : new RegexCache();
}
- // 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>>(
- CACHE_VALUES_TO_RESULT_SIZE);
- // private final LimitedConcurrentHashMap<Pattern, LimitedConcurrentHashMap<String, MyMatchResult>> matchers = new
- // LimitedConcurrentHashMap<Pattern, LimitedConcurrentHashMap<String, MyMatchResult>>(
- // CACHE_VALUES_TO_RESULT_SIZE, LimitedConcurrentHashMap.TRUNC_METHOD.OLDEST_GET);
-
+ 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 RegexCache() {
@@ -69,17 +64,13 @@
if (object == null)
return false;
final String value = object instanceof String ? (String) object : object.toString();
-
- // Matcher m = getMatcher(regex, value);
- // return m.find();
-
return result(regex, value) != null;
}
/**
* Liefert eine compiliertes RegEx Pattern aus dem Cache. Wenn es vorher nicht existierte wird es erstellt.
*/
- public Pattern getPattern(String regex) {
+ public Pattern getPattern(final String regex) {
synchronized (patterns) {
Pattern p = patterns.get(regex);
if (p == null) {
@@ -90,80 +81,12 @@
}
}
- // final static Map<String, ThreadLocal<Matcher>> matchersCachedThreadLocalPerRegex = Collections
- // .synchronizedMap(new LimitedHashMap<String, ThreadLocal<Matcher>>(10000, TRUNC_METHOD.OLDEST_GET));
-
- final static Map<String, ThreadLocal<Matcher>> matchersCachedThreadLocalPerRegex = new ConcurrentHashMap<String, ThreadLocal<Matcher>>(
- 10000);
-
- public static boolean matcherCache = false;
-
- /**
- * 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 Matcher getMatcher(final String regex, final String text) {
- if (!matcherCache) {
- return getPattern(regex).matcher(text);
- }
-
- ThreadLocal<Matcher> threadLocal = matchersCachedThreadLocalPerRegex.get(regex);
-
- synchronized (regex) {
-
- if (threadLocal == null) {
-
- threadLocal = new ThreadLocal<Matcher>() {
-
- @Override
- protected Matcher initialValue() {
- return getPattern(regex).matcher(text);
- }
- };
- matchersCachedThreadLocalPerRegex.put(regex, threadLocal);
- }
-
- }
-
- return threadLocal.get().reset(text);
+ return getPattern(regex).matcher(text);
}
/**
- * 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 Matcher getMatcher(final String regex, final String text) {
- // ThreadLocal<Matcher> threadLocal = matchersCachedThreadLocalPerRegex.get(regex);
- //
- // synchronized (regex) {
- //
- // if (threadLocal == null) {
- //
- // threadLocal = new ThreadLocal<Matcher>() {
- //
- // @Override
- // protected Matcher initialValue() {
- // return getPattern(regex).matcher(text);
- // }
- // };
- // matchersCachedThreadLocalPerRegex.put(regex, threadLocal);
- // }
- //
- // }
- //
- // return threadLocal.get().reset(text);
-
- // return getPattern(regex).matcher(text);
- // }
-
- /**
* Will throw java exceptions when pattern won't compile.
*
* @param regex
@@ -175,49 +98,30 @@
*/
public final MatchResult result(final String regex, final String value) {
- // Wenn der value-String zu lang ist, dann einfach so machten
- if (value.length() > CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH) {
- Matcher m = getMatcher(regex, value);
- boolean found = m.find();
- return found ? m.toMatchResult() : null;
- }
-
final Pattern pattern = getPattern(regex);
- ConcurrentHashMap<String, MyMatchResult> m;
-// synchronized (matcherResults) { matcherResults ist jetzt concurrent!
- m = matcherResults.get(pattern);
+ LimitedHashMap<String, MyMatchResult> m;
+ synchronized (matchers) {
+ m = matchers.get(pattern);
if (m == null) {
- matcherResults.put(pattern, m = new ConcurrentHashMap<String, MyMatchResult>(
- CACHE_VALUES_TO_RESULT_SIZE));
+ matchers.put(pattern, m = new LimitedHashMap<String, MyMatchResult>(CACHE_VALUES_TO_RESULT_SIZE,
+ TRUNC_METHOD.OLDEST_GET));
}
-// }
-
- // LimitedConcurrentHashMap<String, MyMatchResult> m;
- // synchronized (matchers) {
- // m = matchers.get(pattern);
- // if (m == null) {
- // matchers.put(pattern, m = new LimitedConcurrentHashMap<String, MyMatchResult>(
- // CACHE_VALUES_TO_RESULT_SIZE, TRUNC_METHOD.OLDEST_GET));
- // }
- // }
+ }
- MyMatchResult mResult;
-// synchronized (m) {
- mResult = m.get(value);
- if (mResult == null) {
- // final Matcher xm = pattern.matcher(value);
- final Matcher xm = getMatcher(regex, value);
+ MyMatchResult matcher;
+ synchronized (m) {
+ matcher = m.get(value);
+ if (matcher == null) {
+ final Matcher xm = pattern.matcher(value);
if (xm.find())
- mResult = new MyMatchResult(xm.toMatchResult());
+ matcher = new MyMatchResult(xm.toMatchResult());
else
- mResult = new MyMatchResult(null);
-
- m.put(regex, mResult); // Hat die gefehlt?
+ matcher = new MyMatchResult(null);
}
-// }
+ }
- return mResult.matcherResult;
+ return matcher.matcherResult;
}
}
Added: trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache2.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache2.java (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache2.java 2012-05-26 21:52:49 UTC (rev 2017)
@@ -0,0 +1,224 @@
+package de.schmitzm.regex;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 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 RegexCache2 {
+
+ /**
+ * 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.
+ **/
+ private static final int CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH = 500;
+
+ private static final int CACHE_VALUES_TO_RESULT_SIZE = 500;
+
+ private static RegexCache2 singletonInstance;
+
+ public static RegexCache2 getInstance() {
+ return singletonInstance != null ? singletonInstance : new RegexCache2();
+ }
+
+ // 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>>(
+ CACHE_VALUES_TO_RESULT_SIZE);
+ // private final LimitedConcurrentHashMap<Pattern, LimitedConcurrentHashMap<String, MyMatchResult>> matchers = new
+ // LimitedConcurrentHashMap<Pattern, LimitedConcurrentHashMap<String, MyMatchResult>>(
+ // CACHE_VALUES_TO_RESULT_SIZE, LimitedConcurrentHashMap.TRUNC_METHOD.OLDEST_GET);
+
+ private final ConcurrentHashMap<String, Pattern> patterns = new ConcurrentHashMap<String, Pattern>(1000);
+
+ private RegexCache2() {
+ }
+
+ /**
+ * 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();
+
+ // Matcher m = getMatcher(regex, value);
+ // return m.find();
+
+ return result(regex, value) != null;
+ }
+
+ /**
+ * Liefert eine compiliertes RegEx Pattern aus dem Cache. Wenn es vorher nicht existierte wird es erstellt.
+ */
+ public Pattern getPattern(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;
+ // }
+ }
+
+ // final static Map<String, ThreadLocal<Matcher>> matchersCachedThreadLocalPerRegex = Collections
+ // .synchronizedMap(new LimitedHashMap<String, ThreadLocal<Matcher>>(10000, TRUNC_METHOD.OLDEST_GET));
+
+ final static Map<String, ThreadLocal<Matcher>> matchersCachedThreadLocalPerRegex = new ConcurrentHashMap<String, ThreadLocal<Matcher>>(
+ 10000);
+
+ public static boolean matcherCache = true;
+ public static boolean resultsCache = false;
+
+ /**
+ * 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 Matcher getMatcher(final String regex, final String text) {
+
+ if (!matcherCache) {
+ return getPattern(regex).matcher(text);
+ }
+
+ ThreadLocal<Matcher> threadLocal = matchersCachedThreadLocalPerRegex.get(regex);
+
+ synchronized (regex) {
+
+ if (threadLocal == null) {
+
+ threadLocal = new ThreadLocal<Matcher>() {
+
+ @Override
+ protected Matcher initialValue() {
+ return getPattern(regex).matcher(text);
+ }
+ };
+ matchersCachedThreadLocalPerRegex.put(regex, threadLocal);
+ }
+
+ }
+
+ return threadLocal.get().reset(text);
+ }
+
+ /**
+ * 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 Matcher getMatcher(final String regex, final String text) {
+ // ThreadLocal<Matcher> threadLocal = matchersCachedThreadLocalPerRegex.get(regex);
+ //
+ // synchronized (regex) {
+ //
+ // if (threadLocal == null) {
+ //
+ // threadLocal = new ThreadLocal<Matcher>() {
+ //
+ // @Override
+ // protected Matcher initialValue() {
+ // return getPattern(regex).matcher(text);
+ // }
+ // };
+ // matchersCachedThreadLocalPerRegex.put(regex, threadLocal);
+ // }
+ //
+ // }
+ //
+ // return threadLocal.get().reset(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) {
+
+ // Wenn der value-String zu lang oder zu kurz ist, dann einfach so machten
+ if (!resultsCache || value.length() < 30 || value.length() > CACHE_VALUES_TO_RESULT_MAX_VALUE_LENGTH) {
+ Matcher m = getMatcher(regex, value);
+ boolean found = m.find();
+ return found ? m.toMatchResult() : null;
+ }
+
+ final Pattern pattern = getPattern(regex);
+
+ ConcurrentHashMap<String, MyMatchResult> m;
+ // synchronized (matcherResults) { matcherResults ist jetzt concurrent!
+ m = matcherResults.get(pattern);
+ if (m == null) {
+ matcherResults.put(pattern, m = new ConcurrentHashMap<String, MyMatchResult>());
+ }
+ // }
+
+ // LimitedConcurrentHashMap<String, MyMatchResult> m;
+ // synchronized (matchers) {
+ // m = matchers.get(pattern);
+ // if (m == null) {
+ // matchers.put(pattern, m = new LimitedConcurrentHashMap<String, MyMatchResult>(
+ // CACHE_VALUES_TO_RESULT_SIZE, TRUNC_METHOD.OLDEST_GET));
+ // }
+ // }
+
+ MyMatchResult mResult;
+ // synchronized (m) {
+ mResult = m.get(value);
+ if (mResult == null) {
+ // final Matcher xm = pattern.matcher(value);
+ final Matcher xm = getMatcher(regex, value);
+ if (xm.find())
+ mResult = new MyMatchResult(xm.toMatchResult());
+ else
+ mResult = new MyMatchResult(null);
+
+ m.put(regex, mResult); // Hat die gefehlt?
+ }
+ // }
+
+ return mResult.matcherResult;
+ }
+
+}
Property changes on: trunk/schmitzm-core/src/main/java/de/schmitzm/regex/RegexCache2.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
More information about the Schmitzm-commits
mailing list