CcArray.cs

Concurrent Array (Ordered) Class with Indexing, and without Blocking

Updated: Aug-2,2021

        RandomBigInt rng  = new RandomBigInt(64);
        ulong[]      sla1 = Enumerable.Range(0, 1000000).AsParallel().WithDegreeOfParallelism(10).Select(i => (ulong)rng.Next()).ToArray();
        CcArray<ulong> ccl = new CcArray<ulong>(1000000);

Example 1:       
        Parallel.ForEach(sla1, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (v, p, i) =>
        {
            ccl.Add(v, (int)i);
        });

Example 2:
        Parallel.For(0,sla1.Length,i=>
        {
            ccl.Add(sla1[i], (int)i);
        });

Example 3:
        sla1.AsEnumerable().Select( (v,i)=> new {value=v,index=i}).AsParallel().WithDegreeOfParallelism(10).ForAll(x=>
        {
            ccl[x.index] = x.value;
        });

       Var asa = new ulong[1000000];
       for (var i = 0; i < 1000000; ++i)
          asa[i] = ccl[i];
       var exc = sla1.Except(asa).ToArray();
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
public class CcArray<T> : IEnumerable<T>
{
    private readonly int           _size;
    private volatile int           _activeThreadPosition;
    private volatile int[]         _activeThreads;
    private volatile IntSet18<T>[] _array;
    public volatile  int           NumberOfActiveThreads;
    public CcArray(int size)
    {
        ThreadPool.GetMaxThreads(out var nW, out var nI);
        _array                = new IntSet18<T>[nW];
        _size                 = size;
        NumberOfActiveThreads = 0;
        _activeThreadPosition = 0;
        _activeThreads        = new int[Environment.ProcessorCount];
        _activeThreads.Fill(-1);
    }
    public T this[int index]
    {
        get
        {
            var (idx, trd) = FindIndex(index);
            return idx != -1 ? _array[trd].Slots[idx].Value : default;
        }
        set
        {
            var (idx, trd) = FindIndex(index);
            if (idx != -1)
                _array[trd].Slots[idx].Value = value;
            else Add(value, index);
        }
    }
    public int Count
    {
        get
        {
            if (_activeThreads == null)
                throw new Exception("Initialization has not completed. Note: The constructor cannot be void.");
            var totalCount = 0;
            for (var i = 0; i < _activeThreads.Length; ++i)
                if (_activeThreads[i] != -1)
                    if (_array[_activeThreads[i]].Allocated)
                        totalCount += _array[_activeThreads[i]].Count;
            return totalCount;
        }
    }
    public IEnumerator<T> GetEnumerator()
    {
        return GetEnum();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnum();
    }
    public void Add(T item, int index, bool updateValue = false)
    {
        if (_activeThreads == null)
            throw new Exception("Initialization has not completed. Note: The constructor cannot be void.");
        var id = ProcessThread();
        var (idx, trd) = FindIndex(index);
        if (idx == -1)
            _array[id].Add(index, item);
        else if (updateValue)
            _array[trd].Slots[idx].Value = item;
    }
    public (int idx, int trd) FindIndex(int index)
    {
        if (_activeThreads == null)
            throw new Exception("Initialization has not completed. Note: The constructor cannot be void.");
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]].Allocated)
                {
                    var idx = _array[_activeThreads[i]].FindKey(index);
                    if (idx != -1)
                        return (idx, _activeThreads[i]);
                }
        return (-1, -1);
    }
    private int ProcessThread()
    {
        var id = Thread.CurrentThread.ManagedThreadId;
        if (!_array[id].Allocated)
        {
            Interlocked.Increment(ref NumberOfActiveThreads);
            _array[id] = new IntSet18<T>(_size / NumberOfActiveThreads);
            if (_activeThreadPosition >= _activeThreads.Length)
            {
                var newActiveThreads = new int[_activeThreads.Length << 1];
                newActiveThreads.Fill(-1);
                for (var i = 0; i < _activeThreads.Length; ++i)
                    if (_activeThreads[i] != -1)
                        newActiveThreads[i] = _activeThreads[i];
                _activeThreads = newActiveThreads;
            }
            _activeThreads[_activeThreadPosition] = id;
            Interlocked.Increment(ref _activeThreadPosition);
        }
        return id;
    }
    public bool Contains(T item)
    {
        if (_activeThreads == null)
            throw new Exception("Initialization has not completed. Note: The constructor cannot be void.");
        var eComparer = EqualityComparer<T>.Default;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]].Allocated)
                    for (var j = 0; j < _array[_activeThreads[i]].Count; ++j)
                        if (eComparer.Equals(_array[_activeThreads[i]].Slots[j].Value, item))
                            return true;
        return false;
    }
    public T[] ToArray()
    {
        if (_activeThreads == null)
            throw new Exception("Initialization has not completed. Note: The constructor cannot be void.");
        var outputArray = new T[Count];
        var ptr         = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]].Allocated)
                    foreach (var v in _array[_activeThreads[i]])
                        outputArray[ptr++] = v.Value;
        return outputArray;
    }
    private IEnumerator<T> GetEnum()
    {
        var array = ToArray();
        foreach (var i in array)
            yield return i;
    }
    [DebuggerDisplay("Count = {" + nameof(Count) + "}")]
    internal struct IntSet18<T1>
    {
        private  int[]  _buckets;
        internal Slot[] Slots;
        public   bool   Allocated;
        public IntSet18(int size)
        {
            _buckets  = new int[size];
            Slots     = new Slot[size];
            Count     = 0;
            Allocated = true;
        }
        public int Count
        {
            get;
            private set;
        }
        public IEnumerator<KeyValuePair<int, T1>> GetEnumerator()
        {
            for (var i = 0; i < Count; i++)
                if (Slots[i].Key >= 0)
                    yield return new KeyValuePair<int, T1>(Slots[i].Key, Slots[i].Value);
        }
        public bool Add(int key, T1 value)
        {
            if (FindKey(key) != -1)
                return true;
            if (Count >= Slots.Length)
                Resize();
            var pos = key % _buckets.Length;
            Slots[Count].Next  = _buckets[pos] - 1;
            Slots[Count].Key   = key;
            Slots[Count].Value = value;
            _buckets[pos]      = Count + 1;
            ++Count;
            return false;
        }
        private void Resize()
        {
            var newSize    = _buckets.Length + _buckets.Length / 4 * 3;
            var newSlots   = new Slot[newSize];
            var newBuckets = new int[newSize];
            var newCount   = 0;
            var en         = GetEnumerator();
            while (en.MoveNext())
            {
                var key   = en.Current.Key;
                var value = en.Current.Value;
                var pos   = key % newBuckets.Length;
                newSlots[newCount].Next  = newBuckets[pos] - 1;
                newSlots[newCount].Key   = key;
                newSlots[newCount].Value = value;
                newBuckets[pos]          = newCount + 1;
                ++newCount;
            }
            Slots    = newSlots;
            _buckets = newBuckets;
            Count    = newCount;
        }
        public int FindKey(int key)
        {
            for (var position = _buckets[key % _buckets.Length] - 1; position >= 0; position = Slots[position].Next)
                if (Equals(Slots[position].Key, key))
                    return position;
            return -1;
        }
        internal struct Slot
        {
            public int Next;
            public int Key;
            public T1  Value;
        }
    }
}

