Skip to content

Commit 667bec5

Browse files
benmwatsonBen Watson
andauthored
Release 2.2.0: Update version and documentation (#207)
* Update documentation and version * Re-generated using latest xmldocmd (2.7.0) Co-authored-by: Ben Watson <[email protected]>
1 parent 36b471a commit 667bec5

File tree

111 files changed

+526
-409
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+526
-409
lines changed

CHANGES.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
# Version 2.2.0
2+
3+
API changes:
4+
* Add an override for `GetStream` that takes a `ReadOnlySpan<byte>`. This supercedes the versions of `GetStream` that take `Memory<byte>`, which were marked as `[Obsolete]`.
5+
6+
Bug Fixes:
7+
* Fixed: `GetReadOnlySequence()` throws `ArgumentOutOfRangeException`
8+
9+
Performance Improvements:
10+
* Removed enumerator allocation when returning blocks to the pool.
11+
* Changed default size of stream's block list to 0 because `EnsureCapacity` will always run, potentially resizing the list anyway.
12+
* Removed unneeded closure allocation when copying buffers.
13+
* Use `GC.AllocateUninitializedArray` in an additional spot, for better performance in .NET 5+.
14+
15+
Documentation:
16+
* Improved documentation, standardized puncutation, fixed code formatting.
17+
18+
# Version 2.1.3
19+
20+
Bug Fixes:
21+
* Fixed another integer overflow error when returning buffers to the pool.
22+
23+
# Version 2.1.2
24+
25+
Bug Fixes:
26+
* Added `[SecurityRules(SecurityRuyleSet.Level1)]` to assembly to allow more relaxed inheritance security rules.
27+
* Fixed an integer overflow when calculating large buffer sizes.
28+
129
# Version 2.1.0
230

331
* Added `RecyclableMemoryStreamManager` constructor overloads that take parameters for specifying the maximum free pool sizes. Updated IntelliSense documentation to make clear that these values need to be explciitly set to avoid unbounded pool growth.

docs/Microsoft.IO.RecyclableMemoryStream.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
| public type | description |
66
| --- | --- |
7-
| class [RecyclableMemoryStream](Microsoft.IO/RecyclableMemoryStream.md) | MemoryStream implementation that deals with pooling and managing memory streams which use potentially large buffers. |
8-
| class [RecyclableMemoryStreamManager](Microsoft.IO/RecyclableMemoryStreamManager.md) | Manages pools of [`RecyclableMemoryStream`](Microsoft.IO/RecyclableMemoryStream.md) objects. |
7+
| class [RecyclableMemoryStream](./Microsoft.IO/RecyclableMemoryStream.md) | MemoryStream implementation that deals with pooling and managing memory streams which use potentially large buffers. |
8+
| class [RecyclableMemoryStreamManager](./Microsoft.IO/RecyclableMemoryStreamManager.md) | Manages pools of [`RecyclableMemoryStream`](./Microsoft.IO/RecyclableMemoryStream.md) objects. |
99

1010
<!-- DO NOT EDIT: generated by xmldocmd for Microsoft.IO.RecyclableMemoryStream.dll -->

docs/Microsoft.IO/RecyclableMemoryStream.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,32 @@ public sealed class RecyclableMemoryStream : MemoryStream, IBufferWriter<byte>
1010

1111
| name | description |
1212
| --- | --- |
13-
| [RecyclableMemoryStream](RecyclableMemoryStream/RecyclableMemoryStream.md)(…) | Allocate a new RecyclableMemoryStream object. (8 constructors) |
14-
| override [CanRead](RecyclableMemoryStream/CanRead.md) { get; } | Whether the stream can currently read |
15-
| override [CanSeek](RecyclableMemoryStream/CanSeek.md) { get; } | Whether the stream can currently seek |
16-
| override [CanTimeout](RecyclableMemoryStream/CanTimeout.md) { get; } | Always false |
17-
| override [CanWrite](RecyclableMemoryStream/CanWrite.md) { get; } | Whether the stream can currently write |
18-
| override [Capacity](RecyclableMemoryStream/Capacity.md) { getset; } | Gets or sets the capacity |
13+
| [RecyclableMemoryStream](RecyclableMemoryStream/RecyclableMemoryStream.md)(…) | Initializes a new instance of the [`RecyclableMemoryStream`](./RecyclableMemoryStream.md) class. (8 constructors) |
14+
| override [CanRead](RecyclableMemoryStream/CanRead.md) { get; } | Whether the stream can currently read. |
15+
| override [CanSeek](RecyclableMemoryStream/CanSeek.md) { get; } | Whether the stream can currently seek. |
16+
| override [CanTimeout](RecyclableMemoryStream/CanTimeout.md) { get; } | Always false. |
17+
| override [CanWrite](RecyclableMemoryStream/CanWrite.md) { get; } | Whether the stream can currently write. |
18+
| override [Capacity](RecyclableMemoryStream/Capacity.md) { getset; } | Gets or sets the capacity. |
1919
| [Capacity64](RecyclableMemoryStream/Capacity64.md) { getset; } | Returns a 64-bit version of capacity, for streams larger than `int.MaxValue` in length. |
2020
| override [Length](RecyclableMemoryStream/Length.md) { get; } | Gets the number of bytes written to this stream. |
21-
| override [Position](RecyclableMemoryStream/Position.md) { getset; } | Gets the current position in the stream |
22-
| [Advance](RecyclableMemoryStream/Advance.md)(…) | Notifies the stream that *count* bytes were written to the buffer returned by [`GetMemory`](RecyclableMemoryStream/GetMemory.md) or [`GetSpan`](RecyclableMemoryStream/GetSpan.md). Seeks forward by *count* bytes. |
23-
| override [Close](RecyclableMemoryStream/Close.md)() | Equivalent to `Dispose` |
21+
| override [Position](RecyclableMemoryStream/Position.md) { getset; } | Gets the current position in the stream. |
22+
| [Advance](RecyclableMemoryStream/Advance.md)(…) | Notifies the stream that *count* bytes were written to the buffer returned by [`GetMemory`](./RecyclableMemoryStream/GetMemory.md) or [`GetSpan`](./RecyclableMemoryStream/GetSpan.md). Seeks forward by *count* bytes. |
23+
| override [Close](RecyclableMemoryStream/Close.md)() | Equivalent to `Dispose`. |
2424
| override [CopyToAsync](RecyclableMemoryStream/CopyToAsync.md)(…) | Asynchronously reads all the bytes from the current position in this stream and writes them to another stream. |
2525
| override [GetBuffer](RecyclableMemoryStream/GetBuffer.md)() | Returns a single buffer containing the contents of the stream. The buffer may be longer than the stream length. |
2626
| [GetMemory](RecyclableMemoryStream/GetMemory.md)(…) | |
2727
| [GetReadOnlySequence](RecyclableMemoryStream/GetReadOnlySequence.md)() | Returns a sequence containing the contents of the stream. |
2828
| [GetSpan](RecyclableMemoryStream/GetSpan.md)(…) | |
29-
| override [Read](RecyclableMemoryStream/Read.md)(…) | Reads from the current position into the provided buffer (2 methods) |
29+
| override [Read](RecyclableMemoryStream/Read.md)(…) | Reads from the current position into the provided buffer. (2 methods) |
3030
| override [ReadByte](RecyclableMemoryStream/ReadByte.md)() | Reads a single byte from the current position in the stream. |
31-
| [SafeRead](RecyclableMemoryStream/SafeRead.md)(…) | Reads from the specified position into the provided buffer (4 methods) |
31+
| [SafeRead](RecyclableMemoryStream/SafeRead.md)(…) | Reads from the specified position into the provided buffer. (4 methods) |
3232
| [SafeReadByte](RecyclableMemoryStream/SafeReadByte.md)(…) | Reads a single byte from the specified position in the stream. (2 methods) |
33-
| override [Seek](RecyclableMemoryStream/Seek.md)(…) | Sets the position to the offset from the seek location |
34-
| override [SetLength](RecyclableMemoryStream/SetLength.md)(…) | Sets the length of the stream |
35-
| override [ToArray](RecyclableMemoryStream/ToArray.md)() | Returns a new array with a copy of the buffer's contents. You should almost certainly be using [`GetBuffer`](RecyclableMemoryStream/GetBuffer.md) combined with the [`Length`](RecyclableMemoryStream/Length.md) to access the bytes in this stream. Calling `ToArray` will destroy the benefits of pooled buffers, but it is included for the sake of completeness. |
33+
| override [Seek](RecyclableMemoryStream/Seek.md)(…) | Sets the position to the offset from the seek location. |
34+
| override [SetLength](RecyclableMemoryStream/SetLength.md)(…) | Sets the length of the stream. |
35+
| override [ToArray](RecyclableMemoryStream/ToArray.md)() | Returns a new array with a copy of the buffer's contents. You should almost certainly be using [`GetBuffer`](./RecyclableMemoryStream/GetBuffer.md) combined with the [`Length`](./RecyclableMemoryStream/Length.md) to access the bytes in this stream. Calling `ToArray` will destroy the benefits of pooled buffers, but it is included for the sake of completeness. |
3636
| override [ToString](RecyclableMemoryStream/ToString.md)() | Returns a useful string for debugging. This should not normally be called in actual production code. |
3737
| override [TryGetBuffer](RecyclableMemoryStream/TryGetBuffer.md)(…) | Returns an `ArraySegment` that wraps a single buffer containing the contents of the stream. |
38-
| override [Write](RecyclableMemoryStream/Write.md)(…) | Writes the buffer to the stream (2 methods) |
38+
| override [Write](RecyclableMemoryStream/Write.md)(…) | Writes the buffer to the stream. (2 methods) |
3939
| override [WriteByte](RecyclableMemoryStream/WriteByte.md)(…) | Writes a single byte to the current position in the stream. |
4040
| override [WriteTo](RecyclableMemoryStream/WriteTo.md)(…) | Synchronously writes this stream's bytes to the argument stream. |
4141
| [WriteTo](RecyclableMemoryStream/WriteTo.md)(…) | Synchronously writes this stream's bytes, starting at offset, for count bytes, to the argument stream. (5 methods) |
@@ -49,16 +49,16 @@ public sealed class RecyclableMemoryStream : MemoryStream, IBufferWriter<byte>
4949

5050
## Remarks
5151

52-
This class works in tandem with the [`RecyclableMemoryStreamManager`](RecyclableMemoryStreamManager.md) to supply `MemoryStream`-derived objects to callers, while avoiding these specific problems:
52+
This class works in tandem with the [`RecyclableMemoryStreamManager`](./RecyclableMemoryStreamManager.md) to supply `MemoryStream`-derived objects to callers, while avoiding these specific problems:
5353

5454
1. **LOH allocations** – Since all large buffers are pooled, they will never incur a Gen2 GC
5555
2. **Memory waste** – A standard memory stream doubles its size when it runs out of room. This leads to continual memory growth as each stream approaches the maximum allowed size.
56-
3. **Memory copying** – Each time a `MemoryStream` grows, all the bytes are copied into new buffers. This implementation only copies the bytes when [`GetBuffer`](RecyclableMemoryStream/GetBuffer.md) is called.
56+
3. **Memory copying** – Each time a `MemoryStream` grows, all the bytes are copied into new buffers. This implementation only copies the bytes when [`GetBuffer`](./RecyclableMemoryStream/GetBuffer.md) is called.
5757
4. **Memory fragmentation** – By using homogeneous buffer sizes, it ensures that blocks of memory can be easily reused.
5858

5959
The stream is implemented on top of a series of uniformly-sized blocks. As the stream's length grows, additional blocks are retrieved from the memory manager. It is these blocks that are pooled, not the stream object itself.
6060

61-
The biggest wrinkle in this implementation is when [`GetBuffer`](RecyclableMemoryStream/GetBuffer.md) is called. This requires a single contiguous buffer. If only a single block is in use, then that block is returned. If multiple blocks are in use, we retrieve a larger buffer from the memory manager. These large buffers are also pooled, split by size--they are multiples/exponentials of a chunk size (1 MB by default).
61+
The biggest wrinkle in this implementation is when [`GetBuffer`](./RecyclableMemoryStream/GetBuffer.md) is called. This requires a single contiguous buffer. If only a single block is in use, then that block is returned. If multiple blocks are in use, we retrieve a larger buffer from the memory manager. These large buffers are also pooled, split by size--they are multiples/exponentials of a chunk size (1 MB by default).
6262

6363
Once a large buffer is assigned to the stream the small blocks are NEVER again used for this stream. All operations take place on the large buffer. The large buffer can be replaced by a larger buffer from the pool as needed. All blocks and large buffers are maintained in the stream until the stream is disposed (unless AggressiveBufferReturn is enabled in the stream manager).
6464

docs/Microsoft.IO/RecyclableMemoryStream/Advance.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
# RecyclableMemoryStream.Advance method
22

3-
Notifies the stream that *count* bytes were written to the buffer returned by [`GetMemory`](GetMemory.md) or [`GetSpan`](GetSpan.md). Seeks forward by *count* bytes.
3+
Notifies the stream that *count* bytes were written to the buffer returned by [`GetMemory`](./GetMemory.md) or [`GetSpan`](./GetSpan.md). Seeks forward by *count* bytes.
44

55
```csharp
66
public void Advance(int count)
77
```
88

99
| parameter | description |
1010
| --- | --- |
11-
| count | How many bytes to advance |
11+
| count | How many bytes to advance. |
1212

1313
## Exceptions
1414

1515
| exception | condition |
1616
| --- | --- |
17-
| ObjectDisposedException | Object has been disposed |
18-
| ArgumentOutOfRangeException | *count* is negative |
19-
| InvalidOperationException | *count* is larger than the size of the previously requested buffer |
17+
| ObjectDisposedException | Object has been disposed. |
18+
| ArgumentOutOfRangeException | *count* is negative. |
19+
| InvalidOperationException | *count* is larger than the size of the previously requested buffer. |
2020

2121
## Remarks
2222

docs/Microsoft.IO/RecyclableMemoryStream/CanRead.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RecyclableMemoryStream.CanRead property
22

3-
Whether the stream can currently read
3+
Whether the stream can currently read.
44

55
```csharp
66
public override bool CanRead { get; }

docs/Microsoft.IO/RecyclableMemoryStream/CanSeek.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RecyclableMemoryStream.CanSeek property
22

3-
Whether the stream can currently seek
3+
Whether the stream can currently seek.
44

55
```csharp
66
public override bool CanSeek { get; }

docs/Microsoft.IO/RecyclableMemoryStream/CanTimeout.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RecyclableMemoryStream.CanTimeout property
22

3-
Always false
3+
Always false.
44

55
```csharp
66
public override bool CanTimeout { get; }

docs/Microsoft.IO/RecyclableMemoryStream/CanWrite.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RecyclableMemoryStream.CanWrite property
22

3-
Whether the stream can currently write
3+
Whether the stream can currently write.
44

55
```csharp
66
public override bool CanWrite { get; }

docs/Microsoft.IO/RecyclableMemoryStream/Capacity.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RecyclableMemoryStream.Capacity property
22

3-
Gets or sets the capacity
3+
Gets or sets the capacity.
44

55
```csharp
66
public override int Capacity { get; set; }
@@ -10,15 +10,16 @@ public override int Capacity { get; set; }
1010

1111
| exception | condition |
1212
| --- | --- |
13-
| ObjectDisposedException | Object has been disposed |
13+
| ObjectDisposedException | Object has been disposed. |
14+
| InvalidOperationException | Capacity is larger than int.MaxValue. |
1415

1516
## Remarks
1617

1718
Capacity is always in multiples of the memory manager's block size, unless the large buffer is in use. Capacity never decreases during a stream's lifetime. Explicitly setting the capacity to a lower value than the current value will have no effect. This is because the buffers are all pooled by chunks and there's little reason to allow stream truncation.
1819

1920
Writing past the current capacity will cause `Capacity` to automatically increase, until MaximumStreamCapacity is reached.
2021

21-
If the capacity is larger than `int.MaxValue`, then `int.MaxValue` will be returned. If you anticipate using larger streams, use the [`Capacity64`](Capacity64.md) property instead.
22+
If the capacity is larger than `int.MaxValue`, then `InvalidOperationException` will be thrown. If you anticipate using larger streams, use the [`Capacity64`](./Capacity64.md) property instead.
2223

2324
## See Also
2425

docs/Microsoft.IO/RecyclableMemoryStream/Close.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RecyclableMemoryStream.Close method
22

3-
Equivalent to `Dispose`
3+
Equivalent to `Dispose`.
44

55
```csharp
66
public override void Close()

0 commit comments

Comments
 (0)