DiagLinkedList<T>
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 "[]";
}
}
}
}