CcDictionary.cs

Concurrent Dictionary Class without Blocking

Updated: July-27,2021

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
public class CcDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
    private readonly int                     _size;
    private volatile int[]                   _activeThreads;
    private          DicA<TKey, TValue>[]    _array;
    private volatile int                     _bP;
    internal         IEqualityComparer<TKey> _comparer;
    public volatile  int                     NumberOfActiveThreads;
    public CcDictionary() : this(1024, null)
    {
    }
    public CcDictionary(int size) : this(size, null)
    {
    }
    public CcDictionary(int size, IEqualityComparer<TKey> comparer)
    {
        ThreadPool.GetMaxThreads(out var nW, out var nI);
        _array                = new DicA<TKey, TValue>[nW];
        _size                 = size;
        NumberOfActiveThreads = 0;
        _bP                   = 0;
        _activeThreads        = new int[Environment.ProcessorCount];
        _activeThreads.Fill(-1);
        if (comparer == null)
            _comparer = EqualityComparer<TKey>.Default;
        else
            _comparer = comparer;
    }
    public CcDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, int concurrencyLevel = 0)
    {
        ThreadPool.GetMaxThreads(out var nW, out var nI);
        _array = new DicA<TKey, TValue>[nW];
        var col = collection.ToList();
        _size                 = col.Count;
        NumberOfActiveThreads = 0;
        _bP                   = 0;
        _activeThreads        = new int[Environment.ProcessorCount];
        _activeThreads.Fill(-1);
        _comparer = EqualityComparer<TKey>.Default;
        var ccl = Environment.ProcessorCount;
        if (concurrencyLevel != 0)
            ccl = concurrencyLevel;
        col.AsParallel().WithDegreeOfParallelism(ccl).ForAll(i =>
        {
            Add(i.Key, i.Value);
        });
    }
    public int Count
    {
        get
        {
            var totalCount = 0;
            for (var i = 0; i < _activeThreads.Length; ++i)
                if (_activeThreads[i] != -1)
                    if (_array[_activeThreads[i]] != null)
                        totalCount += _array[_activeThreads[i]].Count;
            return totalCount;
        }
    }
    public TValue this[TKey key]
    {
        get
        {
           ProcessThread();
            var rv = FindKey(key);
            return rv.idx != -1 ? _array[rv.trd][key] : default;
        }
        set => Add(key, value, true);
    }
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return GetEnum();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnum();
    }
    public bool TryGetValue(TKey key, out TValue value)
    {
        var (idx, trd) = FindKey(key);
        if (idx == -1)
        {
            value = default;
            return false;
        }
        value = _array[trd][key];
        return true;
    }
    public void Clear()
    {
        ThreadPool.GetMaxThreads(out var nW, out var nI);
        _array                = new DicA<TKey, TValue>[nW];
        NumberOfActiveThreads = 0;
        _bP                   = 0;
        _activeThreads        = new int[Environment.ProcessorCount];
        _activeThreads.Fill(-1);
    }
    public void AddRange(IEnumerable<KeyValuePair<TKey, TValue>> collection, int concurrencyLevel = 0)
    {
        var ccl = Environment.ProcessorCount;
        if (concurrencyLevel != 0)
            ccl = concurrencyLevel;
        collection.AsParallel().WithDegreeOfParallelism(ccl).ForAll(i =>
        {
            Add(i.Key, i.Value);
        });
    }
    public void Add(TKey key, TValue value, bool updateValue = false)
    {
        var id  = ProcessThread();
        var idx = FindKey(key);
        if (idx.idx == -1)
            _array[id].Add(key, value);
        else if (updateValue)
            _array[idx.trd].Values[idx.idx] = value;
    }
    private int ProcessThread()
    {
        var id = Thread.CurrentThread.ManagedThreadId;
        if (_array[id] == null)
        {
            _array[id] = new DicA<TKey, TValue>(_size, _comparer);
            Interlocked.Increment(ref NumberOfActiveThreads);
            if (_bP >= _activeThreads.Length)
            {
                var nAtA = new int[_activeThreads.Length << 1];
                nAtA.Fill(-1);
                for (var i = 0; i < _activeThreads.Length; ++i)
                    if (_activeThreads[i] != -1)
                        nAtA[i] = _activeThreads[i];
                _activeThreads = nAtA;
            }
            _activeThreads[_bP] = id;
            Interlocked.Increment(ref _bP);
        }
        return id;
    }
    public bool TryAdd(TKey key, TValue value)
    {
        Add(key, value);
        return true;
    }
    public bool ContainsKey(TKey key)
    {
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                    if (_array[_activeThreads[i]].ContainsKey(key))
                        return true;
        return false;
    }
    public bool ContainsValue(TValue value)
    {
        var eComparer = EqualityComparer<TValue>.Default;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                    for (var j = 0; j < _array[_activeThreads[i]].Count; ++j)
                        if (eComparer.Equals(_array[_activeThreads[i]].Values[j], value))
                            return true;
        return false;
    }
    public (int idx, int trd) FindKey(TKey key)
    {
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                {
                    var idx = _array[_activeThreads[i]].FindKeyIndex(key);
                    if (idx != -1)
                        return (idx, _activeThreads[i]);
                }
        return (-1, -1);
    }
    public bool Remove(TKey key)
    {
        var (idx, trd) = FindKey(key);
        if (idx == -1)
            return false;
        _array[_activeThreads[trd]].Remove(key);
        return true;
    }
    private IEnumerator<KeyValuePair<TKey, TValue>> GetEnum()
    {
        foreach (var i in ToArray())
            yield return new KeyValuePair<TKey, TValue>(i.Key, i.Value);
    }
    public KeyValuePair<TKey, TValue>[] ToArray()
    {
        var totalCount = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                    totalCount += _array[_activeThreads[i]].Count;
        var ta  = new KeyValuePair<TKey, TValue>[totalCount];
        var ptr = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                    foreach (var v in _array[_activeThreads[i]])
                        ta[ptr++] = new KeyValuePair<TKey, TValue>(v.Key, v.Value);
        return ta;
    }
    public class DicA<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        public MSet15<TKey> Keys;
        public int          Resizes;
        public TValue[]     Values;
        public DicA() : this(101, EqualityComparer<TKey>.Default)
        {
        }
        public DicA(int size) : this(size, EqualityComparer<TKey>.Default)
        {
        }
        public DicA(int size, IEqualityComparer<TKey> comparer)
        {
            if (comparer == null)
                comparer = EqualityComparer<TKey>.Default;
            Keys          = new MSet15<TKey>(size);
            Values        = new TValue[size];
            Keys.Comparer = comparer;
        }
        public DicA(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer = null)
        {
            if (comparer == null)
                comparer = EqualityComparer<TKey>.Default;
            Keys.Comparer = comparer;
            foreach (var kp in collection)
                Add(kp.Key, kp.Value);
        }
        public int Count => Keys.Count;
        public TValue this[TKey key]
        {
            get
            {
                var pos = Keys.FindEntry(key);
                return pos == -1 ? default : Values[pos];
            }
            set => Add(key, value);
        }
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            for (var i = 0; i < Count; i++)
                if (Keys.Slots[i].HashCode > 0)
                    yield return new KeyValuePair<TKey, TValue>(Keys.Slots[i].Value, Values[i]);
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        public bool Add(TKey key, TValue value)
        {
            if (!Keys.Add(key))
            {
                if (Values.Length != Keys.Slots.Length)
                {
                    var nValues = new TValue[Keys.Slots.Length];
                    Array.Copy(Values, nValues, Values.Length);
                    Values = nValues;
                    Resizes++;
                }
                Values[Keys.Position] = value;
                return false;
            }
            Values[Keys.Position] = value;
            return true;
        }
        public void Remove(TKey key)
        {
            var pos = Keys.FindEntry(key);
            if (pos != -1)
            {
                Values[pos] = default;
                Keys.Remove(key);
            }
        }
        public bool ContainsKey(TKey key)
        {
            return Keys.FindEntry(key) != -1;
        }
        public int FindKeyIndex(TKey key)
        {
            return Keys.FindEntry(key);
        }
    }
}

