// Gets value out of cache. // On entry. gCacheMutex must not be held. value must be NULL. status // must be U_ZERO_ERROR. // On exit. value and status set to what is in cache at key or on cache // miss the key's createObject() is called and value and status are set to // the result of that. In this latter case, best effort is made to add the // value and status to the cache. If createObject() fails to create a value, // gNoValue is stored in cache, and value is set to NULL. Caller must call // removeRef on value if non NULL. void UnifiedCache::_get( const CacheKeyBase &key, const SharedObject *&value, const void *creationContext, UErrorCode &status) const { U_ASSERT(value == NULL); U_ASSERT(status == U_ZERO_ERROR); if (_poll(key, value, status)) { if (value == gNoValue) { SharedObject::clearPtr(value); } return; } if (U_FAILURE(status)) { return; } value = key.createObject(creationContext, status); U_ASSERT(value == NULL || value->hasHardReferences()); U_ASSERT(value != NULL || status != U_ZERO_ERROR); if (value == NULL) { SharedObject::copyPtr(gNoValue, value); } _putIfAbsentAndGet(key, value, status); if (value == gNoValue) { SharedObject::clearPtr(value); } }
// Places a new value and creationStatus in the cache for the given key. // On entry, gCacheMutex must be held. key must not exist in the cache. // On exit, value and creation status placed under key. Soft reference added // to value on successful add. On error sets status. void UnifiedCache::_putNew( const CacheKeyBase &key, const SharedObject *value, const UErrorCode creationStatus, UErrorCode &status) const { if (U_FAILURE(status)) { return; } CacheKeyBase *keyToAdopt = key.clone(); if (keyToAdopt == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; } keyToAdopt->creationStatus = creationStatus; uhash_put(fHashtable, keyToAdopt, (void *) value, &status); if (U_SUCCESS(status)) { value->addSoftRef(); } }
void UnifiedCache::_putNew( const CacheKeyBase &key, const SharedObject *value, const UErrorCode creationStatus, UErrorCode &status) const { if (U_FAILURE(status)) { return; } CacheKeyBase *keyToAdopt = key.clone(); if (keyToAdopt == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; } keyToAdopt->fCreationStatus = creationStatus; if (value->softRefCount == 0) { _registerMaster(keyToAdopt, value); } void *oldValue = uhash_put(fHashtable, keyToAdopt, (void *) value, &status); U_ASSERT(oldValue == nullptr); (void)oldValue; if (U_SUCCESS(status)) { value->softRefCount++; } }