mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
ICU-6708 Static Hashtable caching of NumberingSystem object instances in NumberFormat, C implementation - with crash fix
X-SVN-Rev: 26428
This commit is contained in:
parent
71cc388673
commit
3bdd87634d
1 changed files with 81 additions and 6 deletions
|
@ -102,6 +102,28 @@ static const UChar * const gLastResortNumberPatterns[] =
|
|||
gLastResortPluralCurrencyPat,
|
||||
};
|
||||
|
||||
// Static hashtable cache of NumberingSystem objects used by NumberFormat
|
||||
static UHashtable * NumberingSystem_cache = NULL;
|
||||
|
||||
/**
|
||||
* Release all static memory held by Number Format.
|
||||
*/
|
||||
U_CDECL_BEGIN
|
||||
static void U_CALLCONV
|
||||
deleteNumberingSystem(void *obj) {
|
||||
delete (NumberingSystem *)obj;
|
||||
}
|
||||
|
||||
static UBool U_CALLCONV NSCache_cleanup(void) {
|
||||
if (NumberingSystem_cache) {
|
||||
// delete NumberingSystem_cache;
|
||||
uhash_close(NumberingSystem_cache);
|
||||
NumberingSystem_cache = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
// *****************************************************************************
|
||||
// class NumberFormat
|
||||
// *****************************************************************************
|
||||
|
@ -880,6 +902,8 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
|
|||
UResourceBundle *numberPatterns = ures_getByKey(resource, DecimalFormat::fgNumberPatterns, NULL, &status);
|
||||
NumberingSystem *ns = NULL;
|
||||
UBool deleteSymbols = TRUE;
|
||||
UHashtable * cache;
|
||||
int32_t hashKey;
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
// We don't appear to have resource data available -- use the last-resort data
|
||||
|
@ -927,9 +951,62 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
|
|||
}
|
||||
}
|
||||
|
||||
ns = NumberingSystem::createInstance(desiredLocale,status);
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
// Use numbering system cache hashtable
|
||||
umtx_lock(NULL);
|
||||
cache = NumberingSystem_cache;
|
||||
umtx_unlock(NULL);
|
||||
|
||||
// Check cache we got, create if non-existant
|
||||
status = U_ZERO_ERROR;
|
||||
if (cache == NULL) {
|
||||
cache = uhash_open(uhash_hashLong,
|
||||
uhash_compareLong,
|
||||
NULL,
|
||||
&status);
|
||||
|
||||
if (cache == NULL || U_FAILURE(status)) {
|
||||
// cache not created - out of memory
|
||||
cache = NULL;
|
||||
}
|
||||
else {
|
||||
// cache created
|
||||
uhash_setValueDeleter(cache, deleteNumberingSystem);
|
||||
|
||||
// set final NumberingSystem_cache value
|
||||
UHashtable* h;
|
||||
umtx_lock(NULL);
|
||||
h = NumberingSystem_cache;
|
||||
if (h == NULL) {
|
||||
NumberingSystem_cache = h = cache;
|
||||
cache = NULL;
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, NSCache_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
if(cache != NULL) {
|
||||
delete cache;
|
||||
}
|
||||
cache = h;
|
||||
}
|
||||
}
|
||||
|
||||
// Get cached numbering system
|
||||
if (cache != NULL) {
|
||||
hashKey = desiredLocale.hashCode();
|
||||
umtx_lock(NULL);
|
||||
ns = (NumberingSystem *)uhash_iget(cache, hashKey);
|
||||
if (ns == NULL) {
|
||||
ns = NumberingSystem::createInstance(desiredLocale,status);
|
||||
uhash_iput(cache, hashKey, (void*)ns, &status);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
else {
|
||||
ns = NumberingSystem::createInstance(desiredLocale,status);
|
||||
}
|
||||
|
||||
// check results of getting a numbering system
|
||||
if ((ns == NULL) || (U_FAILURE(status))) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -989,9 +1066,7 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
|
|||
cleanup:
|
||||
ures_close(numberPatterns);
|
||||
ures_close(resource);
|
||||
if (ns) {
|
||||
delete ns;
|
||||
}
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
/* If f exists, then it will delete the symbols */
|
||||
if (f==NULL) {
|
||||
|
|
Loading…
Add table
Reference in a new issue