CcHashSet.cs

Concurrent HashSet Class without Blocking

Updated: July-23,2021

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
public class CcHashSet<T> : IEnumerable
{
    private readonly HashSet<T>[]         _array;
    private readonly int                  _size;
    private volatile int[]                _activeThreads;
    private volatile int                  _bP;
    private readonly IEqualityComparer<T> _comparer;
    public volatile  int                  NumberOfActiveThreads;
    public CcHashSet() : this(1024, null)
    {
    }
    public CcHashSet(int size) : this(size, null)
    {
    }
    public CcHashSet(int size, IEqualityComparer<T> comparer)
    {
        if (comparer == null)
            _comparer = EqualityComparer<T>.Default;
        else
            _comparer = comparer;
        ThreadPool.GetMaxThreads(out var nW, out var nI);
        _array                = new HashSet<T>[nW];
        _size                 = size;
        NumberOfActiveThreads = 0;
        _bP                   = 0;
        _activeThreads        = new int[Environment.ProcessorCount];
        _activeThreads.Fill(-1);
    }
    public int Count
    {
        get
        {
            var totalCount = 0;
            for (var i = 0; i < _activeThreads.Length; ++i)
                if (_activeThreads[i] != -1)
                    if (_array[_activeThreads[i]] != null)
                        totalCount += _array[_activeThreads[i]].Count;
            return totalCount;
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnum();
    }
    public IEnumerator<T> GetEnumerator()
    {
        return GetEnum();
    }
    public void Add(T item)
    {
        var id = Thread.CurrentThread.ManagedThreadId;
        if (_array[id] == null)
        {
            _array[id] = new HashSet<T>(_size, _comparer);
            Interlocked.Increment(ref NumberOfActiveThreads);
            if (_bP >= _activeThreads.Length)
            {
                var nAtA = new int[_activeThreads.Length << 1];
                nAtA.Fill(-1);
                for (var i = 0; i < _activeThreads.Length; ++i)
                    if (_activeThreads[i] != -1)
                        nAtA[i] = _activeThreads[i];
                _activeThreads = nAtA;
            }
            _activeThreads[_bP] = id;
            Interlocked.Increment(ref _bP);
        }
        if (!Contains(item))
            _array[id].Add(item);
    }
    public bool Contains(T item)
    {
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                    if (_array[_activeThreads[i]].Contains(item))
                        return true;
        return false;
    }
    public IEnumerator<T> GetEnum()
    {
        var arr = ToArray();
        foreach (var i in arr)
            yield return i;
    }
    public T[] ToArray()
    {
        var totalCount = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                    totalCount += _array[_activeThreads[i]].Count;
        var ta  = new T[totalCount];
        var ptr = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]] != null)
                {
                    var it = _array[_activeThreads[i]].ToArray();
                    for (var j = 0; j < it.Length; ++j)
                        ta[ptr++] = it[j];
                }
        return ta;
    }
}

