// ---------------------------------------------------------------------------- // method: removeNARoutine // // The method is called when DDL is performed against a routine making its // definition incorrect. // It has a side affect of generating query invalidation keys that are // propagate to all the other processes that could have the routine stored // in cache. // ---------------------------------------------------------------------------- void NARoutineDB::removeNARoutine2(QualifiedName &routineName, ComQiScope qiScope, Int64 objUID) { NAHashDictionaryIterator<NARoutineDBKey,NARoutine> iter (*this); NARoutineDBKey *key = NULL; NARoutine *cachedNARoutine = NULL; NASet<Int64> objectUIDs(CmpCommon::statementHeap(), 1); // If there are no items in cache, skip if (entries() > 0) { NASet<Int64> objectUIDs(CmpCommon::statementHeap(), 1); // iterate over all entries and remove the ones that match the name iter.reset(); iter.getNext(key,cachedNARoutine); while(key && cachedNARoutine) { if (cachedNARoutine->getSqlName() == routineName) { objectUIDs.insert(cachedNARoutine->getRoutineID()); moveRoutineToDeleteList(cachedNARoutine,key); } iter.getNext(key,cachedNARoutine); } } // clear out the other users' caches too. if (qiScope == REMOVE_FROM_ALL_USERS) { // There are some scenarios where the affected object does not have an // NARoutine cache entry. However, other processes may have this routine // in their caches. Go ahead and create an invalidation key if (0 == objectUIDs.entries()) objectUIDs.insert(objUID); Int32 numKeys = objectUIDs.entries(); SQL_QIKEY qiKeys[numKeys]; for (CollIndex i = 0; i < numKeys; i++) { qiKeys[i].ddlObjectUID = objectUIDs[i]; qiKeys[i].operation[0] = 'O'; qiKeys[i].operation[1] = 'R'; } long retcode = SQL_EXEC_SetSecInvalidKeys(numKeys, qiKeys); } }
// NARoutineDB private member functions. // ====================================== // Check if cache size is within maximum allowed cache size. If not, // then remove entries in the cache based on the replacement policy, // until the cache size drops below the allowed size. // DO NOT CALL THIS ROUTINE IN THE MIDDLE OF A STATEMENT. NABoolean NARoutineDB::enforceMemorySpaceConstraints() { NABoolean retval = TRUE; // Set cache size to CQD setting. maxCacheSize_ = CmpCommon::getDefaultLong(ROUTINE_CACHE_SIZE) * 1024 * 1024; // Check if cache size is within memory constraints if (currentCacheSize_ <= maxCacheSize_) return retval; // Need to reduce cache size // Loop through the list and attempt to remove the entries // that are least recently used (that is, that have the oldest // timestamps of when they were last used). Do not allow the // number of times looped to exceed the number of entries in // cache. Lng32 loopCnt = 0, entries = this->entries(); while (currentCacheSize_ > maxCacheSize_ && loopCnt++ < entries){ // Find least recently used NARoutine in cache. NAHashDictionaryIterator<NARoutineDBKey,NARoutine> iter (*this); NARoutineDBKey *key=0, *oldestKey=0; NARoutine *routine=0, *oldestRoutine=0; Int64 oldestTime; iter.reset(); iter.getNext(key,routine); if (key && routine) // This should always be true. { oldestTime = routine->getLastUsedTime(); while(key) { // Check routine for last used time. Save oldest. Must use // '<=' so that oldestKey will get set first time through loop. if (routine && routine->getLastUsedTime() <= oldestTime) { oldestTime = routine->getLastUsedTime(); oldestKey = key; oldestRoutine = routine; } iter.getNext(key, routine); } remove(oldestKey); currentCacheSize_ -= oldestRoutine->getSize(); if (entries_>0) entries_--; delete oldestRoutine; } if ((ULng32) oldestRoutine->getSize() <= currentCacheSize_) { currentCacheSize_ -= oldestRoutine->getSize(); if (entries_>0) entries_--; } else { currentCacheSize_ = 0; entries_ = 0; } } //return true indicating cache size is below maximum memory allowance. if (currentCacheSize_ > maxCacheSize_) retval = FALSE; return retval; }