Esempio n. 1
0
TimeZoneGenericNames*
TimeZoneGenericNames::createInstance(const Locale& locale, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    TimeZoneGenericNames* instance = new TimeZoneGenericNames();
    if (instance == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    TZGNCoreRef *cacheEntry = NULL;
    {
        Mutex lock(&gTZGNLock);

        if (!gTZGNCoreCacheInitialized) {
            // Create empty hashtable
            gTZGNCoreCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
            if (U_SUCCESS(status)) {
                uhash_setKeyDeleter(gTZGNCoreCache, uprv_free);
                uhash_setValueDeleter(gTZGNCoreCache, deleteTZGNCoreRef);
                gTZGNCoreCacheInitialized = TRUE;
                ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONEGENERICNAMES, tzgnCore_cleanup);
            }
        }
        if (U_FAILURE(status)) {
            return NULL;
        }

        // Check the cache, if not available, create new one and cache
        const char *key = locale.getName();
        cacheEntry = (TZGNCoreRef *)uhash_get(gTZGNCoreCache, key);
        if (cacheEntry == NULL) {
            TZGNCore *tzgnCore = NULL;
            char *newKey = NULL;

            tzgnCore = new TZGNCore(locale, status);
            if (tzgnCore == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
            }
            if (U_SUCCESS(status)) {
                newKey = (char *)uprv_malloc(uprv_strlen(key) + 1);
                if (newKey == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                } else {
                    uprv_strcpy(newKey, key);
                }
            }
            if (U_SUCCESS(status)) {
                cacheEntry = (TZGNCoreRef *)uprv_malloc(sizeof(TZGNCoreRef));
                if (cacheEntry == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                } else {
                    cacheEntry->obj = tzgnCore;
                    cacheEntry->refCount = 1;
                    cacheEntry->lastAccess = (double)uprv_getUTCtime();

                    uhash_put(gTZGNCoreCache, newKey, cacheEntry, &status);
                }
            }
            if (U_FAILURE(status)) {
                if (tzgnCore != NULL) {
                    delete tzgnCore;
                }
                if (newKey != NULL) {
                    uprv_free(newKey);
                }
                if (cacheEntry != NULL) {
                    uprv_free(cacheEntry);
                }
                cacheEntry = NULL;
            }
        } else {
            // Update the reference count
            cacheEntry->refCount++;
            cacheEntry->lastAccess = (double)uprv_getUTCtime();
        }
        gAccessCount++;
        if (gAccessCount >= SWEEP_INTERVAL) {
            // sweep
            sweepCache();
            gAccessCount = 0;
        }
    }  // End of mutex locked block

    if (cacheEntry == NULL) {
        delete instance;
        return NULL;
    }

    instance->fRef = cacheEntry;
    return instance;
}
Esempio n. 2
0
TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) {
    Mutex lock(&gTimeZoneNamesLock);
    if (!gTimeZoneNamesCacheInitialized) {
        // Create empty hashtable if it is not already initialized.
        gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
        if (U_SUCCESS(status)) {
            uhash_setKeyDeleter(gTimeZoneNamesCache, uprv_free);
            uhash_setValueDeleter(gTimeZoneNamesCache, deleteTimeZoneNamesCacheEntry);
            gTimeZoneNamesCacheInitialized = TRUE;
            ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONENAMES, timeZoneNames_cleanup);
        }
    }

    if (U_FAILURE(status)) {
        return;
    }

    // Check the cache, if not available, create new one and cache
    TimeZoneNamesCacheEntry *cacheEntry = NULL;

    const char *key = locale.getName();
    cacheEntry = (TimeZoneNamesCacheEntry *)uhash_get(gTimeZoneNamesCache, key);
    if (cacheEntry == NULL) {
        TimeZoneNames *tznames = NULL;
        char *newKey = NULL;

        tznames = new TimeZoneNamesImpl(locale, status);
        if (tznames == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
        }
        if (U_SUCCESS(status)) {
            newKey = (char *)uprv_malloc(uprv_strlen(key) + 1);
            if (newKey == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
            } else {
                uprv_strcpy(newKey, key);
            }
        }
        if (U_SUCCESS(status)) {
            cacheEntry = (TimeZoneNamesCacheEntry *)uprv_malloc(sizeof(TimeZoneNamesCacheEntry));
            if (cacheEntry == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
            } else {
                cacheEntry->names = tznames;
                cacheEntry->refCount = 1;
                cacheEntry->lastAccess = (double)uprv_getUTCtime();

                uhash_put(gTimeZoneNamesCache, newKey, cacheEntry, &status);
            }
        }
        if (U_FAILURE(status)) {
            if (tznames != NULL) {
                delete tznames;
            }
            if (newKey != NULL) {
                uprv_free(newKey);
            }
            if (cacheEntry != NULL) {
                uprv_free(cacheEntry);
            }
            cacheEntry = NULL;
        }
    } else {
        // Update the reference count
        cacheEntry->refCount++;
        cacheEntry->lastAccess = (double)uprv_getUTCtime();
    }
    gAccessCount++;
    if (gAccessCount >= SWEEP_INTERVAL) {
        // sweep
        sweepCache();
        gAccessCount = 0;
    }
    fTZnamesCacheEntry = cacheEntry;
}