CcCollection.cs

Concurrent Collection Class without Blocking

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
public class CcCollection<T> : IEnumerable<T>
{
    private readonly IntA<T>[] _array;
    private readonly int       _size;
    private volatile int[]     _activeThreads;
    private volatile int       _bP;
    public volatile  int       NumberOfActiveThreads;
    public CcCollection() : this(1024)
    {
    }
    public CcCollection(int size)
    {
        ThreadPool.GetMaxThreads(out var nW, out var nI);
        _array                = new IntA<T>[nW];
        _size                 = size;
        NumberOfActiveThreads = 0;
        _bP                   = 0;
        _activeThreads        = new int[Environment.ProcessorCount];
        _activeThreads.Fill(-1);
    }
    public int Count
    {
        get
        {
            var totalCount = 0;
            for (var i = 0; i < _activeThreads.Length; ++i)
                if (_activeThreads[i] != -1)
                    if (_array[_activeThreads[i]].Allocated)
                        totalCount += _array[_activeThreads[i]].Count;
            return totalCount;
        }
    }
    public IEnumerator<T> GetEnumerator()
    {
        return GetEnum();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnum();
    }
    public void Add(T item)
    {
        var id = Thread.CurrentThread.ManagedThreadId;
        if (!_array[id].Allocated)
        {
            _array[id] = new IntA<T>(_size);
            Interlocked.Increment(ref NumberOfActiveThreads);
            if (_bP >= _activeThreads.Length)
            {
                var nAtA = new int[_activeThreads.Length << 1];
                nAtA.Fill(-1);
                for (var i = 0; i < _activeThreads.Length; ++i)
                    if (_activeThreads[i] != -1)
                        nAtA[i] = _activeThreads[i];
                _activeThreads = nAtA;
            }
            _activeThreads[_bP] = id;
            Interlocked.Increment(ref _bP);
        }
        _array[id].Add(item);
    }
    public IEnumerator<T> GetEnum()
    {
        var arr = ToArray();
        foreach (var i in arr)
            yield return i;
    }
    public T[] ToArray()
    {
        var totalCount = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]].Allocated)
                    totalCount += _array[_activeThreads[i]].Count;
        var ta  = new T[totalCount];
        var ptr = 0;
        for (var i = 0; i < _activeThreads.Length; ++i)
            if (_activeThreads[i] != -1)
                if (_array[_activeThreads[i]].Allocated)
                {
                    var it = _array[_activeThreads[i]].ToArray();
                    for (var j = 0; j < it.Length; ++j)
                        ta[ptr++] = it[j];
                }
        return ta;
    }
    internal struct IntA<T> : IEnumerable<T>
    {
        private T[]  _array;
        public  bool Allocated;
        public IntA(int cap)
        {
            Count     = 0;
            _array    = new T[cap];
            Allocated = true;
        }
        public int Count
        {
            get;
            private set;
        }
        public int Length => _array.Length;
        public T this[int index]
        {
            get
            {
                if (index > _array.Length)
                    throw new Exception("Error: Index out of range.");
                return _array[index];
            }
            set
            {
                if (index > _array.Length)
                    throw new Exception("Error: Index out of range.");
                _array[index] = value;
            }
        }
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        public void Add(T item)
        {
            if (Count >= _array.Length)
                Array.Resize(ref _array, _array.Length << 1);
            _array[Count] = item;
            Count++;
        }
        public T[] ToArray()
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            return newtArray;
        }
        public void Trim()
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            _array = newtArray;
        }
        public void Clear()
        {
            Array.Clear(_array, 0, Count);
            Count = 0;
        }
        public void Zero()
        {
            _array = Array.Empty<T>();
            Count  = 0;
        }
        public IEnumerator<T> GetEnumerator()
        {
            return GetEnum();
        }
        public IEnumerator<T> GetEnum()
        {
            for (var i = 0; i < Count; i++)
                yield return _array[i];
        }
    }
}

Windows 11 Enable New Boot Animation

This process will either enable the new boot animation.

1). Open Regedit winkey + R
2). Enter “RegEdit” (Enter)
3). Navigate to “HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control”
4). Right Click on ‘Control’ and then “New” -> “Key”
5). The new Name for this key should be “BootControl”
6). Right Click on the new key ‘BootControl’ -> “New” -> Dword(32-Bit)
7). The new Name value should be “BootProgressAnimation”
8). Double click to edit: 1 New boot animation, 0 old boot animation.
9). Exit Regedit, and Open Task Manager.
10). In the “Processes” tab find “Windows Explorer” -> Right Click choose “End Task”

This will re-start Explorer and re-load the system using the new Registry settings.

Windows 11 Use Windows 10 File Explorer

This will allow the use of the old Windows 10 style file explorer in Windows 11.

1). Open Regedit winkey + R
2). Enter “RegEdit” (Enter)
3). Navigate to “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced”
4). Right Click “New” Dword(32-Bit)
5). The new Name value should be “SeparateProcess”
7). Double click to edit: 1 Windows 10 style, 0 Windows 11 style.
8). Exit Regedit, and Open Task Manager.
9). In the “Processes” tab find “Windows Explorer” -> Right Click choose “End Task”

This will re-start Explorer and re-load the system using the new Registry settings.

Note: Always backup the registry before editing.

Windows 11 Move Taskbar to Top

This will move the Windows 11 Taskbar from its default location (bottom) to the Top of the screen.

1). Open Regedit winkey + R
2). Enter “RegEdit” (Enter)
3). Navigate to “HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3”
4). Double click “Settings” REG_BINARY to edit.
5). You will see 6 rows and 8 columns. The first row is: 30 00 00 00 FE FF FF FF
and the second row is: 7A F4 00 00 *01 00 00 00
6). The * indicates the value to edit. Place the cursor just beyond the 01 and backspace to delete it. Enter 03 in its place.
7). Exit Regedit, and Open Task Manager.
8). In the “Processes” tab find “Windows Explorer” -> Right Click choose “End Task”

This will re-start Explorer and re-load the system using the new Registry settings. To place the Taskbar back on the bottom, change the 03 back to a 01 and and repeat steps 8 and 9.

Note: Always backup the registry before editing.

Windows 11 Change Taskbar Size

This will allow you to change Windows 11 Taskbar size.

1). Open Regedit winkey + R
2). Enter “RegEdit” (Enter)
3). Navigate to “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced”
4). Right Click “New” Dword(32-Bit)
5). The new Name value should be “TaskbarSi”
6). Double click to edit: 0 for small, 1 for standard, 2 for Large
7). Exit Regedit, and Open Task Manager.
8). In the “Processes” tab find “Windows Explorer” -> Right Click choose “End Task”

This will re-start Explorer and re-load the system using the new Registry settings.

Note: Always backup the registry before editing.

Windows 11 Tray Icons Fix

This is a fix for the mess that is the Windows 11 system tray if you have upgraded from an existing Windows 10 install.

1). Open Regedit winkey + R
2). Enter “RegEdit” (Enter)
3). Navigate to “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer”
4). Find key “EnableAutoTray”, type= reg_dword
5). Modify the value from “0” (Show) to “1” (Hide).
6). Exit Regedit, and Open Task Manager.
7). In the “Processes” tab find “Windows Explorer” -> Right Click choose “End Task”

This will re-start Explorer and re-load the system tray using the new Registry setting.

Note: Always backup the registry before editing.

SegmentedArray.cs

Segmented Array Class

I wrote this array class while investigating the error curve in Prime Number Theorem. I wanted to avoid using blocking while using parallel invoke, while using as little memory as possible.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
public struct SegmentedArray<T>
{
    private readonly IntA<T>[] _array;
    private readonly int       _size;
    public SegmentedArray(int length, int size)
    {
        _array = new IntA<T>[16];
        _size  = size;
    }
    public void Add(T item, int index, long range, long total)
    {
        if (!_array[index].Allocated)
            _array[index] = new IntA<T>(_size);
        var density = (float)_array[index].Count / range;
        var ssic    = total                      * density;
        _array[index].Add(item, (int)ssic);
    }
    public T[] ToArray()
    {
        var totalCount = 0;
        for (var i = 0; i < 16; ++i)
            if (_array[i].Allocated)
                totalCount += _array[i].Count;
        var ta  = new T[totalCount];
        var ptr = 0;
        for (var i = 0; i < 16; ++i)
            if (_array[i].Allocated)
            {
                var it = _array[i].ToArray();
                _array[i].Zero();
                for (var j = 0; j < it.Length; ++j)
                    ta[ptr++] = it[j];
            }
        return ta;
    }
    [DebuggerDisplay("Count = {Count}")]
    internal struct IntA<T> : IEnumerable<T>
    {
        internal T[]  _array;
        internal bool Allocated;
        public IntA(int cap)
        {
            Count     = 0;
            _array    = new T[cap];
            Allocated = true;
        }
        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
            {
                if (index > _array.Length)
                    throw new Exception("Error: Index out of range.");
                _array[index] = value;
            }
        }
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        public void Add(T item, int suggestedSize)
        {
            if (Count >= _array.Length)
                Array.Resize(ref _array, suggestedSize);
            _array[Count] = item;
            Count++;
        }
        public T[] ToArray()
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            return newtArray;
        }
        public void Clean()
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            _array = newtArray;
        }
        public void Clear()
        {
            Array.Clear(_array, 0, Count);
            Count = 0;
        }
        public void Zero()
        {
            _array = Array.Empty<T>();
            Count  = 0;
        }
        public IEnumerator<T> GetEnumerator()
        {
            return GetEnum();
        }
        public IEnumerator<T> GetEnum()
        {
            for (var i = 0; i < Count; i++)
                yield return _array[i];
        }
    }
}