Non-Linear Array Size Adjustment Class
using System;
using System.Collections.Generic;
using Microsoft.VisualBasic.Devices;
public class SizeHelper<T>
{
private static readonly FixedIntXPrimality bp = new FixedIntXPrimality(64);
private readonly int AllocatedSizeLimit;
public int[] Curve;
private int Resizes;
public SizeHelper()
{
var measure = new MeasureSize<T>();
var sizeOfOne = measure.GetByteSize();
var am = new ComputerInfo().AvailablePhysicalMemory;
AllocatedSizeLimit = (int) ((long) am / sizeOfOne);
}
public int GetNewSize(int currentSize)
{
Resizes++;
if (Curve == null)
BuildCurve(currentSize);
foreach (var v in Curve)
if (v > currentSize)
return v;
var nv = GetNextValue(currentSize);
return nv != -1 ? nv : int.MaxValue;
}
private int GetNextValue(int currentValue)
{
for (var value = currentValue | 1; value < AllocatedSizeLimit; value += 16384)
{
if (value < 0)
break;
if (bp.IsPrime(value))
return value + 1;
}
return -1;
}
private void BuildCurve(int Size)
{
int Sizer(int oldSize)
{
try
{
oldSize = (int) (uint) oldSize;
var log = Math.Log(oldSize);
var inv = 1.0 / log * 4;
var newSize = oldSize * (1.0 + inv);
return (int) (uint) newSize;
}
catch
{
return AllocatedSizeLimit;
}
}
var curlst = new List<int>();
var value = Size | 1;
do
{
value = Sizer(value);
if (value < 0)
break;
if (value < AllocatedSizeLimit)
curlst.Add(value);
} while (value < AllocatedSizeLimit);
Curve = curlst.ToArray();
var dl = new List<int>();
var last = 0;
for (var i = 0; i < Curve.Length; ++i)
{
if (i > 0)
last = Curve[i - 1];
var v = Curve[i];
dl.Add(v - last);
}
var str = "";
foreach (var v in dl)
str += $"{v},";
}
}