ICU-4084 Improve DateFormat construction performance.

X-SVN-Rev: 16223
This commit is contained in:
George Rhoten 2004-08-31 18:04:12 +00:00
parent b637e0ffb0
commit db7d00f2cb
5 changed files with 113 additions and 140 deletions

View File

@ -23,7 +23,6 @@
#if !UCONFIG_NO_FORMATTING
#include "unicode/dtfmtsym.h"
#include "unicode/resbund.h"
#include "unicode/smpdtfmt.h"
#include "ucln_in.h"
#include "mutex.h"
@ -40,7 +39,7 @@
* resource data.
*/
#define PATTERN_CHARS_LEN 20
#define PATTERN_CHARS_LEN 24
/**
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All
@ -48,9 +47,9 @@
*/
static const UChar gPatternChars[] = {
// GyMdkHmsSEDFwWahKzYeugAZ
0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45, 0x44,
0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65, 0x75, 0x67,
0x41, 0x5A, 0
0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,
0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,
0x75, 0x67, 0x41, 0x5A, 0
};
//------------------------------------------------------
@ -511,14 +510,16 @@ DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChar
//------------------------------------------------------
void
DateFormatSymbols::initField(UnicodeString **field, int32_t& length, const ResourceBundle &data, UErrorCode &status) {
DateFormatSymbols::initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) {
if (U_SUCCESS(status)) {
length = data.getSize();
int32_t strLen = 0;
length = ures_getSize(data);
*field = newUnicodeStringArray(length);
if (*field) {
for(int32_t i = 0; i<length; i++) {
// fastCopyFrom() - see assignArray comments
(*(field)+i)->fastCopyFrom(data.getStringEx(i, status));
const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status);
// setTo() - see assignArray comments
(*(field)+i)->setTo(TRUE, resStr, strLen);
}
}
else {
@ -583,9 +584,10 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
UResourceBundle *nonCalendarData = ures_open((char*)0, locale.getName(), &status);
// load the first data item
ResourceBundle eras(calData.getBundleByKey(gErasTag, status).getWithFallback(gAbbreviatedTag, status));
ResourceBundle lsweekdaysData(calData.getBundleByKey2(gDayNamesTag, gNamesAbbrTag, status));
ResourceBundle weekdaysData(calData.getBundleByKey2(gDayNamesTag, gNamesWideTag, status));
UResourceBundle *erasMain = calData.getByKey(gErasTag, status);
UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gAbbreviatedTag, NULL, &status);
UResourceBundle *lsweekdaysData = NULL; // Data closed by calData
UResourceBundle *weekdaysData = NULL; // Data closed by calData
UResourceBundle *zoneArray = ures_getByKey(nonCalendarData, gZoneStringsTag, NULL, &status);
UResourceBundle *zoneRow = ures_getByIndex(zoneArray, (int32_t)0, NULL, &status);
U_LOCALE_BASED(locBased, *this);
@ -622,16 +624,21 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
// if we make it to here, the resource data is cool, and we can get everything out
// of it that we need except for the time-zone and localized-pattern data, which
// are stored in a separate file
locBased.setLocaleIDs(eras.getLocale(ULOC_VALID_LOCALE, status).getName(),
eras.getLocale(ULOC_ACTUAL_LOCALE, status).getName());
locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status));
initField(&fEras, fErasCount, eras, status);
initField(&fMonths, fMonthsCount, calData.getBundleByKey2(gMonthNamesTag, gNamesWideTag, status), status);
initField(&fShortMonths, fShortMonthsCount, calData.getBundleByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
initField(&fAmPms, fAmPmsCount, calData.getBundleByKey(gAmPmMarkersTag, status), status);
initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status);
// fastCopyFrom()/setTo() - see assignArray comments
resStr = ures_getStringByKey(nonCalendarData, gLocalPatternCharsTag, &len, &status);
fLocalPatternChars.setTo(TRUE, resStr, len);
// If the locale data does not include new pattern chars, use the defaults
// TODO: Consider making this an error, since this may add conflicting characters.
if (len < PATTERN_CHARS_LEN) {
fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
}
/* TODO: Fix the case where the zoneStrings is not a perfect square array of information. */
fZoneStringsRowCount = ures_getSize(zoneArray);
@ -658,7 +665,8 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
}
// {sfb} fixed to handle 1-based weekdays
fWeekdaysCount = weekdaysData.getSize();
weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
fWeekdaysCount = ures_getSize(weekdaysData);
fWeekdays = new UnicodeString[fWeekdaysCount+1];
/* test for NULL */
if (fWeekdays == 0) {
@ -667,12 +675,14 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
}
// leave fWeekdays[0] empty
for(i = 0; i<fWeekdaysCount; i++) {
// fastCopyFrom() - see assignArray comments
fWeekdays[i+1].fastCopyFrom(weekdaysData.getStringEx(i, status));
resStr = ures_getStringByIndex(weekdaysData, i, &len, &status);
// setTo() - see assignArray comments
fWeekdays[i+1].setTo(TRUE, resStr, len);
}
fWeekdaysCount++;
fShortWeekdaysCount = lsweekdaysData.getSize();
lsweekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
fShortWeekdaysCount = ures_getSize(lsweekdaysData);
fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1];
/* test for NULL */
if (fShortWeekdays == 0) {
@ -681,16 +691,11 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
}
// leave fShortWeekdays[0] empty
for(i = 0; i<fShortWeekdaysCount; i++) {
// fastCopyFrom() - see assignArray comments
fShortWeekdays[i+1].fastCopyFrom(lsweekdaysData.getStringEx(i, status));
resStr = ures_getStringByIndex(lsweekdaysData, i, &len, &status);
// setTo() - see assignArray comments
fShortWeekdays[i+1].setTo(TRUE, resStr, len);
}
fShortWeekdaysCount++;
// If the locale data does not include new pattern chars, use the defaults
len = fLocalPatternChars.length();
if (len < PATTERN_CHARS_LEN) {
fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
}
cleanup:
ures_close(zoneRow);
ures_close(zoneArray);

