-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDependencyQueueTopic.cs
More file actions
137 lines (118 loc) · 3.94 KB
/
Copy pathDependencyQueueTopic.cs
File metadata and controls
137 lines (118 loc) · 3.94 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
// Copyright Subatomix Research Inc.
// SPDX-License-Identifier: MIT
using System.Text;
namespace DependencyQueue;
/// <summary>
/// A name which queue items can provide or require in order to express
/// edges in a dependency graph.
/// </summary>
/// <typeparam name="T">
/// The type of values contained in queue items.
/// </typeparam>
public class DependencyQueueTopic<T>
{
/// <summary>
/// Initializes a new <see cref="DependencyQueueTopic{T}"/> instance with
/// the specified name.
/// </summary>
/// <param name="name">
/// The name of the topic.
/// </param>
internal DependencyQueueTopic(string name)
{
if (name is null)
throw Errors.ArgumentNull(nameof(name));
if (name.Length == 0)
throw Errors.ArgumentEmpty(nameof(name));
Name = name;
ProvidedBy = new();
RequiredBy = new();
}
/// <summary>
/// Gets the name of the topic.
/// </summary>
public string Name { get; }
/// <summary>
/// Gets the set of items that provide the topic.
/// </summary>
internal List<DependencyQueueItem<T>> ProvidedBy { get; }
/// <summary>
/// Gets the set of items that require the topic.
/// </summary>
internal List<DependencyQueueItem<T>> RequiredBy { get; }
/// <inheritdoc/>
public override string ToString()
{
return Name;
}
/// <summary>
/// A read-only view of an exclusively-locked
/// <see cref="DependencyQueueTopic{T}"/>.
/// </summary>
public readonly struct View
{
private readonly DependencyQueueTopic<T> _topic;
private readonly AsyncMonitor.Lock _lock;
internal View(DependencyQueueTopic<T> dependencyQueueTopic, AsyncMonitor.Lock @lock)
{
_topic = dependencyQueueTopic;
_lock = @lock;
}
/// <summary>
/// Gets the underlying topic.
/// </summary>
public DependencyQueueTopic<T> Topic => _topic;
/// <inheritdoc cref="DependencyQueueTopic{T}.Name"/>
public string Name => _topic.Name;
/// <inheritdoc cref="DependencyQueueTopic{T}.ProvidedBy"/>
/// <exception cref="ObjectDisposedException">
/// The underlying lock has been released.
/// </exception>
public DependencyQueueItemListView<T> ProvidedBy
{
get
{
_lock.RequireNotDisposed();
return new(_topic.ProvidedBy, _lock);
}
}
/// <inheritdoc cref="DependencyQueueTopic{T}.RequiredBy"/>
/// <exception cref="ObjectDisposedException">
/// The underlying lock has been released.
/// </exception>
public DependencyQueueItemListView<T> RequiredBy
{
get
{
_lock.RequireNotDisposed();
return new(_topic.RequiredBy, _lock);
}
}
/// <inheritdoc/>
/// <exception cref="ObjectDisposedException">
/// The underlying lock has been released.
/// </exception>
public override string ToString()
{
_lock.RequireNotDisposed();
const string
ChunkA = " (ProvidedBy: ",
ChunkB = "; RequiredBy: ",
ChunkC = ")";
var providedBy = _topic.ProvidedBy.Select(e => e.Name);
var requiredBy = _topic.RequiredBy.Select(e => e.Name);
var length
= ChunkA.Length
+ ChunkB.Length
+ ChunkC.Length
+ Name .Length
+ providedBy.GetJoinedLength()
+ requiredBy.GetJoinedLength();
return new StringBuilder(length)
.Append(Name)
.Append(ChunkA ).AppendJoined(providedBy)
.Append(ChunkB ).AppendJoined(requiredBy)
.Append(ChunkC[0]).ToString();
}
}
}