/// <summary> /// Sets a new start line in the given buffer and updates the LRU cache, if the buffer /// is present in the cache. The caller must have write lock for 'lruCacheDictLock'; /// </summary> /// <param name="logBuffer"></param> /// <param name="newLineNum"></param> private void SetNewStartLineForBuffer(LogBuffer logBuffer, int newLineNum) { Util.AssertTrue(_lruCacheDictLock.IsWriterLockHeld, "No writer lock for lru cache"); if (_lruCacheDict.ContainsKey(logBuffer.StartLine)) { _lruCacheDict.Remove(logBuffer.StartLine); logBuffer.StartLine = newLineNum; LogBufferCacheEntry cacheEntry = new LogBufferCacheEntry(); cacheEntry.LogBuffer = logBuffer; _lruCacheDict.Add(logBuffer.StartLine, cacheEntry); } else { logBuffer.StartLine = newLineNum; } }
private void UpdateLruCache(LogBuffer logBuffer) { LogBufferCacheEntry cacheEntry; _lruCacheDictLock.AcquireReaderLock(Timeout.Infinite); if (_lruCacheDict.TryGetValue(logBuffer.StartLine, out cacheEntry)) { cacheEntry.Touch(); } else { LockCookie cookie = _lruCacheDictLock.UpgradeToWriterLock(Timeout.Infinite); if (!_lruCacheDict.TryGetValue(logBuffer.StartLine, out cacheEntry)) // #536: re-test, because multiple threads may have been waiting for writer lock { cacheEntry = new LogBufferCacheEntry(); cacheEntry.LogBuffer = logBuffer; try { _lruCacheDict.Add(logBuffer.StartLine, cacheEntry); } catch (ArgumentException e) { #if DEBUG // there seems to be a bug with double added key Logger.logError(string.Format("Error in LRU cache: {0}", e.Message)); Logger.logInfo("Added buffer:"); DumpBufferInfos(logBuffer); LogBufferCacheEntry exisingEntry; if (_lruCacheDict.TryGetValue(logBuffer.StartLine, out exisingEntry)) { Logger.logInfo("Existing buffer: "); DumpBufferInfos(exisingEntry.LogBuffer); } else { Logger.logWarn("Ooops? Cannot find the already existing entry in LRU."); } #endif _lruCacheDictLock.ReleaseLock(); throw e; } } _lruCacheDictLock.DowngradeFromWriterLock(ref cookie); } _lruCacheDictLock.ReleaseReaderLock(); }