DynConcurrentList.cs

Dynamic Concurrent Generic List

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class DynConcurrentList<T> : MonitorActionFunc, IEnumerable<T>
{
    private          T[]        _array;
    private volatile MiniSet<T> _mSet;
    public volatile  int        Count;
    public DynConcurrentList() : this(101)
    {
    }
    public DynConcurrentList(IEnumerable<T> collection)
    {
        var enumerable = collection as T[] ?? collection.ToArray();
        Count  = enumerable.Length;
        _array = new T[Count];
        Array.Copy(enumerable, 0, _array, 0, Count);
    }
    public DynConcurrentList(int cap)
    {
        _array = new T[cap];
        Count  = 0;
    }
    public int Capacity
    {
        get
        {
            var tmpThis = this;
            return tmpThis.Lock(tmpThis, () =>
            {
                return _array.Length;
            });
        }
        set
        {
            var tmpThis = this;
            tmpThis.Lock(tmpThis, () =>
            {
                Array.Resize(ref _array, value);
            });
        }
    }
    public T this[int index]
    {
        get
        {
            var array   = _array;
            var idx     = index;
            var tmpThis = this;
            return tmpThis.Lock(tmpThis, () =>
            {
                if (idx > array.Length)
                    throw new Exception("Error: Index out of range.");
                return array[idx];
            });
        }
        set
        {
            var tmpThis = this;
            var idx     = index;
            tmpThis.Lock(tmpThis, () =>
            {
                if (idx >= _array.Length)
                    Array.Resize(ref _array, _array.Length + _array.Length / 4 * 3);
                _array[idx] = value;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void Add(T item)
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            if (Count >= _array.Length)
                Array.Resize(ref _array, _array.Length + _array.Length / 4 * 3);
            _array[Count] = item;
            Interlocked.Increment(ref Count);
        });
    }
    public void AddRange(IEnumerable<T> col)
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            var enumerable = col as T[] ?? col.ToArray();
            for (var i = 0; i < enumerable.Length; ++i)
            {
                if (Count >= _array.Length)
                    Array.Resize(ref _array, _array.Length + _array.Length / 4 * 3);
                _array[Count] = enumerable[i];
                Interlocked.Increment(ref Count);
            }
        });
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, _array.Length);
            Count = 0;
        });
    }
    public void Clean()
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            _array = newtArray;
        });
    }
    public bool Contains(T item, IEqualityComparer<T> comparer = null)
    {
        if (comparer == null)
            comparer = EqualityComparer<T>.Default;
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            if (_mSet != null && _mSet.Count != Count)
            {
                _mSet = new MiniSet<T>(_array, comparer);
            }
            else
            {
                _mSet = new MiniSet<T>(Count, comparer);
                Clean();
                _mSet.AddRange(_array);
            }
            return _mSet.Contains(item);
        });
    }
    public void CopyTo(int index, T[] array, int arrayIndex, int count)
    {
        if (Capacity - index < count)
            throw new Exception("Collection too small.");
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            Array.Copy(_array, index, array, arrayIndex, count);
        });
    }
    public void ForEach(Action<T> action)
    {
        if (action == null)
            throw new Exception("Action cannot be null.");
        for (var index = 0; index < Count; ++index)
            action(_array[index]);
    }
    public void ParallelForEach(Action<T> action)
    {
        _array.AsParallel().ForAll(i =>
        {
            if (action == null)
                throw new Exception("Action cannot be null.");
            action(i);
        });
    }
    public int IndexOf(T item, int index)
    {
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            if (index > Count)
                throw new Exception("Index out of range.");
            return Array.IndexOf(_array, item, index, Count - index);
        });
    }
    public void RemoveAt(int index)
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            if ((uint) index >= (uint) Count)
                throw new Exception("Index out of range.");
            Interlocked.Decrement(ref Count);
            if (index < Count)
                Array.Copy(_array, index + 1, _array, index, Count - index);
            _array[Count] = default;
        });
    }
    public void Reverse()
    {
        Reverse(0, Count);
    }
    public void Reverse(int index, int count)
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            if (index < 0)
                throw new Exception("Index out of range.");
            if (count < 0)
                throw new Exception("Count out of range.");
            if (Count - index < count)
                throw new Exception("Invalid offset.");
            Clean();
            Array.Reverse(_array, index, count);
        });
    }
    public void Sort()
    {
        Sort(0, Count, null);
    }
    public void Sort(IComparer<T> comparer)
    {
        Sort(0, Count, comparer);
    }
    public void Sort(int index, int count, IComparer<T> comparer)
    {
        var tmpThis = this;
        tmpThis.Lock(tmpThis, () =>
        {
            if (index < 0)
                throw new Exception("Index out of range.");
            if (count < 0)
                throw new Exception("Count out of range.");
            if (Count - index < count)
                throw new Exception("Invalid offset.");
            Array.Sort(_array, index, count, comparer);
        });
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    public T[] ToArray()
    {
        Array.Resize(ref _array, Count);
        return _array;
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
}

MiniArray.cs

A Small Generic Array Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
[Serializable]
public class MiniArray<T> : IEnumerable<T>
{
    public T[] Array;
    public MiniArray() : this(101)
    {
    }
    public MiniArray(int cap)
    {
        Count = 0;
        Array = new T[cap];
    }
    public int Count
    {
        get;
        private set;
    }
    public T this[int index]
    {
        get
        {
            if (index > Array.Length)
                throw new Exception("Error: Index out of range.");
            return Array[index];
        }
        set
        {
            EnsureSize();
            Array[index] = value;
            Count++;
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator<T>(this);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator<T>(this);
    }
    private void EnsureSize()
    {
        if (Count >= Array.Length)
        {
            var NewLength = Array.Length == 0 ? 1 : Array.Length * 2;
            var newtArray = new T[NewLength];
            System.Array.Copy(Array, 0, newtArray, 0, Array.Length);
            Array = newtArray;
        }
    }
    public void Add(T item)
    {
        EnsureSize();
        Array[Count] = item;
        Count++;
    }
    public T[] ToArray()
    {
        var newtArray = new T[Count];
        System.Array.Copy(Array, 0, newtArray, 0, Count);
        return newtArray;
    }
    public IEnumerable<T> All()
    {
        for (var i = 0; i < Count; ++i)
            yield return Array[i];
    }
    public void Clean()
    {
        var newtArray = new T[Count];
        System.Array.Copy(Array, 0, newtArray, 0, Count);
        Array = newtArray;
    }
    public void Clear()
    {
        System.Array.Clear(Array, 0, Count);
        Count = 0;
    }
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Enumerator<T> : IEnumerator<T>
{
    private readonly MiniArray<T> thing;
    private          int          index;
    internal Enumerator(MiniArray<T> thing)
    {
        this.thing = thing;
        index      = 0;
        Current    = default;
    }
    public void Dispose()
    {
    }
    public bool MoveNext()
    {
        var tthing = thing;
        if (index < tthing.Count)
        {
            Current = tthing[index];
            index++;
            return true;
        }
        index   = thing.Count + 1;
        Current = default;
        return false;
    }
    public T Current
    {
        get;
        private set;
    }
    object IEnumerator.Current => Current;
    void IEnumerator.Reset()
    {
        index   = 0;
        Current = default;
    }
}

GHash128.cs

Generic 128-Bit Hash

using System;
using System.Security.Cryptography;
public class GHash128 : HashAlgorithm
{
    private readonly Int128[] table = new Int128[256];
    private          Int128   hash;
    private          Int128   k    = new Int128("129143687381477724263020268747464783");
    private          Int128   seed = new Int128("5967883051065466352865241413511");
    public GHash128()
    {
        hash     = seed;
        table[0] = k;
        Expand(table);
    }
    public override int HashSize => 128;
    public void SetSeed(Int128 s, Int128 k)
    {
        seed   = s;
        this.k = k;
        Array.Clear(table, 0, table.Length);
        table[0] = this.k;
        Expand(table);
    }
    private static void Expand(Int128[] x)
    {
        var length = x.Length;
        for (var i = 0; i < length; ++i)
        {
            Int128 n = 0;
            for (var j = 0; j < length; ++j)
                n = n ^ x[j];
            x[i] = (n << 1) | (n >> 120) | 1;
        }
    }
    public override void Initialize()
    {
        hash = seed;
    }
    protected override void HashCore(byte[] bytes, int ibStart, int cbSize)
    {
        Transform128(bytes, ibStart, cbSize);
    }
    protected override byte[] HashFinal()
    {
        return hash.ToByteArray();
    }
    public void Transform128(byte[] bytes, int ibStart, int cbSize)
    {
        if (bytes == null)
            return;
        if (ibStart >= bytes.Length || cbSize > bytes.Length)
            return;
        var i = 0;
        do
        {
            hash = (hash ^ bytes[i]) * table[bytes[i++]];
        } while (i < cbSize);
    }
}

EntropyGeneric.cs

Detect Entropy Levels from Primitive Data Arrays

using System;
using System.Collections.Generic;
public class EntropyGeneric<T>
{
    private const    double             NaturalLogOfTwo = 0.69314718055994530941723212145818;
    private readonly Dictionary<T, int> _hist           = new Dictionary<T, int>();
    private          bool               _mapStatus;
    public EntropyGeneric()
    {
        _hist.Clear();
        _mapStatus = false;
    }
    public (double entropy, int perfect) Entropy(T[] s)
    {
        if (_mapStatus)
        {
            _hist.Clear();
            _mapStatus = false;
        }
        foreach (var c in s)
            if (!_hist.ContainsKey(c))
                _hist.Add(c, 1);
            else
                _hist[c] += 1;
        _mapStatus = true;
        var e = 0.0;
        foreach (var v in _hist.Values)
        {
            if (v <= 0)
                continue;
            var r = v             / (double) s.Length;
            e -= r * (Math.Log(r) / NaturalLogOfTwo);
        }
        return (e, GetSize());
    }
    private byte[] ConvertTypeByteArray(T[] ia)
    {
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean:
                break;
            case TypeCode.Char:
                break;
            case TypeCode.SByte:
                break;
            case TypeCode.Byte:
                break;
            case TypeCode.Int16:
                break;
            case TypeCode.UInt16:
                break;
            case TypeCode.Int32:
                break;
            case TypeCode.UInt32:
                break;
            case TypeCode.Single:
                break;
            case TypeCode.String:
                break;
            case TypeCode.Decimal:
                break;
            case TypeCode.Int64:
                break;
            case TypeCode.UInt64:
                break;
            case TypeCode.Double:
                break;
            case TypeCode.DateTime:
                break;
            default:
                throw new ArgumentException("Type is not a valid primitive.");
        }
        return ia.GetBytesObject();
    }
    private int GetSize()
    {
        var size = 0;
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean:
                size = 8;
                break;
            case TypeCode.Char:
                size = 16;
                break;
            case TypeCode.SByte:
                size = 8;
                break;
            case TypeCode.Byte:
                size = 8;
                break;
            case TypeCode.Int16:
                size = 16;
                break;
            case TypeCode.UInt16:
                size = 16;
                break;
            case TypeCode.Int32:
                size = 32;
                break;
            case TypeCode.UInt32:
                size = 32;
                break;
            case TypeCode.Single:
                size = 32;
                break;
            case TypeCode.String:
                size = 32;
                break;
            case TypeCode.Decimal:
                size = 96;
                break;
            case TypeCode.Int64:
                size = 64;
                break;
            case TypeCode.UInt64:
                size = 64;
                break;
            case TypeCode.Double:
                size = 64;
                break;
            case TypeCode.DateTime:
                size = 64;
                break;
            default:
                throw new ArgumentException("Type is not a valid primitive.");
        }
        return size;
    }
}