c#环形缓冲区

    public class CircularBuffer<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
    {
        private int capacity;
        volatile private int size;
        volatile private int head;//头,指示读数据位置
        volatile private int tail;//尾,指示写数据位置
        volatile private T[] buffer;//内部数据

        [NonSerialized()] 
        private object _syncRoot = new object();

        public CircularBuffer(int capacity)
            : this(capacity, false)
        {
        }

        public CircularBuffer(int capacity, bool allowOverflow)
        {
            if (capacity < 0)
                throw new ArgumentException("Capacity set to " + capacity, "capacity");

            this.capacity = capacity;
            size = 0;
            head = 0;
            tail = 0;
            buffer = new T[capacity];
            AllowOverflow = allowOverflow;
        }
        public bool AllowOverflow//缓冲器满了以后是否允许溢出,即进行覆盖
        {
            get;
            set;
        }

        public int Capacity//获取或设置缓冲区大小
        {
            get { return capacity; }
            set
            {
                if (value == capacity)
                    return;

                if (value < size)
                    throw new ArgumentOutOfRangeException("value", "Capacity to small");

                var dst = new T[value];
                if (size > 0)
                    CopyTo(dst);
                buffer = dst;

                capacity = value;
            }
        }

        public int Size
        {
            get { return size; }
        }

        public bool Contains(T item)
        {
            int bufferIndex = head;
            var comparer = EqualityComparer<T>.Default;
            for (int i = 0; i < size; i++, bufferIndex++)
            {
                if (bufferIndex == capacity)
                    bufferIndex = 0;

                if (item == null && buffer[bufferIndex] == null)
                    return true;
                else if ((buffer[bufferIndex] != null) &&
                    comparer.Equals(buffer[bufferIndex], item))
                    return true;
            }

            return false;
        }

        public void Clear()
        {
            size = 0;
            head = 0;
            tail = 0;
        }

        public int Put(T[] src)
        {
            return Put(src, 0, src.Length);
        }

        public int Put(T[] src, int offset, int count)//写入数据,如果缓冲区不足且 AllowOverflow为false,则抛出异常
        {
            lock (_syncRoot)
            {
                if (!AllowOverflow &&  count > capacity - size)
                    throw new InvalidOperationException("Buffer Overflow");

                int srcIndex = offset;
                for (int i = 0; i < count; i++, tail++, srcIndex++)
                {
                    if (tail == capacity)
                        tail = 0;
                    buffer[tail] = src[srcIndex];
                }
                size = Math.Min(size + count, capacity);
                return count;
            }
        }

        public void Put(T item)
        {
            lock (_syncRoot)
            {
                if (!AllowOverflow && size == capacity)
                    throw new InvalidOperationException("Buffer Overflow");

                buffer[tail] = item;
                if (++tail == capacity)
                    tail = 0;
                size++;
            }
        }

        public void Skip(int count)
        {
            lock (_syncRoot)
            {
                head += count;
                if (head >= capacity)
                    head -= capacity;
            }
        }

        public T[] Get(int count)
        {
            var dst = new T[count];
            Get(dst);
            return dst;
        }

        public int Get(T[] dst)
        {
            return Get(dst, 0, dst.Length);
        }

        public int Get(T[] dst, int offset, int count)//读取数据,如果缓冲区的数据少于要读取的数量,则只读取剩余的数量
        {
            lock (_syncRoot)
            {
                int realCount = Math.Min(count, size);
                int dstIndex = offset;
                for (int i = 0; i < realCount; i++, head++, dstIndex++)
                {
                    if (head == capacity)
                        head = 0;
                    dst[dstIndex] = buffer[head];
                }
                size -= realCount;
                return realCount;
            }
        }

        public T Get()
        {
            lock (_syncRoot)
            {
                if (size == 0)
                    throw new InvalidOperationException("Buffer Empty");
                
                var item = buffer[head];
                if (++head == capacity)
                    head = 0;
                size--;
                return item;
            }
        }

        public void CopyTo(T[] array)
        {
            CopyTo(array, 0);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            CopyTo(0, array, arrayIndex, size);
        }

        public void CopyTo(int index, T[] array, int arrayIndex, int count)//拷贝缓冲区的数据到指定数组的指定位置,如果缓冲区的数量不足,则抛出异常
        {
            if (count > size)
                throw new ArgumentOutOfRangeException("count", "Read size to large");

            int bufferIndex = head;
            for (int i = 0; i < count; i++, bufferIndex++, arrayIndex++)
            {
                if (bufferIndex == capacity)
                    bufferIndex = 0;
                array[arrayIndex] = buffer[bufferIndex];
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            int bufferIndex = head;
            for (int i = 0; i < size; i++, bufferIndex++)
            {
                if (bufferIndex == capacity)
                    bufferIndex = 0;

                yield return buffer[bufferIndex];
            }
        }

        public T[] GetBuffer()
        {
            return buffer;
        }

        public T[] ToArray()
        {
            var dst = new T[size];
            CopyTo(dst);
            return dst;
        }

        #region ICollection<T> Members

        int ICollection<T>.Count
        {
            get { return Size; }
        }

        bool ICollection<T>.IsReadOnly
        {
            get { return false; }
        }

        void ICollection<T>.Add(T item)
        {
            Put(item);
        }

        bool ICollection<T>.Remove(T item)
        {
            if (size == 0)
                return false;

            Get();
            return true;
        }

        #endregion

        #region IEnumerable<T> Members

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        #region ICollection Members

        int ICollection.Count
        {
            get { return Size; }
        }

        bool ICollection.IsSynchronized
        {
            get { return false; }
        }

        object ICollection.SyncRoot
        {
            get
            {
                if (_syncRoot == null)
                    Interlocked.CompareExchange(ref _syncRoot, new object(), null);
                return _syncRoot;
            }
        }

        void ICollection.CopyTo(Array array, int arrayIndex)
        {
            CopyTo((T[])array, arrayIndex);
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        #endregion
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值