-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathS3Directory.cs
More file actions
154 lines (127 loc) · 5.47 KB
/
S3Directory.cs
File metadata and controls
154 lines (127 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System.Runtime.CompilerServices;
using Amazon.S3.Model;
namespace Ramstack.FileSystem.Amazon;
/// <summary>
/// Represents an implementation of <see cref="VirtualDirectory"/> that maps a directory
/// to a path within a specified Amazon S3 bucket.
/// </summary>
internal sealed class S3Directory : VirtualDirectory
{
private readonly AmazonS3FileSystem _fs;
private readonly string _prefix;
/// <inheritdoc />
public override IVirtualFileSystem FileSystem => _fs;
/// <summary>
/// Initializes a new instance of the <see cref="S3Directory"/> class.
/// </summary>
/// <param name="fileSystem">The file system associated with this directory.</param>
/// <param name="path">The path to the directory within the specified Amazon S3 bucket.</param>
public S3Directory(AmazonS3FileSystem fileSystem, string path) : base(path)
{
_fs = fileSystem;
_prefix = FullName == "/" ? "" : $"{FullName[1..]}/";
}
/// <inheritdoc />
protected override ValueTask<VirtualNodeProperties?> GetPropertiesCoreAsync(CancellationToken cancellationToken)
{
var properties = VirtualNodeProperties.CreateDirectoryProperties(default, default, default);
return new ValueTask<VirtualNodeProperties?>(properties);
}
/// <inheritdoc />
protected override ValueTask CreateCoreAsync(CancellationToken cancellationToken) =>
default;
/// <inheritdoc />
protected override async ValueTask DeleteCoreAsync(CancellationToken cancellationToken)
{
var lr = new ListObjectsV2Request
{
BucketName = _fs.BucketName,
Prefix = _prefix
};
var dr = new DeleteObjectsRequest
{
BucketName = _fs.BucketName
};
do
{
// The maximum number of objects returned is MaxKeys, which is 1000,
// and the maximum number of objects that can be deleted at once is also 1000.
// Therefore, we can rely (sure?) on this and avoid splitting
// the retrieved objects into separate batches.
var response = await _fs.AmazonClient
.ListObjectsV2Async(lr, cancellationToken)
.ConfigureAwait(false);
foreach (var obj in response.S3Objects)
dr.Objects.Add(new KeyVersion { Key = obj.Key });
if (dr.Objects.Count != 0)
await _fs.AmazonClient
.DeleteObjectsAsync(dr, cancellationToken)
.ConfigureAwait(false);
dr.Objects.Clear();
lr.ContinuationToken = response.NextContinuationToken;
}
while (lr.ContinuationToken is not null && !cancellationToken.IsCancellationRequested);
}
/// <inheritdoc />
protected override async IAsyncEnumerable<VirtualNode> GetFileNodesCoreAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var request = new ListObjectsV2Request
{
BucketName = _fs.BucketName,
Prefix = _prefix,
Delimiter = "/"
};
do
{
var response = await _fs.AmazonClient
.ListObjectsV2Async(request, cancellationToken)
.ConfigureAwait(false);
foreach (var prefix in response.CommonPrefixes)
yield return new S3Directory(_fs, VirtualPath.Normalize(prefix));
foreach (var obj in response.S3Objects)
yield return new S3File(_fs, VirtualPath.Normalize(obj.Key));
request.ContinuationToken = response.NextContinuationToken;
}
while (request.ContinuationToken is not null && !cancellationToken.IsCancellationRequested);
}
/// <inheritdoc />
protected override async IAsyncEnumerable<VirtualFile> GetFilesCoreAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var request = new ListObjectsV2Request
{
BucketName = _fs.BucketName,
Prefix = _prefix,
Delimiter = "/"
};
do
{
var response = await _fs.AmazonClient
.ListObjectsV2Async(request, cancellationToken)
.ConfigureAwait(false);
foreach (var obj in response.S3Objects)
yield return new S3File(_fs, VirtualPath.Normalize(obj.Key));
request.ContinuationToken = response.NextContinuationToken;
}
while (request.ContinuationToken is not null && !cancellationToken.IsCancellationRequested);
}
/// <inheritdoc />
protected override async IAsyncEnumerable<VirtualDirectory> GetDirectoriesCoreAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var request = new ListObjectsV2Request
{
BucketName = _fs.BucketName,
Prefix = _prefix,
Delimiter = "/"
};
do
{
var response = await _fs.AmazonClient
.ListObjectsV2Async(request, cancellationToken)
.ConfigureAwait(false);
foreach (var prefix in response.CommonPrefixes)
yield return new S3Directory(_fs, VirtualPath.Normalize(prefix));
request.ContinuationToken = response.NextContinuationToken;
}
while (request.ContinuationToken is not null && !cancellationToken.IsCancellationRequested);
}
}