/// <summary>
        /// Creates a buffer of the specified length. Depending on the length, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
        /// </summary>
        /// <param name="chunkSource">The chunk pool.</param>
        /// <param name="minimumCapacity">The minimum capacity.</param>
        /// <returns>A buffer with at least the minimum capacity.</returns>
        public static IByteBuffer Create(IBsonChunkSource chunkSource, int minimumCapacity)
        {
            if (chunkSource == null)
            {
                throw new ArgumentNullException("chunkSource");
            }
            if (minimumCapacity <= 0)
            {
                throw new ArgumentOutOfRangeException("minimumCapacity");
            }

            var capacity = 0;
            var chunks   = new List <IBsonChunk>();

            while (capacity < minimumCapacity)
            {
                var chunk = chunkSource.GetChunk(minimumCapacity - capacity);
                chunks.Add(chunk);
                capacity += chunk.Bytes.Count;
            }

            if (chunks.Count == 1)
            {
                return(new SingleChunkBuffer(chunks[0], 0, isReadOnly: false));
            }
            else
            {
                return(new MultiChunkBuffer(chunks, 0, isReadOnly: false));
            }
        }
Exemplo n.º 2
0
        private void ExpandCapacity(int minimumCapacity)
        {
            if (_chunkSource == null)
            {
                throw new InvalidOperationException("Capacity cannot be expanded because this buffer was created without specifying a chunk source.");
            }

            while (_capacity < minimumCapacity)
            {
                var chunk = _chunkSource.GetChunk(minimumCapacity);
                _chunks.Add(chunk);
                _capacity += chunk.Bytes.Count;
                _positions.Add(_capacity);
            }
        }
Exemplo n.º 3
0
        private void ExpandCapacity(int minimumCapacity)
        {
            if (_chunkSource == null)
            {
                throw new InvalidOperationException("Capacity cannot be expanded because this buffer was created without specifying a chunk source.");
            }

            while (_capacity < minimumCapacity)
            {
                var chunk = _chunkSource.GetChunk(minimumCapacity);
                _chunks.Add(chunk);
                var newCapacity = (long)_capacity + (long)chunk.Bytes.Count;
                if (newCapacity > int.MaxValue)
                {
                    throw new InvalidOperationException("Capacity is limited to 2GB.");
                }
                _capacity = (int)newCapacity;
                _positions.Add(_capacity);
            }
        }
        /// <summary>
        /// Creates a buffer of the specified length. Depending on the length, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
        /// </summary>
        /// <param name="chunkSource">The chunk pool.</param>
        /// <param name="minimumCapacity">The minimum capacity.</param>
        /// <returns>A buffer with at least the minimum capacity.</returns>
        public static IByteBuffer Create(IBsonChunkSource chunkSource, int minimumCapacity)
        {
            if (chunkSource == null)
            {
                throw new ArgumentNullException("chunkSource");
            }
            if (minimumCapacity <= 0)
            {
                throw new ArgumentOutOfRangeException("minimumCapacity");
            }

            var capacity = 0;
            var chunks = new List<IBsonChunk>();
            while (capacity < minimumCapacity)
            {
                var chunk = chunkSource.GetChunk(minimumCapacity - capacity);
                chunks.Add(chunk);
                capacity += chunk.Bytes.Count;
            }

            if (chunks.Count == 1)
            {
                var chunk = chunks[0];

                ByteArrayChunk byteArrayChunk;
                if ((byteArrayChunk = chunk as ByteArrayChunk) != null)
                {
                    var segment = byteArrayChunk.Bytes;
                    if (segment.Offset == 0)
                    {
                        return new ByteArrayBuffer(segment.Array, segment.Count, isReadOnly: false);
                    }
                }

                return new SingleChunkBuffer(chunk, 0, isReadOnly: false);
            }
            else
            {
                return new MultiChunkBuffer(chunks, 0, isReadOnly: false);
            }
        }
Exemplo n.º 5
0
        /// <inheritdoc/>
        public IBsonChunk GetChunk(int requestedSize)
        {
            if (requestedSize <= 0)
            {
                throw new ArgumentOutOfRangeException("requestedSize");
            }
            ThrowIfDisposed();

            if (requestedSize <= _maxUnpooledChunkSize)
            {
                return(new ByteArrayChunk(requestedSize));
            }

            var powerOf2Size = PowerOf2.RoundUpToPowerOf2(requestedSize);

            if (powerOf2Size - requestedSize > _minChunkSize)
            {
                powerOf2Size = powerOf2Size / 2;
            }
            var chunkSize = Math.Max(Math.Min(powerOf2Size, _maxChunkSize), _minChunkSize);

            return(_baseSource.GetChunk(chunkSize));
        }
Exemplo n.º 6
0
        /// <inheritdoc/>
        public IBsonChunk GetChunk(int requestedSize)
        {
            if (requestedSize <= 0)
            {
                throw new ArgumentOutOfRangeException("requestedSize");
            }
            ThrowIfDisposed();

            IBsonChunk chunk;

            if (_previousChunkSize == 0 && _initialUnpooledChunkSize != 0)
            {
                chunk = new ByteArrayChunk(_initialUnpooledChunkSize);
            }
            else
            {
                var powerOf2Size = PowerOf2.RoundUpToPowerOf2(_previousChunkSize + 1);
                var chunkSize    = Math.Max(Math.Min(powerOf2Size, _maxChunkSize), _minChunkSize);
                chunk = _baseSource.GetChunk(chunkSize);
            }

            _previousChunkSize = chunk.Bytes.Count;
            return(chunk);
        }