Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        /// <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;
            }
        }