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];
}
}
}
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]; } } }
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];
        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *