ICU-12534 Optimizing currency spacing data loading in ICUCurrencyDisplayInfoProvider using data sink.

X-SVN-Rev: 38772
This commit is contained in:
Shane Carr 2016-05-31 16:34:58 +00:00
parent f2cf8cd5ac
commit d03ad991d9
3 changed files with 105 additions and 44 deletions

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 2009-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2009-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.impl;
@ -40,24 +40,40 @@ public class CurrencyData {
}
public static final class CurrencySpacingInfo {
public final String beforeCurrencyMatch;
public final String beforeContextMatch;
public final String beforeInsert;
public final String afterCurrencyMatch;
public final String afterContextMatch;
public final String afterInsert;
private final String[][] symbols = new String[SpacingType.COUNT.ordinal()][SpacingPattern.COUNT.ordinal()];
public CurrencySpacingInfo(
String beforeCurrencyMatch, String beforeContextMatch, String beforeInsert,
String afterCurrencyMatch, String afterContextMatch, String afterInsert) {
this.beforeCurrencyMatch = beforeCurrencyMatch;
this.beforeContextMatch = beforeContextMatch;
this.beforeInsert = beforeInsert;
this.afterCurrencyMatch = afterCurrencyMatch;
this.afterContextMatch = afterContextMatch;
this.afterInsert = afterInsert;
public static enum SpacingType { BEFORE, AFTER, COUNT };
public static enum SpacingPattern { CURRENCY_MATCH, SURROUNDING_MATCH, INSERT_BETWEEN, COUNT };
public CurrencySpacingInfo() {}
public CurrencySpacingInfo(String... strings) {
assert strings.length == 6;
int k = 0;
for (int i=0; i<SpacingType.COUNT.ordinal(); i++) {
for (int j=0; j<SpacingPattern.COUNT.ordinal(); j++) {
symbols[i][j] = strings[k];
k++;
}
}
}
public void setSymbolIfNull(SpacingType type, SpacingPattern pattern, String value) {
int i = type.ordinal();
int j = pattern.ordinal();
if (symbols[i][j] == null) {
symbols[i][j] = value;
}
}
public String[] getBeforeSymbols() {
return symbols[SpacingType.BEFORE.ordinal()];
}
public String[] getAfterSymbols() {
return symbols[SpacingType.AFTER.ordinal()];
}
private static final String DEFAULT_CUR_MATCH = "[:letter:]";
private static final String DEFAULT_CTX_MATCH = "[:digit:]";

View file

@ -662,20 +662,23 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* {@icu} Indicates the currency match pattern used in {@link #getPatternForCurrencySpacing}.
* @stable ICU 4.2
*/
public static final int CURRENCY_SPC_CURRENCY_MATCH = 0;
public static final int CURRENCY_SPC_CURRENCY_MATCH =
CurrencySpacingInfo.SpacingPattern.CURRENCY_MATCH.ordinal();
/**
* {@icu} Indicates the surrounding match pattern used in {@link
* #getPatternForCurrencySpacing}.
* @stable ICU 4.2
*/
public static final int CURRENCY_SPC_SURROUNDING_MATCH = 1;
public static final int CURRENCY_SPC_SURROUNDING_MATCH =
CurrencySpacingInfo.SpacingPattern.SURROUNDING_MATCH.ordinal();
/**
* {@icu} Indicates the insertion value used in {@link #getPatternForCurrencySpacing}.
* @stable ICU 4.4
*/
public static final int CURRENCY_SPC_INSERT = 2;
public static final int CURRENCY_SPC_INSERT =
CurrencySpacingInfo.SpacingPattern.INSERT_BETWEEN.ordinal();
private String[] currencySpcBeforeSym;
private String[] currencySpcAfterSym;
@ -976,8 +979,6 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
// Get currency spacing data.
currencySpcBeforeSym = new String[3];
currencySpcAfterSym = new String[3];
initSpacingInfo(info.getSpacingInfo());
}
@ -1064,12 +1065,8 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
}
private void initSpacingInfo(CurrencySpacingInfo spcInfo) {
currencySpcBeforeSym[CURRENCY_SPC_CURRENCY_MATCH] = spcInfo.beforeCurrencyMatch;
currencySpcBeforeSym[CURRENCY_SPC_SURROUNDING_MATCH] = spcInfo.beforeContextMatch;
currencySpcBeforeSym[CURRENCY_SPC_INSERT] = spcInfo.beforeInsert;
currencySpcAfterSym[CURRENCY_SPC_CURRENCY_MATCH] = spcInfo.afterCurrencyMatch;
currencySpcAfterSym[CURRENCY_SPC_SURROUNDING_MATCH] = spcInfo.afterContextMatch;
currencySpcAfterSym[CURRENCY_SPC_INSERT] = spcInfo.afterInsert;
currencySpcBeforeSym = spcInfo.getBeforeSymbols();
currencySpcAfterSym = spcInfo.getAfterSymbols();
}
/**

View file

@ -136,7 +136,7 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
return map;
}
@Override
@Override
public Map<String, String> getUnitPatterns() {
Map<String, String> result = new HashMap<String, String>();
@ -183,24 +183,72 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
@Override
public CurrencySpacingInfo getSpacingInfo() {
ICUResourceBundle srb = rb.findWithFallback("currencySpacing");
if (srb != null) {
ICUResourceBundle brb = srb.findWithFallback("beforeCurrency");
ICUResourceBundle arb = srb.findWithFallback("afterCurrency");
if (arb != null && brb != null) {
String beforeCurrencyMatch = brb.findStringWithFallback("currencyMatch");
String beforeContextMatch = brb.findStringWithFallback("surroundingMatch");
String beforeInsert = brb.findStringWithFallback("insertBetween");
String afterCurrencyMatch = arb.findStringWithFallback("currencyMatch");
String afterContextMatch = arb.findStringWithFallback("surroundingMatch");
String afterInsert = arb.findStringWithFallback("insertBetween");
SpacingInfoSink sink = new SpacingInfoSink();
rb.getAllItemsWithFallback("currencySpacing", sink);
return sink.getSpacingInfo(fallback);
}
return new CurrencySpacingInfo(
beforeCurrencyMatch, beforeContextMatch, beforeInsert,
afterCurrencyMatch, afterContextMatch, afterInsert);
private final class SpacingInfoSink extends UResource.Sink {
CurrencySpacingInfo spacingInfo = new CurrencySpacingInfo();
boolean hasBeforeCurrency = false;
boolean hasAfterCurrency = false;
/*
* currencySpacing{
* afterCurrency{
* currencyMatch{"[:^S:]"}
* insertBetween{" "}
* surroundingMatch{"[:digit:]"}
* }
* beforeCurrency{
* currencyMatch{"[:^S:]"}
* insertBetween{" "}
* surroundingMatch{"[:digit:]"}
* }
* }
*/
@Override
public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
UResource.Table spacingTypesTable = value.getTable();
for (int i = 0; spacingTypesTable.getKeyAndValue(i, key, value); ++i) {
CurrencySpacingInfo.SpacingType type;
if (key.contentEquals("beforeCurrency")) {
type = CurrencySpacingInfo.SpacingType.BEFORE;
hasBeforeCurrency = true;
} else if (key.contentEquals("afterCurrency")) {
type = CurrencySpacingInfo.SpacingType.AFTER;
hasAfterCurrency = true;
} else {
continue;
}
UResource.Table patternsTable = value.getTable();
for (int j = 0; patternsTable.getKeyAndValue(j, key, value); ++j) {
CurrencySpacingInfo.SpacingPattern pattern;
if (key.contentEquals("currencyMatch")) {
pattern = CurrencySpacingInfo.SpacingPattern.CURRENCY_MATCH;
} else if (key.contentEquals("surroundingMatch")) {
pattern = CurrencySpacingInfo.SpacingPattern.SURROUNDING_MATCH;
} else if (key.contentEquals("insertBetween")) {
pattern = CurrencySpacingInfo.SpacingPattern.INSERT_BETWEEN;
} else {
continue;
}
spacingInfo.setSymbolIfNull(type, pattern, value.getString());
}
}
}
CurrencySpacingInfo getSpacingInfo(boolean fallback) {
if (hasBeforeCurrency && hasAfterCurrency) {
return spacingInfo;
} else if (fallback) {
return CurrencySpacingInfo.DEFAULT;
} else {
return null;
}
}
return fallback ? CurrencySpacingInfo.DEFAULT : null;
}
private Map<String, String> _createSymbolMap() {