namespace UniversalNetFrame451;
///
/// The Smaller T_Level value is, The higher Priority it has
///
///
///
public class PriorityQueue : IEnumerable
where T_Level : Enum
//where T_Level : IOrderedEnumerable
{
public PriorityQueue()
{
Type type = Enum.GetUnderlyingType(typeof(T_Level));
if (type == typeof(int))
{
Dictionary t_int = new();
foreach (var item in Enum.GetValues(typeof(T_Level)))
t_int[(int)item] = (T_Level)item;
foreach (var item in t_int.OrderBy(t => t.Key))
_queues.Add(item.Value, new());
return;
}
if (type == typeof(byte))
{
Dictionary t_byte = new();
foreach (var item in Enum.GetValues(typeof(T_Level)))
t_byte[(byte)item] = (T_Level)item;
foreach (var item in t_byte.OrderBy(t => t.Key))
_queues.Add(item.Value, new());
return;
}
if (type == typeof(short))
{
Dictionary t_short = new();
foreach (var item in Enum.GetValues(typeof(T_Level)))
t_short[(short)item] = (T_Level)item;
foreach (var item in t_short.OrderBy(t => t.Key))
_queues.Add(item.Value, new());
return;
}
if (type == typeof(long))
{
Dictionary t_long = new();
foreach (var item in Enum.GetValues(typeof(T_Level)))
t_long[(long)item] = (T_Level)item;
foreach (var item in t_long.OrderBy(t => t.Key))
_queues.Add(item.Value, new());
return;
}
throw new Exception();
}
private readonly Dictionary> _queues = [];
public bool TryEnqueue(T_Level level, T_type content)
{
lock (this)
{
if (!this._queues.TryGetValue(level, out Queue queue) || queue is null)
return false;
queue.Enqueue(content);
return true;
}
}
public bool TryPeek(out T_type output)
{
lock (this)
{
foreach (T_Level Key in _queues.Keys)
{
if (!this._queues[Key].TryPeek(out output))
continue;
return true;
}
output = default;
return false;
}
}
public bool TryPeek(T_Level level, out T_type output)
{
lock (this)
{
output = default;
if (!this._queues.TryGetValue(level, out Queue queue) || queue is null)
return false;
return queue.TryPeek(out output);
}
}
public bool TryDequeue(out T_type output)
{
lock (this)
{
foreach (T_Level Key in _queues.Keys)
{
if (!this._queues[Key].TryDequeue(out output))
continue;
return true;
}
output = default;
return false;
}
}
public bool TryDequeue(T_Level level, out T_type output)
{
lock (this)
{
output = default;
if (!this._queues.TryGetValue(level, out Queue queue) || queue is null)
return false;
return queue.TryDequeue(out output);
}
}
public Dictionary Count
{
get
{
lock (this)
{
Dictionary counts = [];
foreach (var item in _queues)
counts[item.Key] = item.Value.Count;
return counts;
}
}
}
public int Total
{
get
{
int count = 0; lock (this)
{
foreach (var item in _queues)
count += item.Value.Count;
return count;
}
}
}
public int LevelCount(T_Level t_Level)
{
lock (this)
{
if (!_queues.TryGetValue(t_Level, out var Value) || Value is null)
return 0;
return Value.Count;
}
}
public IEnumerator GetEnumerator()
{
lock (this)
{
List t = [];
while (TryDequeue(out T_type output))
t.Add(output);
return t.GetEnumerator();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}