/// <summary>
        /// Creates a buffer of the specified fixed capacity. Depending on the required capacity, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
        /// </summary>
        /// <param name="chunkPool">The chunk pool.</param>
        /// <param name="fixedCapacity">The required capacity.</param>
        /// <returns>A buffer.</returns>
        public static IByteBuffer Create(BsonChunkPool chunkPool, int fixedCapacity)
        {
            if (chunkPool == null)
            {
                throw new ArgumentNullException("pool");
            }
            if (fixedCapacity <= 0)
            {
                throw new ArgumentOutOfRangeException("capacity");
            }

            if (fixedCapacity < chunkPool.ChunkSize)
            {
                var chunk = chunkPool.AcquireChunk();
                return new SingleChunkBuffer(chunk, 0, 0, false);
            }
            else
            {
                var chunksNeeded = ((fixedCapacity - 1) / chunkPool.ChunkSize) + 1;
                var chunks = new List<BsonChunk>(chunksNeeded);
                for (int i = 0; i < chunksNeeded; i++)
                {
                    chunks.Add(chunkPool.AcquireChunk());
                }
                return new MultiChunkBuffer(chunks, 0, 0, false);
            }
        }
예제 #2
0
        /// <summary>
        /// Creates a buffer of the specified fixed capacity. Depending on the required capacity, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
        /// </summary>
        /// <param name="chunkPool">The chunk pool.</param>
        /// <param name="fixedCapacity">The required capacity.</param>
        /// <returns>A buffer.</returns>
        public static IByteBuffer Create(BsonChunkPool chunkPool, int fixedCapacity)
        {
            if (chunkPool == null)
            {
                throw new ArgumentNullException("pool");
            }
            if (fixedCapacity <= 0)
            {
                throw new ArgumentOutOfRangeException("capacity");
            }

            if (fixedCapacity < chunkPool.ChunkSize)
            {
                var chunk = chunkPool.AcquireChunk();
                return(new SingleChunkBuffer(chunk, 0, 0, false));
            }
            else
            {
                var chunksNeeded = ((fixedCapacity - 1) / chunkPool.ChunkSize) + 1;
                var chunks       = new List <BsonChunk>(chunksNeeded);
                for (int i = 0; i < chunksNeeded; i++)
                {
                    chunks.Add(chunkPool.AcquireChunk());
                }
                return(new MultiChunkBuffer(chunks, 0, 0, false));
            }
        }
예제 #3
0
        // constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="BsonChunk"/> class.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <param name="chunkPool">The chunk pool.</param>
        /// <exception cref="System.ArgumentNullException">
        /// bytes
        /// or
        /// pool
        /// </exception>
        public BsonChunk(byte[] bytes, BsonChunkPool chunkPool)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }
            if (chunkPool == null)
            {
                throw new ArgumentNullException("chunkPool");
            }

            _bytes     = bytes;
            _chunkPool = chunkPool;
        }
예제 #4
0
        // constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="BsonChunk"/> class.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <param name="chunkPool">The chunk pool.</param>
        /// <exception cref="System.ArgumentNullException">
        /// bytes
        /// or
        /// pool
        /// </exception>
        public BsonChunk(byte[] bytes, BsonChunkPool chunkPool)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }
            if (chunkPool == null)
            {
                throw new ArgumentNullException("chunkPool");
            }

            _bytes = bytes;
            _chunkPool = chunkPool;
        }
        // constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="MultiChunkBuffer"/> class.
        /// </summary>
        /// <param name="chunkPool">The chunk pool.</param>
        /// <exception cref="System.ArgumentNullException">chunkPool</exception>
        public MultiChunkBuffer(BsonChunkPool chunkPool)
        {
            if (chunkPool == null)
            {
                throw new ArgumentNullException("chunkPool");
            }

            _chunkPool   = chunkPool;
            _chunks      = new List <BsonChunk>();
            _chunkSize   = chunkPool.ChunkSize;
            _sliceOffset = 0;

            _capacity = 0; // EnsureSpaceAvailable will add capacity as needed
            _length   = 0;
            _position = 0;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MultiChunkBuffer"/> class.
        /// </summary>
        /// <param name="chunks">The chunks.</param>
        /// <param name="sliceOffset">The slice offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="isReadOnly">Whether the buffer is read only.</param>
        /// <exception cref="System.ArgumentNullException">chunks</exception>
        internal MultiChunkBuffer(IEnumerable <BsonChunk> chunks, int sliceOffset, int length, bool isReadOnly)
        {
            if (chunks == null)
            {
                throw new ArgumentNullException("chunks");
            }

            _chunks = new List <BsonChunk>(chunks);
            if (_chunks.Count == 0)
            {
                throw new ArgumentException("No chunks where provided.", "chunks");
            }

            _chunkSize = _chunks[0].Bytes.Length;
            foreach (var chunk in _chunks)
            {
                if (chunk.Bytes.Length != _chunkSize)
                {
                    throw new ArgumentException("The chunks are not all the same size.");
                }
            }

            if (sliceOffset < 0)
            {
                throw new ArgumentOutOfRangeException("sliceOffset");
            }
            _sliceOffset = sliceOffset;

            var maxCapacity = _chunks.Count * _chunkSize - _sliceOffset;

            if (length < 0 || length > maxCapacity)
            {
                throw new ArgumentOutOfRangeException("length");
            }
            _capacity = isReadOnly ? length : maxCapacity;  // the capacity is fixed
            _length   = length;

            _chunkPool  = null;
            _isReadOnly = isReadOnly;
            _position   = 0;

            foreach (var chunk in _chunks)
            {
                chunk.IncrementReferenceCount();
            }
        }