ICU-5225 Minor speed improvement for opening and closing converters

by storing information about whether converter options are on the canonical converter name.

X-SVN-Rev: 19707
This commit is contained in:
George Rhoten 2006-06-12 10:05:08 +00:00
parent f7ad33b0b7
commit 78f8b26a73
4 changed files with 38 additions and 14 deletions

View File

@ -160,6 +160,7 @@ static uint16_t gAvailableConverterCount = 0;
static char gDefaultConverterNameBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH + 1]; /* +1 for NULL */
static const char *gDefaultConverterName = NULL;
static UBool gDefaultConverterContainsOption;
static const char DATA_TYPE[] = "cnv";
@ -182,6 +183,7 @@ static UBool U_CALLCONV ucnv_cleanup(void) {
gDefaultConverterName = NULL;
gDefaultConverterNameBuffer[0] = 0;
gDefaultConverterContainsOption = FALSE;
umtx_destroy(&cnvCacheMutex); /* Don't worry about destroying the mutex even */
/* if the hash table still exists. The mutex */
@ -658,6 +660,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
UConverterLookupData stackLookup;
UConverterSharedData *mySharedConverterData = NULL;
UErrorCode internalErrorCode = U_ZERO_ERROR;
UBool mayContainOption = TRUE;
if (U_FAILURE (*err)) {
return NULL;
@ -673,6 +676,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
/* In case "name" is NULL we want to open the default converter. */
if (converterName == NULL) {
lookup->realName = ucnv_getDefaultName();
mayContainOption = gDefaultConverterContainsOption;
if (lookup->realName == NULL) {
*err = U_MISSING_RESOURCE_ERROR;
return NULL;
@ -687,7 +691,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
}
/* get the canonical converter name */
lookup->realName = ucnv_io_getConverterName(lookup->cnvName, &internalErrorCode);
lookup->realName = ucnv_io_getConverterName(lookup->cnvName, &mayContainOption, &internalErrorCode);
if (U_FAILURE(internalErrorCode) || lookup->realName == NULL) {
/*
* set the input name in case the converter was added
@ -698,7 +702,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
}
/* separate the converter name from the options */
if(lookup->realName != lookup->cnvName) {
if(mayContainOption && lookup->realName != lookup->cnvName) {
parseConverterOptions(lookup->realName, lookup->cnvName, lookup->locale, &lookup->options, err);
lookup->realName = lookup->cnvName;
}
@ -1113,6 +1117,7 @@ ucnv_getDefaultName() {
uprv_memcpy(gDefaultConverterNameBuffer, name, length);
gDefaultConverterNameBuffer[length]=0;
gDefaultConverterName = gDefaultConverterNameBuffer;
gDefaultConverterContainsOption = (UBool)(uprv_strchr(gDefaultConverterName, UCNV_OPTION_SEP_CHAR) != NULL);
name = gDefaultConverterName;
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
umtx_unlock(&cnvCacheMutex);
@ -1133,7 +1138,7 @@ ucnv_setDefaultName(const char *converterName) {
umtx_unlock(&cnvCacheMutex);
} else {
UErrorCode errorCode=U_ZERO_ERROR;
const char *name=ucnv_io_getConverterName(converterName, &errorCode);
const char *name=ucnv_io_getConverterName(converterName, NULL, &errorCode);
umtx_lock(&cnvCacheMutex);
@ -1147,6 +1152,7 @@ ucnv_setDefaultName(const char *converterName) {
uprv_memcpy(gDefaultConverterNameBuffer, converterName, length);
gDefaultConverterNameBuffer[length]=0;
gDefaultConverterName=gDefaultConverterNameBuffer;
gDefaultConverterContainsOption = (UBool)(uprv_strchr(gDefaultConverterName, UCNV_OPTION_SEP_CHAR) != NULL);
}
}
umtx_unlock(&cnvCacheMutex);

View File

@ -73,6 +73,8 @@
* index of this list is also used by other sections, like the 4th section.
* The index for the 3rd and 4th section is used to get the
* alias -> converter name mapping. Section 3 and 4 form a two column table.
* Some of the most significant bits of each index may contain other
* information (see findConverter for details).
*
* 4) This section contains a list of mapped converter names. Consider this
* as a table that maps the 3rd section to the 1st section. This list contains
@ -187,7 +189,8 @@ enum {
};
static const UConverterAliasOptions defaultTableOptions = {
UCNV_IO_UNNORMALIZED
UCNV_IO_UNNORMALIZED,
0 /* containsCnvOptionInfo */
};
static UConverterAlias gMainTable;
@ -435,7 +438,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
* return the converter number index for gConverterList
*/
static U_INLINE uint32_t
findConverter(const char *alias, UErrorCode *pErrorCode) {
findConverter(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) {
uint32_t mid, start, limit;
uint32_t lastMid;
int result;
@ -484,6 +487,14 @@ findConverter(const char *alias, UErrorCode *pErrorCode) {
if (gMainTable.untaggedConvArray[mid] & UCNV_AMBIGUOUS_ALIAS_MAP_BIT) {
*pErrorCode = U_AMBIGUOUS_ALIAS_WARNING;
}
/* State whether the canonical converter name contains an option.
This information is contained in this list in order to maintain backward & forward compatibility. */
if (containsOption) {
UBool containsCnvOptionInfo = (UBool)gMainTable.optionTable->containsCnvOptionInfo;
*containsOption = (UBool)((containsCnvOptionInfo
&& ((gMainTable.untaggedConvArray[mid] & UCNV_CONTAINS_OPTION_BIT) != 0))
|| !containsCnvOptionInfo);
}
return gMainTable.untaggedConvArray[mid] & UCNV_CONVERTER_INDEX_MASK;
}
}
@ -528,7 +539,7 @@ findTaggedAliasListsOffset(const char *alias, const char *standard, UErrorCode *
uint32_t tagNum = getTagNumber(standard);
/* Make a quick guess. Hopefully they used a TR22 canonical alias. */
convNum = findConverter(alias, &myErr);
convNum = findConverter(alias, NULL, &myErr);
if (myErr != U_ZERO_ERROR) {
*pErrorCode = myErr;
}
@ -579,7 +590,7 @@ findTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErr
uint32_t tagNum = getTagNumber(standard);
/* Make a quick guess. Hopefully they used a TR22 canonical alias. */
convNum = findConverter(alias, &myErr);
convNum = findConverter(alias, NULL, &myErr);
if (myErr != U_ZERO_ERROR) {
*pErrorCode = myErr;
}
@ -615,9 +626,9 @@ findTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErr
U_CFUNC const char *
ucnv_io_getConverterName(const char *alias, UErrorCode *pErrorCode) {
ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) {
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
uint32_t convNum = findConverter(alias, pErrorCode);
uint32_t convNum = findConverter(alias, containsOption, pErrorCode);
if (convNum < gMainTable.converterListSize) {
return GET_STRING(gMainTable.converterList[convNum]);
}
@ -724,7 +735,7 @@ ucnv_openStandardNames(const char *convName,
static uint16_t
ucnv_io_countAliases(const char *alias, UErrorCode *pErrorCode) {
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
uint32_t convNum = findConverter(alias, pErrorCode);
uint32_t convNum = findConverter(alias, NULL, pErrorCode);
if (convNum < gMainTable.converterListSize) {
/* tagListNum - 1 is the ALL tag */
int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum];
@ -743,7 +754,7 @@ static uint16_t
ucnv_io_getAliases(const char *alias, uint16_t start, const char **aliases, UErrorCode *pErrorCode) {
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
uint32_t currAlias;
uint32_t convNum = findConverter(alias, pErrorCode);
uint32_t convNum = findConverter(alias, NULL, pErrorCode);
if (convNum < gMainTable.converterListSize) {
/* tagListNum - 1 is the ALL tag */
int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum];
@ -767,7 +778,7 @@ ucnv_io_getAliases(const char *alias, uint16_t start, const char **aliases, UErr
static const char *
ucnv_io_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) {
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
uint32_t convNum = findConverter(alias, pErrorCode);
uint32_t convNum = findConverter(alias, NULL, pErrorCode);
if (convNum < gMainTable.converterListSize) {
/* tagListNum - 1 is the ALL tag */
int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum];

View File

@ -20,6 +20,7 @@
#include "udataswp.h"
#define UCNV_AMBIGUOUS_ALIAS_MAP_BIT 0x8000
#define UCNV_CONTAINS_OPTION_BIT 0x4000
#define UCNV_CONVERTER_INDEX_MASK 0xFFF
#define UCNV_NUM_RESERVED_TAGS 2
#define UCNV_NUM_HIDDEN_TAGS 1
@ -32,6 +33,7 @@ typedef enum {
typedef struct {
uint16_t stringNormalizationType;
uint16_t containsCnvOptionInfo;
} UConverterAliasOptions;
typedef struct UConverterAlias {
@ -85,11 +87,12 @@ ucnv_io_stripEBCDICForCompare(char *dst, const char *name);
* is returned in mixed-case.
* Returns NULL if the alias is not found.
* @param alias The alias name to be searched.
* @param containsOption A return value stating whether the returned converter name contains an option (a comma)
* @param pErrorCode The error code
* @return the converter name in mixed-case, return NULL if the alias is not found.
*/
U_CFUNC const char *
ucnv_io_getConverterName(const char *alias, UErrorCode *pErrorCode);
ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode);
/**
* Return the number of all aliases and converter names.

View File

@ -138,7 +138,8 @@ static UBool verbose = FALSE;
static int lineNum = 1;
static UConverterAliasOptions tableOptions = {
UCNV_IO_UNNORMALIZED
UCNV_IO_UNNORMALIZED,
1 /* containsCnvOptionInfo */
};
/* prototypes --------------------------------------------------------------- */
@ -880,6 +881,9 @@ resolveAliases(uint16_t *uniqueAliasArr, uint16_t *uniqueAliasToConverterArr, ui
oldTagNum = currTagNum;
/*printf("%s -> %s\n", GET_ALIAS_STR(knownAliases[idx]), GET_ALIAS_STR(converters[currConvNum].converter));*/
}
if (uprv_strchr(GET_ALIAS_STR(converters[currConvNum].converter), UCNV_OPTION_SEP_CHAR) != NULL) {
uniqueAliasToConverterArr[uniqueAliasIdx-1] |= UCNV_CONTAINS_OPTION_BIT;
}
}
return uniqueAliasIdx;
}