Пример #1
0
        /// <summary>
        /// Not allowed to set data larger than the buffer size
        /// </summary>
        public void Put(T[] dataToSet)
        {
            var sourceDataLength = dataToSet.Length;

            if (sourceDataLength > _capacity)
            {
                throw new ArgumentException("Amount of data that is trying to be set is larger than the capacity of this buffer");
            }

            bool isOverflowed;
            int  nextTail;

            lock (_lockObj)
            {
                // Calculate the amount of data (including the data being read at the moment, if a read is ongoing)
                var capacityInUse = BufferLogicHelper.CalculateUsedCapacity(_isEmpty, _head, _tail, _capacity);
                if (BufferLogicHelper.WillDataBeOverwritten(sourceDataLength, capacityInUse, _capacity))
                {
                    // We just throw away a chunk if there is no room
                    LostData += sourceDataLength;
                }

                // Calculate the next tail, this way we also know whether we are overflowing
                nextTail = BufferLogicHelper.CalculateNextIndex(_tail, sourceDataLength, _capacity, out isOverflowed);
            }

            if (isOverflowed)
            {
                // Data spans across the end and beginning of the storage array, we need to do two copies
                var itemsToWriteAtEnd = _capacity - _tail;
                Array.Copy(dataToSet, 0, _storage, _tail, itemsToWriteAtEnd);

                var itemsToWriteAtBeginning = sourceDataLength - itemsToWriteAtEnd;
                Array.Copy(dataToSet, itemsToWriteAtEnd, _storage, 0, itemsToWriteAtBeginning);
            }
            else
            {
                Array.Copy(dataToSet, 0, _storage, _tail, sourceDataLength);
            }

            lock (_lockObj)
            {
                _tail = nextTail;

                // We just added data, the storage can never be empty now
                _isEmpty = false;

                // Check if we need to set the event
                if (_notifyEventEnabled && !_notifyEvent.IsSet && BufferLogicHelper.CalculateUsedCapacity(_isEmpty, _head, _tail, _capacity) >= _notifyThreshold)
                {
                    // There is not enough data anymore, reset the event
                    _notifyEvent.Set();
                }
            }
        }
 public void Test_WillDataBeOverwritten()
 {
     Assert.IsFalse(BufferLogicHelper.WillDataBeOverwritten(10, 0, 10));
     Assert.IsTrue(BufferLogicHelper.WillDataBeOverwritten(5, 6, 10));
     Assert.IsFalse(BufferLogicHelper.WillDataBeOverwritten(5, 5, 10));
 }