// Get data packer for this object, if we have cached data // AND the CRC matches. JC LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc) { llassert(mCacheLoaded); LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL); if (entry) { // we've seen this object before if (entry->getCRC() == crc) { // Record a hit entry->recordHit(); return entry->getDP(crc); } else { // llinfos << "CRC miss for " << local_id << llendl; mCacheMissCRC.put(local_id); } } else { // llinfos << "Cache miss for " << local_id << llendl; mCacheMissFull.put(local_id); } return NULL; }
// Get data packer for this object, if we have cached data // AND the CRC matches. JC LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); if (entry) { // we've seen this object before if (entry->getCRC() == crc) { // Record a hit entry->recordHit(); cache_miss_type = CACHE_MISS_TYPE_NONE; return entry->getDP(crc); } else { // llinfos << "CRC miss for " << local_id << llendl; cache_miss_type = CACHE_MISS_TYPE_CRC; mCacheMissCRC.put(local_id); } } else { // llinfos << "Cache miss for " << local_id << llendl; cache_miss_type = CACHE_MISS_TYPE_FULL; mCacheMissFull.put(local_id); } return NULL; }
void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) { llassert_always(mInitialized); handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; if(iter == mHandleEntryMap.end()) //no cache { return ; } std::string filename; getObjectCacheFilename(handle, filename); LLAPRFile* apr_file = new LLAPRFile(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); LLUUID cache_id ; if(!checkRead(apr_file, cache_id.mData, UUID_BYTES)) { return ; } if(cache_id != id) { llinfos << "Cache ID doesn't match for this region, discarding"<< llendl; delete apr_file ; return ; } S32 num_entries; if(!checkRead(apr_file, &num_entries, sizeof(S32))) { return ; } for (S32 i = 0; i < num_entries; i++) { LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file); if (!entry->getLocalID()) { llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; delete entry ; break; } cache_entry_map[entry->getLocalID()] = entry; } num_entries = cache_entry_map.size() ; delete apr_file ; return ; }
LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) { U32 local_id = objectp->getLocalID(); U32 crc = objectp->getCRC(); LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); if (entry) { // we've seen this object before if (entry->getCRC() == crc) { // Record a hit entry->recordDupe(); return CACHE_UPDATE_DUPE; } // Update the cache entry mImpl->mCacheMap.erase(local_id); delete entry; entry = new LLVOCacheEntry(local_id, crc, dp); mImpl->mCacheMap[local_id] = entry; return CACHE_UPDATE_CHANGED; } // we haven't seen this object before // Create new entry and add to map eCacheUpdateResult result = CACHE_UPDATE_ADDED; if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) { delete mImpl->mCacheMap.begin()->second ; mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); result = CACHE_UPDATE_REPLACED; } entry = new LLVOCacheEntry(local_id, crc, dp); mImpl->mCacheMap[local_id] = entry; return result; }
void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) { U32 local_id = objectp->getLocalID(); U32 crc = objectp->getCRC(); LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL); if (entry) { // we've seen this object before if (entry->getCRC() == crc) { // Record a hit entry->recordDupe(); } else { // Update the cache entry mCacheMap.erase(local_id); delete entry; entry = new LLVOCacheEntry(local_id, crc, dp); mCacheMap[local_id] = entry; } } else { // we haven't seen this object before // Create new entry and add to map if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) { mCacheMap.erase(mCacheMap.begin()); } entry = new LLVOCacheEntry(local_id, crc, dp); mCacheMap[local_id] = entry; } return ; }
void LLViewerRegion::dumpCache() { const S32 BINS = 4; S32 hit_bin[BINS]; S32 change_bin[BINS]; S32 i; for (i = 0; i < BINS; ++i) { hit_bin[i] = 0; change_bin[i] = 0; } LLVOCacheEntry *entry; for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter) { entry = iter->second ; S32 hits = entry->getHitCount(); S32 changes = entry->getCRCChangeCount(); hits = llclamp(hits, 0, BINS-1); changes = llclamp(changes, 0, BINS-1); hit_bin[hits]++; change_bin[changes]++; } llinfos << "Count " << mCacheMap.size() << llendl; for (i = 0; i < BINS; i++) { llinfos << "Hits " << i << " " << hit_bin[i] << llendl; } for (i = 0; i < BINS; i++) { llinfos << "Changes " << i << " " << change_bin[i] << llendl; } }
void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) { if(!mEnabled) { llwarns << "Not reading cache for handle " << handle << "): Cache is currently disabled." << llendl; return ; } llassert_always(mInitialized); handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; if(iter == mHandleEntryMap.end()) //no cache { llwarns << "No handle map entry for " << handle << llendl; return ; } bool success = true ; { std::string filename; getObjectCacheFilename(handle, filename); LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); LLUUID cache_id ; success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ; if(success) { if(cache_id != id) { llinfos << "Cache ID doesn't match for this region, discarding"<< llendl; success = false ; } if(success) { S32 num_entries; success = check_read(&apr_file, &num_entries, sizeof(S32)) ; for (S32 i = 0; success && i < num_entries; i++) { LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file); if (!entry->getLocalID()) { llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; delete entry ; success = false ; } cache_entry_map[entry->getLocalID()] = entry; } } } } if(!success) { if(cache_entry_map.empty()) { removeEntry(iter->second) ; } } return ; }