/// <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)); } }
/// <summary> /// Creates a buffer of the specified length. Depending on the length, either a SingleChunkBuffer or a MultiChunkBuffer will be created. /// </summary> /// <param name="chunkPool">The chunk pool.</param> /// <param name="length">The length.</param> /// <returns>A buffer.</returns> public static IByteBuffer Create(BsonChunkPool chunkPool, int length) { if (chunkPool == null) { throw new ArgumentNullException("pool"); } if (length <= 0) { throw new ArgumentOutOfRangeException("length"); } if (length < chunkPool.ChunkSize) { var chunk = chunkPool.AcquireChunk(); return new SingleChunkBuffer(chunk, 0, length, false); } else { var chunksNeeded = ((length - 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, length, false); } }
public void ChunkSize_get_should_return_expected_result() { var subject = new BsonChunkPool(1, 16); var result = subject.ChunkSize; result.Should().Be(16); }
public void Create_should_return_expected_result( [Values(1, 63, 64, 65, 128)] int minimumCapacity) { var chunkSource = new BsonChunkPool(1, 64); var result = ByteBufferFactory.Create(chunkSource, minimumCapacity); result.Capacity.Should().BeGreaterOrEqualTo(minimumCapacity); }
public void Create_should_return_MultiChunkBuffer_when_multiple_chunks_are_required( [Values(65, 128)] int minimumCapacity) { var chunkSource = new BsonChunkPool(1, 64); var result = ByteBufferFactory.Create(chunkSource, minimumCapacity); result.Should().BeOfType<MultiChunkBuffer>(); }
public void Create_should_return_SingleChunkBuffer_when_a_single_chunk_is_sufficient( [Values(1, 63, 64)] int minimumCapacity) { var chunkSource = new BsonChunkPool(1, 64); var result = ByteBufferFactory.Create(chunkSource, minimumCapacity); result.Should().BeOfType<SingleChunkBuffer>(); }
public void constructor_should_initialize_subject() { var maxChunkCount = 1; var chunkSize = 16; var subject = new BsonChunkPool(maxChunkCount, chunkSize); var reflector = new Reflector(subject); subject.MaxChunkCount.Should().Be(maxChunkCount); subject.ChunkSize.Should().Be(chunkSize); reflector._disposed.Should().BeFalse(); }
// 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; _origin = 0; _length = 0; }
// 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; _origin = 0; _length = 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; }
// 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(); } }
/// <summary> /// Initializes a new instance of the <see cref="MultiChunkBuffer"/> class. /// </summary> /// <param name="chunks">The chunks.</param> /// <param name="origin">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 origin, 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; if (_chunks.Any(c => c.Bytes.Length != _chunkSize)) { throw new ArgumentException("The chunks are not all the same size."); } _capacity = _chunks.Count * _chunkSize; if (origin < 0 || origin > _capacity) { throw new ArgumentOutOfRangeException("origin"); } _origin = origin; if (length < 0 || _origin + length > _capacity) { throw new ArgumentOutOfRangeException("length"); } _length = length; _chunkPool = null; _isReadOnly = isReadOnly; foreach (var chunk in _chunks) { chunk.IncrementReferenceCount(); } }
public void GetChunk_should_return_expected_result( [Values(1, 15, 16, 17, 32)] int requestedSize) { var subject = new BsonChunkPool(1, 16); var result = subject.GetChunk(requestedSize); result.Bytes.Count.Should().Be(16); }
public ReferenceCountedChunk(byte[] chunk, BsonChunkPool pool) { _chunk = chunk; _pool = pool; }
/// <summary> /// Initializes a new instance of the <see cref="MultiChunkBuffer"/> class. /// </summary> /// <param name="chunks">The chunks.</param> /// <param name="origin">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 origin, 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; if (_chunks.Any(c => c.Bytes.Length != _chunkSize)) { throw new ArgumentException("The chunks are not all the same size."); } _capacity = _chunks.Count * _chunkSize; if (origin < 0 || origin > _capacity) { throw new ArgumentOutOfRangeException("origin"); } _origin = origin; if (length < 0 || _origin + length > _capacity) { throw new ArgumentOutOfRangeException("length"); } _length = length; _chunkPool = null; _isReadOnly = isReadOnly; foreach (var chunk in _chunks) { chunk.IncrementReferenceCount(); } }
public void GetChunk_should_return_pooled_chunk_when_one_is_availabe() { var subject = new BsonChunkPool(1, 16); var pooledChunk = subject.GetChunk(1); var expectedArray = pooledChunk.Bytes.Array; var expectedOffset = pooledChunk.Bytes.Offset; pooledChunk.Dispose(); var result = subject.GetChunk(1); result.Bytes.Array.Should().BeSameAs(expectedArray); result.Bytes.Offset.Should().Be(expectedOffset); result.Bytes.Count.Should().Be(16); }
public void Dispose_should_dispose_subject() { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); subject.Dispose(); var reflector = new Reflector(subject); reflector._disposed.Should().BeTrue(); }
public void Default_set_should_have_expected_effect() { var originalDefaultPool = BsonChunkPool.Default; try { var newDefaultPool = new BsonChunkPool(1, 16); BsonChunkPool.Default = newDefaultPool; BsonChunkPool.Default.Should().BeSameAs(newDefaultPool); } finally { BsonChunkPool.Default = originalDefaultPool; } }
public void MaxChunkCount_get_should_return_expected_result() { var subject = new BsonChunkPool(1, 16); var result = subject.MaxChunkCount; result.Should().Be(1); }
public Reflector(BsonChunkPool instance) { _instance = instance; }
public void Fork_should_throw_when_subject_is_disposed() { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); subject.Dispose(); Action action = () => subject.Fork(); action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("DisposableChunk"); }
/// <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(); } }
public void Bytes_get_should_return_expected_result() { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); var result = subject.Bytes; result.Array.Length.Should().Be(16); result.Offset.Should().Be(0); result.Count.Should().Be(16); }
public void Dispose_should_return_chunk_to_the_pool() { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); subject.Dispose(); pool.ChunkCount.Should().Be(1); }
public void GetChunk_should_throw_when_subject_is_disposed() { var subject = new BsonChunkPool(1, 16); subject.Dispose(); Action action = () => subject.GetChunk(1); action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("BsonChunkPool"); }
public void Dispose_should_return_chunk_to_the_pool_after_all_handles_have_been_disposed( [Values(0, 1, 2, 3, 4, 16)] int numberOfHandles, [Values(false, true)] bool disposeSubjectLast) { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); var handles = new List<IBsonChunk>(); for (var n = 0; n < numberOfHandles; n++) { handles.Add(subject.Fork()); } if (disposeSubjectLast) { handles.Add(subject); } else { handles.Insert(0, subject); } foreach (var handle in handles) { pool.ChunkCount.Should().Be(0); handle.Dispose(); } pool.ChunkCount.Should().Be(1); }
public void Dispose_can_be_called_more_than_once() { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); subject.Dispose(); subject.Dispose(); }
public void Fork_should_return_expected_result() { var pool = new BsonChunkPool(1, 16); var subject = pool.GetChunk(1); var handle = subject.Fork(); handle.Bytes.Array.Should().BeSameAs(subject.Bytes.Array); handle.Bytes.Offset.Should().Be(subject.Bytes.Offset); handle.Bytes.Count.Should().Be(subject.Bytes.Count); }