[+] TEngineServer

[+] TEngineServer
This commit is contained in:
ALEXTANG
2023-07-13 17:17:26 +08:00
parent a69f53592e
commit 0c8f3a5f92
790 changed files with 52737 additions and 2533 deletions

View File

@@ -0,0 +1,267 @@
using System;
using System.Collections;
namespace ProtoBuf.Meta
{
internal sealed class MutableList : BasicList
{
/* Like BasicList, but allows existing values to be changed
*/
public new object this[int index]
{
get { return head[index]; }
set { head[index] = value; }
}
public void RemoveLast()
{
head.RemoveLastWithMutate();
}
public void Clear()
{
head.Clear();
}
}
internal class BasicList : IEnumerable
{
/* Requirements:
* - Fast access by index
* - Immutable in the tail, so a node can be read (iterated) without locking
* - Lock-free tail handling must match the memory mode; struct for Node
* wouldn't work as "read" would not be atomic
* - Only operation required is append, but this shouldn't go out of its
* way to be inefficient
* - Assume that the caller is handling thread-safety (to co-ordinate with
* other code); no attempt to be thread-safe
* - Assume that the data is private; internal data structure is allowed to
* be mutable (i.e. array is fine as long as we don't screw it up)
*/
private static readonly Node nil = new Node(null, 0);
public void CopyTo(Array array, int offset)
{
head.CopyTo(array, offset);
}
protected Node head = nil;
public int Add(object value)
{
return (head = head.Append(value)).Length - 1;
}
public object this[int index] => head[index];
//public object TryGet(int index)
//{
// return head.TryGet(index);
//}
public void Trim() { head = head.Trim(); }
public int Count => head.Length;
IEnumerator IEnumerable.GetEnumerator() => new NodeEnumerator(head);
public NodeEnumerator GetEnumerator() => new NodeEnumerator(head);
public struct NodeEnumerator : IEnumerator
{
private int position;
private readonly Node node;
internal NodeEnumerator(Node node)
{
this.position = -1;
this.node = node;
}
void IEnumerator.Reset() { position = -1; }
public object Current { get { return node[position]; } }
public bool MoveNext()
{
int len = node.Length;
return (position <= len) && (++position < len);
}
}
internal sealed class Node
{
public object this[int index]
{
get
{
if (index >= 0 && index < length)
{
return data[index];
}
throw new ArgumentOutOfRangeException(nameof(index));
}
set
{
if (index >= 0 && index < length)
{
data[index] = value;
}
else
{
throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
//public object TryGet(int index)
//{
// return (index >= 0 && index < length) ? data[index] : null;
//}
private readonly object[] data;
private int length;
public int Length => length;
internal Node(object[] data, int length)
{
Helpers.DebugAssert((data == null && length == 0) ||
(data != null && length > 0 && length <= data.Length));
this.data = data;
this.length = length;
}
public void RemoveLastWithMutate()
{
if (length == 0) throw new InvalidOperationException();
length -= 1;
}
public Node Append(object value)
{
object[] newData;
int newLength = length + 1;
if (data == null)
{
newData = new object[10];
}
else if (length == data.Length)
{
newData = new object[data.Length * 2];
Array.Copy(data, newData, length);
}
else
{
newData = data;
}
newData[length] = value;
return new Node(newData, newLength);
}
public Node Trim()
{
if (length == 0 || length == data.Length) return this;
object[] newData = new object[length];
Array.Copy(data, newData, length);
return new Node(newData, length);
}
internal int IndexOfString(string value)
{
for (int i = 0; i < length; i++)
{
if ((string)value == (string)data[i]) return i;
}
return -1;
}
internal int IndexOfReference(object instance)
{
for (int i = 0; i < length; i++)
{
if ((object)instance == (object)data[i]) return i;
} // ^^^ (object) above should be preserved, even if this was typed; needs
// to be a reference check
return -1;
}
internal int IndexOf(MatchPredicate predicate, object ctx)
{
for (int i = 0; i < length; i++)
{
if (predicate(data[i], ctx)) return i;
}
return -1;
}
internal void CopyTo(Array array, int offset)
{
if (length > 0)
{
Array.Copy(data, 0, array, offset, length);
}
}
internal void Clear()
{
if (data != null)
{
Array.Clear(data, 0, data.Length);
}
length = 0;
}
}
internal int IndexOf(MatchPredicate predicate, object ctx)
{
return head.IndexOf(predicate, ctx);
}
internal int IndexOfString(string value)
{
return head.IndexOfString(value);
}
internal int IndexOfReference(object instance)
{
return head.IndexOfReference(instance);
}
internal delegate bool MatchPredicate(object value, object ctx);
internal bool Contains(object value)
{
foreach (object obj in this)
{
if (object.Equals(obj, value)) return true;
}
return false;
}
internal sealed class Group
{
public readonly int First;
public readonly BasicList Items;
public Group(int first)
{
this.First = first;
this.Items = new BasicList();
}
}
internal static BasicList GetContiguousGroups(int[] keys, object[] values)
{
if (keys == null) throw new ArgumentNullException(nameof(keys));
if (values == null) throw new ArgumentNullException(nameof(values));
if (values.Length < keys.Length) throw new ArgumentException("Not all keys are covered by values", nameof(values));
BasicList outer = new BasicList();
Group group = null;
for (int i = 0; i < keys.Length; i++)
{
if (i == 0 || keys[i] != keys[i - 1]) { group = null; }
if (group == null)
{
group = new Group(keys[i]);
outer.Add(group);
}
group.Items.Add(values[i]);
}
return outer;
}
}
}