<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="10.0.0-preview.7.25380.108" />

DiagLinkedList<T>

sealed class DiagLinkedList<T> : IEnumerable<T>, IEnumerable
using System.Collections; using System.Collections.Generic; using System.Text; namespace System.Diagnostics { internal sealed class DiagLinkedList<T> : IEnumerable<T>, IEnumerable { private DiagNode<T> _first; private DiagNode<T> _last; public DiagNode<T> First => _first; public DiagLinkedList() { } public DiagLinkedList(T firstValue) { _last = (_first = new DiagNode<T>(firstValue)); } public DiagLinkedList(IEnumerator<T> e) { _last = (_first = new DiagNode<T>(e.Current)); while (e.MoveNext()) { _last.Next = new DiagNode<T>(e.Current); _last = _last.Next; } } public void Clear() { lock (this) { _first = (_last = null); } } private void UnsafeAdd(DiagNode<T> newNode) { if (_first == null) _first = (_last = newNode); else { _last.Next = newNode; _last = newNode; } } public void Add(T value) { DiagNode<T> newNode = new DiagNode<T>(value); lock (this) { UnsafeAdd(newNode); } } public bool AddIfNotExist(T value, Func<T, T, bool> compare) { lock (this) { for (DiagNode<T> diagNode = _first; diagNode != null; diagNode = diagNode.Next) { if (compare(value, diagNode.Value)) return false; } DiagNode<T> newNode = new DiagNode<T>(value); UnsafeAdd(newNode); return true; } } public T Remove(T value, Func<T, T, bool> compare) { lock (this) { DiagNode<T> diagNode = _first; if (diagNode != null) { if (!compare(diagNode.Value, value)) { for (DiagNode<T> next = diagNode.Next; next != null; next = next.Next) { if (compare(next.Value, value)) { diagNode.Next = next.Next; if (_last == next) _last = diagNode; return next.Value; } diagNode = next; } return default(T); } _first = diagNode.Next; if (_first == null) _last = null; return diagNode.Value; } return default(T); } } public void AddFront(T value) { DiagNode<T> diagNode = new DiagNode<T>(value); lock (this) { diagNode.Next = _first; _first = diagNode; } } public DiagEnumerator<T> GetEnumerator() { return new DiagEnumerator<T>(_first); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static void ActivityLinkToString(ref ActivityLink al, ref System.Text.ValueStringBuilder vsb) { ActivityContext context = al.Context; vsb.Append("("); vsb.Append(context.TraceId.ToHexString()); vsb.Append(",​"); vsb.Append(context.SpanId.ToHexString()); vsb.Append(",​"); vsb.Append(context.TraceFlags.ToString()); vsb.Append(",​"); vsb.Append(context.TraceState ?? "null"); vsb.Append(",​"); vsb.Append(context.IsRemote ? "true" : "false"); if (al.Tags != null) { vsb.Append(",​["); string s = ""; Activity.Enumerator<KeyValuePair<string, object>> enumerator = al.EnumerateTagObjects().GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, object> current = enumerator.Current; vsb.Append(s); vsb.Append(current.Key); vsb.Append(":​"); vsb.Append(current.Value?.ToString() ?? "null"); s = ",​"; } vsb.Append("]"); } vsb.Append(")"); } private static void ActivityEventToString(ref ActivityEvent ae, ref System.Text.ValueStringBuilder vsb) { vsb.Append("("); vsb.Append(ae.Name); vsb.Append(",​"); vsb.Append(ae.Timestamp.ToString("o")); if (ae.Tags != null) { vsb.Append(",​["); string s = ""; Activity.Enumerator<KeyValuePair<string, object>> enumerator = ae.EnumerateTagObjects().GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, object> current = enumerator.Current; vsb.Append(s); vsb.Append(current.Key); vsb.Append(":​"); vsb.Append(current.Value?.ToString() ?? "null"); s = ",​"; } vsb.Append("]"); } vsb.Append(")"); } public unsafe override string ToString() { lock (this) { DiagNode<T> diagNode = _first; if (diagNode != null) { Span<char> initialBuffer = new Span<char>(stackalloc byte[512], 256); System.Text.ValueStringBuilder vsb = new System.Text.ValueStringBuilder(initialBuffer); vsb.Append("["); if (typeof(T) == typeof(ActivityLink)) { while (diagNode != null) { ActivityLink al = (ActivityLink)(object)diagNode.Value; ActivityLinkToString(ref al, ref vsb); diagNode = diagNode.Next; if (diagNode != null) vsb.Append(",​"); } } else if (!(typeof(T) == typeof(ActivityEvent))) { while (diagNode != null) { ref T reference = ref diagNode.Value; T val = default(T); object obj; if (val == null) { val = reference; ref reference = ref val; if (val == null) { obj = null; goto IL_0131; } } obj = reference.ToString(); goto IL_0131; IL_0131: if (obj == null) obj = "null"; vsb.Append((string)obj); diagNode = diagNode.Next; if (diagNode != null) vsb.Append(",​"); } } else { while (diagNode != null) { ActivityEvent ae = (ActivityEvent)(object)diagNode.Value; ActivityEventToString(ref ae, ref vsb); diagNode = diagNode.Next; if (diagNode != null) vsb.Append(",​"); } } vsb.Append("]"); return vsb.ToString(); } return "[]"; } } } }