Browse Source

This change improves performance by (1) Create a cacheing mechanism to cache frequently used cached regex (2) Precompile some known regexes. (3) Other misc improvements. It also (1) removes dependency to Guava library (2) creates new interfaces that accept parameters that could be reused instead of immutable ones.

pull/567/head
Shaopeng Jia 16 years ago
committed by Mihaela Rosca
parent
commit
364b70614e
5 changed files with 414 additions and 247 deletions
  1. +278
    -243
      java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
  2. +76
    -0
      java/src/com/google/i18n/phonenumbers/RegexCache.java
  3. +2
    -2
      java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java
  4. +2
    -2
      java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
  5. +56
    -0
      java/test/com/google/i18n/phonenumbers/RegexCacheTest.java

+ 278
- 243
java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
File diff suppressed because it is too large
View File


+ 76
- 0
java/src/com/google/i18n/phonenumbers/RegexCache.java View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.i18n.phonenumbers;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* LRU Cache for compiled regular expressions used by the libphonenumbers libary.
*
* @author Shaopeng Jia
*/
public class RegexCache {
private LRUCache<String, Pattern> cache;
public RegexCache(int size) {
cache = new LRUCache<String, Pattern>(size);
}
public Pattern getPatternForRegex(String regex) {
if (containsRegex(regex)) {
return cache.get(regex);
} else {
Pattern pattern = Pattern.compile(regex);
cache.put(regex, pattern);
return pattern;
}
}
boolean containsRegex(String regex) {
return cache.containsKey(regex);
}
private class LRUCache<K, V> {
private LinkedHashMap<K, V> map;
private int size;
public LRUCache(int size) {
this.size = size;
map = new LinkedHashMap<K, V>(size*4/3+1, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > LRUCache.this.size;
}
};
}
public synchronized V get(K key) {
return map.get(key);
}
public synchronized void put(K key, V value) {
map.put(key, value);
}
public synchronized boolean containsKey(K key) {
return map.containsKey(key);
}
}
}

+ 2
- 2
java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java View File

@ -64,8 +64,8 @@ public class AsYouTypeFormatterTest extends TestCase {
assertEquals("1 650 253 2", formatter.inputDigit('2')); assertEquals("1 650 253 2", formatter.inputDigit('2'));
assertEquals("1 650 253 22", formatter.inputDigit('2')); assertEquals("1 650 253 22", formatter.inputDigit('2'));
assertEquals("1 650 253 222", formatter.inputDigit('2')); assertEquals("1 650 253 222", formatter.inputDigit('2'));
assertEquals("1 650 253 2222", formatter.inputDigit('2'));
assertEquals("1 650 253 2222", formatter.inputDigit('2'));
formatter.clear(); formatter.clear();
assertEquals("6", formatter.inputDigit('6')); assertEquals("6", formatter.inputDigit('6'));
assertEquals("65", formatter.inputDigit('5')); assertEquals("65", formatter.inputDigit('5'));


+ 2
- 2
java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java View File

@ -1339,7 +1339,7 @@ public class PhoneNumberUtilTest extends TestCase {
} }
try { try {
String someNumber = "123 456 7890"; String someNumber = "123 456 7890";
phoneUtil.parse(someNumber, "ZZ");
phoneUtil.parse(someNumber, "YY");
fail("'Unknown' country code not allowed: should fail."); fail("'Unknown' country code not allowed: should fail.");
} catch (NumberParseException e) { } catch (NumberParseException e) {
// Expected this exception. // Expected this exception.
@ -1482,7 +1482,7 @@ public class PhoneNumberUtilTest extends TestCase {
.setRawInput("+1800 six-flag") .setRawInput("+1800 six-flag")
.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).build(); .setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).build();
assertEquals(alphaNumericNumber3, assertEquals(alphaNumericNumber3,
phoneUtil.parseAndKeepRawInput("+1800 six-flag", "CN"));
phoneUtil.parseAndKeepRawInput("+1800 six-flag", "NZ"));
PhoneNumber alphaNumericNumber4 = PhoneNumber alphaNumericNumber4 =
PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(18007493524L) PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(18007493524L)


+ 56
- 0
java/test/com/google/i18n/phonenumbers/RegexCacheTest.java View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.i18n.phonenumbers;
import junit.framework.TestCase;
import java.util.regex.Pattern;
/**
* Unittests for LRU Cache for compiled regular expressions used by the libphonenumbers libary.
*
* @author Shaopeng Jia
*/
public class RegexCacheTest extends TestCase {
private RegexCache regexCache;
public RegexCacheTest() {
regexCache = new RegexCache(2);
}
public void testRegexInsertion() {
final String regex1 = "[1-5]";
final String regex2 = "(?:12|34)";
final String regex3 = "[1-3][58]";
regexCache.getPatternForRegex(regex1);
assertTrue(regexCache.containsRegex(regex1));
regexCache.getPatternForRegex(regex2);
assertTrue(regexCache.containsRegex(regex2));
regexCache.getPatternForRegex(regex1);
assertTrue(regexCache.containsRegex(regex1));
regexCache.getPatternForRegex(regex3);
assertTrue(regexCache.containsRegex(regex3));
assertFalse(regexCache.containsRegex(regex2));
assertTrue(regexCache.containsRegex(regex1));
}
}

Loading…
Cancel
Save