Skip to content

Commit aef0f44

Browse files
committed
Use multiple, independent views on the same base stream.
1 parent cd07aa0 commit aef0f44

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCache.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,23 @@ namespace Nerdbank.GitVersioning.ManagedGit
99
{
1010
internal class GitPackMemoryCache : GitPackCache
1111
{
12-
private readonly Dictionary<long, Stream> cache = new Dictionary<long, Stream>();
12+
private readonly Dictionary<long, GitPackMemoryCacheStream> cache = new Dictionary<long, GitPackMemoryCacheStream>();
1313

1414
public override Stream Add(long offset, Stream stream)
1515
{
1616
var cacheStream = new GitPackMemoryCacheStream(stream);
17-
return cacheStream;
17+
this.cache.Add(offset, cacheStream);
18+
return new GitPackMemoryCacheViewStream(cacheStream);
1819
}
1920

2021
public override bool TryOpen(long offset, [NotNullWhen(true)] out Stream? stream)
2122
{
23+
if (this.cache.TryGetValue(offset, out GitPackMemoryCacheStream? cacheStream))
24+
{
25+
stream = new GitPackMemoryCacheViewStream(cacheStream!);
26+
return true;
27+
}
28+
2229
stream = null;
2330
return false;
2431
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text;
5+
6+
namespace Nerdbank.GitVersioning.ManagedGit
7+
{
8+
internal class GitPackMemoryCacheViewStream : Stream
9+
{
10+
private readonly GitPackMemoryCacheStream baseStream;
11+
12+
public GitPackMemoryCacheViewStream(GitPackMemoryCacheStream baseStream)
13+
{
14+
this.baseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
15+
}
16+
17+
public override bool CanRead => true;
18+
19+
public override bool CanSeek => true;
20+
21+
public override bool CanWrite => false;
22+
23+
public override long Length => this.baseStream.Length;
24+
25+
private long position;
26+
27+
public override long Position
28+
{
29+
get => this.position;
30+
set => throw new NotSupportedException();
31+
}
32+
33+
public override void Flush() => throw new NotImplementedException();
34+
35+
public override int Read(byte[] buffer, int offset, int count)
36+
{
37+
return this.Read(buffer.AsSpan(offset, count));
38+
}
39+
40+
#if NETSTANDARD
41+
public int Read(Span<byte> buffer)
42+
#else
43+
/// <inheritdoc/>
44+
public override int Read(Span<byte> buffer)
45+
#endif
46+
{
47+
int read = 0;
48+
49+
lock (this.baseStream)
50+
{
51+
if (this.baseStream.Position != this.position)
52+
{
53+
this.baseStream.Seek(this.position, SeekOrigin.Begin);
54+
}
55+
56+
read = this.baseStream.Read(buffer);
57+
}
58+
59+
this.position += read;
60+
return read;
61+
}
62+
63+
public override long Seek(long offset, SeekOrigin origin)
64+
{
65+
if (origin != SeekOrigin.Begin)
66+
{
67+
throw new NotSupportedException();
68+
}
69+
70+
this.position = Math.Min(offset, this.Length);
71+
return this.position;
72+
}
73+
74+
public override void SetLength(long value) => throw new NotSupportedException();
75+
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
76+
}
77+
}

0 commit comments

Comments
 (0)