View File

@ -174,63 +174,59 @@ void CalendarData::initData(const char *locale, const char *type, UErrorCode& st
}
CalendarData::~CalendarData() {
ures_close(fFillin);
ures_close(fBundle);
ures_close(fFallback);
ures_close(fOtherFillin);
ures_close(fFillin);
ures_close(fBundle);
ures_close(fFallback);
ures_close(fOtherFillin);
}
UResourceBundle*
CalendarData::getByKey(const char *key, UErrorCode& status) {
if(U_FAILURE(status)) {
return NULL;
}
if(U_FAILURE(status)) {
return NULL;
}
if(fBundle) {
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
if(fBundle) {
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
}
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
status = U_ZERO_ERROR; // retry with fallback (gregorian)
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
}
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
status = U_ZERO_ERROR; // retry with fallback (gregorian)
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
}
return fFillin;
}
ResourceBundle CalendarData::getBundleByKey(const char *key, UErrorCode &status) {
return ResourceBundle(getByKey(key,status), status);
}
return fFillin;
}
UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UErrorCode& status) {
if(U_FAILURE(status)) {
return NULL;
}
if(U_FAILURE(status)) {
return NULL;
}
if(fBundle) {
if(fBundle) {
#if defined (U_DEBUG_CALDATA)
fprintf(stderr, "%p: //\n");
fprintf(stderr, "%p: //\n");
#endif
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status));
fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status));
#endif
}
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
status = U_ZERO_ERROR; // retry with fallback (gregorian)
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
}
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
status = U_ZERO_ERROR; // retry with fallback (gregorian)
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
#if defined (U_DEBUG_CALDATA)
fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status));
fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status));
#endif
}
}
//// handling of 'default' keyword on failure: Commented out for 3.0.
// if((status == U_MISSING_RESOURCE_ERROR) &&
@ -265,11 +261,7 @@ UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UE
// }
// }
return fFillin;
}
ResourceBundle CalendarData::getBundleByKey2(const char *key, const char *subKey, UErrorCode& status) {
return ResourceBundle(getByKey2(key, subKey, status), status);
return fFillin;
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CalendarData);

View File

