提交 25ea2528 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Optimize ToDateTokenizer.getTokensInQuestion()

上级 07e12670
...@@ -265,7 +265,7 @@ public class ToDateParser { ...@@ -265,7 +265,7 @@ public class ToDateParser {
while (p.hasToParseData()) { while (p.hasToParseData()) {
List<ToDateTokenizer.FormatTokenEnum> tokenList = List<ToDateTokenizer.FormatTokenEnum> tokenList =
ToDateTokenizer.FormatTokenEnum.getTokensInQuestion(p.getFormatStr()); ToDateTokenizer.FormatTokenEnum.getTokensInQuestion(p.getFormatStr());
if (tokenList.isEmpty()) { if (tokenList == null) {
p.removeFirstChar(); p.removeFirstChar();
continue; continue;
} }
......
...@@ -9,9 +9,7 @@ import static java.lang.String.format; ...@@ -9,9 +9,7 @@ import static java.lang.String.format;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
...@@ -616,10 +614,9 @@ class ToDateTokenizer { ...@@ -616,10 +614,9 @@ class ToDateTokenizer {
// where "T" and "Z" are inlined // where "T" and "Z" are inlined
INLINE(PARSLET_INLINE, PATTERN_INLINE); INLINE(PARSLET_INLINE, PATTERN_INLINE);
private static final List<FormatTokenEnum> EMPTY_LIST = Collections private static final List<FormatTokenEnum> INLINE_LIST = Collections.singletonList(INLINE);
.emptyList();
private static final Map<Character, List<FormatTokenEnum>> CACHE = new HashMap<>(64); private static List<FormatTokenEnum>[] TOKENS;
private final ToDateParslet toDateParslet; private final ToDateParslet toDateParslet;
private final Pattern patternToUse; private final Pattern patternToUse;
...@@ -648,60 +645,52 @@ class ToDateTokenizer { ...@@ -648,60 +645,52 @@ class ToDateTokenizer {
/** /**
* Optimization: Only return a list of {@link FormatTokenEnum} that * Optimization: Only return a list of {@link FormatTokenEnum} that
* share the same 1st char using the 1st char of the 'to parse' * share the same 1st char using the 1st char of the 'to parse'
* formatStr. Or return empty list if no match. * formatStr. Or return {@code null} if no match.
* *
* @param formatStr the format string * @param formatStr the format string
* @return the list of tokens * @return the list of tokens, or {@code null}
*/ */
static List<FormatTokenEnum> getTokensInQuestion(String formatStr) { static List<FormatTokenEnum> getTokensInQuestion(String formatStr) {
List<FormatTokenEnum> result = EMPTY_LIST;
if (CACHE.size() <= 0) {
initCache();
}
if (formatStr != null && formatStr.length() > 0) { if (formatStr != null && formatStr.length() > 0) {
Character key = Character.toUpperCase(formatStr.charAt(0)); char key = Character.toUpperCase(formatStr.charAt(0));
switch (key) { if (key >= 'A' && key <= 'Y') {
case '"': List<FormatTokenEnum>[] tokens = TOKENS;
result = new ArrayList<>(); if (tokens == null) {
result.add(INLINE); tokens = initTokens();
break;
default:
result = CACHE.get(key);
} }
return tokens[key - 'A'];
} else if (key == '"') {
return INLINE_LIST;
} }
if (result == null) {
result = EMPTY_LIST;
} }
return result; return null;
} }
private static synchronized void initCache() { @SuppressWarnings("unchecked")
if (CACHE.size() <= 0) { private static List<FormatTokenEnum>[] initTokens() {
List<FormatTokenEnum>[] tokens = new List[25];
for (FormatTokenEnum token : FormatTokenEnum.values()) { for (FormatTokenEnum token : FormatTokenEnum.values()) {
String name = token.name();
List<Character> tokenKeys = new ArrayList<>(); if (name.indexOf('_') >= 0) {
for (String tokenLets : name.split("_")) {
if (token.name().contains("_")) { putToCache(tokens, token, tokenLets);
String[] tokens = token.name().split("_");
for (String tokenLets : tokens) {
tokenKeys.add(tokenLets.toUpperCase().charAt(0));
} }
} else { } else {
tokenKeys.add(token.name().toUpperCase().charAt(0)); putToCache(tokens, token, name);
}
}
return TOKENS = tokens;
} }
for (Character tokenKey : tokenKeys) { private static void putToCache(List<FormatTokenEnum>[] cache, FormatTokenEnum token, String name) {
List<FormatTokenEnum> l = CACHE.get(tokenKey); int idx = Character.toUpperCase(name.charAt(0)) - 'A';
List<FormatTokenEnum> l = cache[idx];
if (l == null) { if (l == null) {
l = new ArrayList<>(1); l = new ArrayList<>(1);
CACHE.put(tokenKey, l); cache[idx] = l;
} }
l.add(token); l.add(token);
} }
}
}
}
/** /**
* Parse the format-string with passed token of {@link FormatTokenEnum}. * Parse the format-string with passed token of {@link FormatTokenEnum}.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论