/// <summary> /// 根据百分比创建缓存存根 /// </summary> /// <param name="offset">内存段的偏移量</param> /// <param name="size">片段大小</param> /// <param name="percent">百分比</param> private ConcurrentStack <ISegmentCacheStub> CreateStub(ref int offset, int size, float percent) { int percentSize = (int)(Capacity * percent) + _lastSize; int cacheCount = percentSize / size; _lastSize = percentSize - (size * cacheCount); ConcurrentStack <ISegmentCacheStub> stack = new ConcurrentStack <ISegmentCacheStub>(); for (int i = 0; i < cacheCount; i++) { ISegmentCacheStub stub = new SegmentCacheStub(new CacheIndexer { CacheBuffer = _data, BeginOffset = offset, SegmentSize = size }); stack.Push(stub); offset += size; } return(stack); }
/// <summary> /// 获取指定大小缓存所需要的内存片段数量 /// </summary> /// <param name="size">缓存大小</param> /// <returns>返回所需要的缓存数量</returns> private List <ISegmentCacheStub> GetStubs(int size) { int count; int lastSize; int currentLevel; List <ISegmentCacheStub> result = new List <ISegmentCacheStub>(); try { int subSize; for (int i = 0; i < _levels.Length; i++) { currentLevel = _levels[i]; //优先选择靠近当前等级的分块 if ((subSize = currentLevel - size) >= 0 && subSize <= _lastLevelSize) { ISegmentCacheStub segmentCacheStub; if (!_pools[currentLevel].TryPop(out segmentCacheStub)) { continue; } result.Add(segmentCacheStub); return(result); } if (size > currentLevel) { count = size / currentLevel; lastSize = size - (currentLevel * count); ISegmentCacheStub[] stubs; ConcurrentStack <ISegmentCacheStub> stubStack = _pools[currentLevel]; //条件满足 if (stubStack.IsEmpty && i == _levels.Length - 1) { return(null); } stubs = new SegmentCacheStub[count]; if (stubStack.TryPopRange(stubs, 0, count) != count) { //giveback now. Giveback(stubs); continue; } result.AddRange(stubs); List <ISegmentCacheStub> temp = GetStubs(lastSize); if (temp == null) { GivebackRang(result.ToArray()); return(null); } result.AddRange(temp); return(result); } } ISegmentCacheStub stub; if (!_pools[_levels[_levels.Length - 1]].TryPop(out stub)) { return(null); } //小于所有的 result.Add(stub); return(result); } catch (OutOfMemoryException ex) { GivebackRang(result.ToArray()); _tracing.Error(ex, null); return(null); } catch (Exception ex) { _tracing.Error(ex, null); throw; } }