@ -262,66 +262,41 @@ inline int32_t Grego::gregorianShift(int32_t eyear) {
* @internal ICU 3.0
*/
class U_I18N_API CalendarData : public UObject {
public:
/**
* Construct a CalendarData from the given locale.
* @param loc locale to use - the 'calendar' keyword will be used, respecting the
* 'default' value in the resource bundle.
* @param status error code
*/
//CalendarData(const Locale& loc, UErrorCode& status);
public:
/**
* Construct a CalendarData from the given locale.
* @param loc locale to use. The 'calendar' keyword will be ignored.
* @param type calendar type. NULL indicates the gregorian calendar.
* No default lookup is done.
* @param status error code
*/
CalendarData(const Locale& loc, const char *type, UErrorCode& status);
/**
* Construct a CalendarData from the given locale.
* @param loc locale to use. The 'calendar' keyword will be ignored.
* @param type calendar type. NULL indicates the gregorian calendar.
* No default lookup is done.
* @param status error code
*/
CalendarData(const Locale& loc, const char *type, UErrorCode& status);
/**
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
*
* @param key Resource key to data
* @param status Error Status
* @internal
*/
UResourceBundle* getByKey(const char *key, UErrorCode& status);
/**
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
* The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
*
* @param key Resource key to data
* @param status Error Status
* @internal
*/
UResourceBundle* getByKey(const char *key, UErrorCode& status);
/**
* Load data for calendar. returns a ResourceBundle object
*
* @param key Resource key to data
* @param status Error Status
* @internal
*/
ResourceBundle getBundleByKey(const char *key, UErrorCode& status);
/**
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
* There is an implicit key of 'format'
* data is located in: "calendar/key/format/subKey"
* for example, calendar/dayNames/format/abbreviated
* The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
*
* @param key Resource key to data
* @param subKey Resource key to data
* @param status Error Status
* @internal
*/
UResourceBundle* getByKey2(const char *key, const char *subKey, UErrorCode& status);
/**
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
* There is an implicit key of 'format'
* data is located in: "calendar/key/format/subKey"
* for example, calendar/dayNames/format/abbreviated
*
* @param key Resource key to data
* @param subKey Resource key to data
* @param status Error Status
* @internal
*/
UResourceBundle* getByKey2(const char *key, const char *subKey, UErrorCode& status);
/**
* Load data for calendar. Returns a ResourceBundle object
*
* @param key Resource key to data
* @param subKey Resource key to data
* @param status Error Status
* @internal
*/
ResourceBundle getBundleByKey2(const char *key, const char *subKey, UErrorCode& status);
~CalendarData();
~CalendarData();
/**
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
@ -348,14 +323,14 @@ class U_I18N_API CalendarData : public UObject {
*/
static UClassID U_EXPORT2 getStaticClassID(void);
private:
void initData(const char *locale, const char *type, UErrorCode& status);
UResourceBundle *fFillin;
UResourceBundle *fOtherFillin;
UResourceBundle *fBundle;
UResourceBundle *fFallback;
CalendarData(); // Not implemented.
private:
void initData(const char *locale, const char *type, UErrorCode& status);
UResourceBundle *fFillin;
UResourceBundle *fOtherFillin;
UResourceBundle *fBundle;
UResourceBundle *fFallback;
CalendarData(); // Not implemented.
};
U_NAMESPACE_END

View File

@ -278,7 +278,8 @@ void SimpleDateFormat::construct(EStyle timeStyle,
initializeCalendar(NULL, locale, status);
CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
ResourceBundle dateTimePatterns = calData.getBundleByKey(gDateTimePatternsTag, status);
UResourceBundle *dtp = calData.getByKey(gDateTimePatternsTag, status);
ResourceBundle dateTimePatterns(dtp, status);
if (U_FAILURE(status)) return;
if (dateTimePatterns.getSize() <= kDateTime)

View File

@ -24,7 +24,7 @@
#include "unicode/uobject.h"
#include "unicode/locid.h"
#include "unicode/resbund.h"
#include "unicode/ures.h"
U_NAMESPACE_BEGIN
@ -412,7 +412,7 @@ private:
DateFormatSymbols(); // default constructor not implemented
void initField(UnicodeString **field, int32_t& length, const ResourceBundle &data, UErrorCode &status);
void initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status);
void initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status);
/**