/// <summary> /// Creates a new set. /// </summary> /// <param name="tablePool">Pool from which to retrieve integer arrays.</param> /// <param name="elementPool">Pool from which to retrieve typed arrays.</param> /// <param name="initialElementPoolIndex">Initial pool index to pull the object buffer from. The size of the initial buffer will be 2^initialElementPoolIndex.</param> /// <param name="tableSizePower">Initial pool index to pull the object buffer from. The size of the initial table buffer will be 2^(initialElementPoolIndex + tableSizePower).</param> public QuickSet(BufferPool <T> elementPool, BufferPool <int> tablePool, int initialElementPoolIndex = 2, int tableSizePower = 3) { if (tableSizePower <= 0) { throw new ArgumentException("The hash table must be larger than the element array.", "tableSizePower"); } if (initialElementPoolIndex < 0) { throw new ArgumentException("Initial pool index must be nonnegative.", "initialElementPoolIndex"); } this.tablePool = tablePool; this.elementPool = elementPool; elementPoolIndex = initialElementPoolIndex; tablePoolIndex = initialElementPoolIndex + tableSizePower; Elements = elementPool.TakeFromPoolIndex(elementPoolIndex); table = tablePool.TakeFromPoolIndex(tablePoolIndex); //Correctness requires a clean table. '0' means 'not taken'. Array.Clear(table, 0, table.Length); Count = 0; tableMask = table.Length - 1; }
/// <summary> /// Creates a new set. /// </summary> /// <param name="tablePool">Pool from which to retrieve integer arrays.</param> /// <param name="keyPool">Pool from which to retrieve TKey arrays.</param> /// <param name="valuePool">Pool from which to retrieve TValue arrays.</param> /// <param name="initialElementPoolIndex">Initial pool index to pull the object buffer from. The size of the initial buffer will be 2^initialElementPoolIndex.</param> /// <param name="tableSizePower">Initial pool index to pull the object buffer from. The size of the initial table buffer will be 2^(initialElementPoolIndex + tableSizePower).</param> public QuickDictionary(BufferPool <TKey> keyPool, BufferPool <TValue> valuePool, BufferPool <int> tablePool, int initialElementPoolIndex = 2, int tableSizePower = 3) { if (tableSizePower <= 0) { throw new ArgumentException("The hash table must be larger than the element array.", "tableSizePower"); } if (initialElementPoolIndex < 0) { throw new ArgumentException("Initial pool index must be nonnegative.", "initialElementPoolIndex"); } this.tablePool = tablePool; this.keyPool = keyPool; this.valuePool = valuePool; pairPoolIndex = initialElementPoolIndex; tablePoolIndex = initialElementPoolIndex + tableSizePower; Keys = keyPool.TakeFromPoolIndex(pairPoolIndex); Values = valuePool.TakeFromPoolIndex(pairPoolIndex); table = tablePool.TakeFromPoolIndex(tablePoolIndex); //Pooled buffers are not guaranteed to be cleared. The dictionary and set require clean tables, 0 means untaken. Array.Clear(table, 0, table.Length); Count = 0; tableMask = table.Length - 1; }
/// <summary> /// Creates a new list. /// </summary> /// <param name="pool">Pool from which to retrieve typed arrays.</param> /// <param name="initialPoolIndex">Initial pool index to pull the backing array from. The size of the initial buffer will be 2^initialPoolIndex.</param> public QuickList(BufferPool <T> pool, int initialPoolIndex = 5) { this.pool = pool; poolIndex = initialPoolIndex; Elements = pool.TakeFromPoolIndex(poolIndex); count = 0; }
/// <summary> /// Creates a new queue. /// </summary> /// <param name="pool">Pool from which to retrieve typed arrays.</param> /// <param name="initialPoolIndex">Initial pool index to pull the backing array from. The size of the initial buffer will be 2^initialPoolIndex.</param> public QuickQueue(BufferPool <T> pool, int initialPoolIndex = 5) { this.pool = pool; poolIndex = initialPoolIndex; Elements = pool.TakeFromPoolIndex(poolIndex); count = 0; capacityMask = Elements.Length - 1; firstIndex = 0; lastIndex = capacityMask; //length - 1 }
public static unsafe void CreateBinnedResources(BufferPool <int> bufferPool, int maximumSubtreeCount, out int[] buffer, out MemoryRegion region, out BinnedResources resources) { int nodeCount = maximumSubtreeCount - 1; //Note alignment. Probably won't provide any actual benefit- if the CLR doesn't provide aligned memory by default, //it's highly unlikely that anything is built to expect or benefit from aligned memory (at the software level, anyway). //(And I don't think the vector types are aligned.) int bytesRequired = 16 * (3 + 3 + 1) + sizeof(BoundingBox) * (maximumSubtreeCount + 3 * nodeCount + 3 * MaximumBinCount) + 16 * (6 + 3 + 8) + sizeof(int) * (maximumSubtreeCount * 6 + nodeCount * 3 + MaximumBinCount * 8) + 16 * (1) + sizeof(Vector3) * maximumSubtreeCount + 16 * (1) + sizeof(SubtreeHeapEntry) * maximumSubtreeCount + 16 * (1) + sizeof(Node) * nodeCount; //Divide by 4 due to int. //We're using int buffers because they are the most commonly requested resource type, so the resource stands a higher chance of being reused. int poolIndex = BufferPool <int> .GetPoolIndex(bytesRequired / 4); buffer = bufferPool.TakeFromPoolIndex(poolIndex); region = new MemoryRegion(buffer); resources.BoundingBoxes = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * maximumSubtreeCount); resources.LeafCounts = (int *)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.IndexMap = (int *)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.Centroids = (Vector3 *)region.Allocate(sizeof(Vector3) * maximumSubtreeCount); resources.SubtreeHeapEntries = (SubtreeHeapEntry *)region.Allocate(sizeof(SubtreeHeapEntry) * maximumSubtreeCount); resources.StagingNodes = (Node *)region.Allocate(sizeof(Node) * nodeCount); resources.SubtreeBinIndicesX = (int *)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.SubtreeBinIndicesY = (int *)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.SubtreeBinIndicesZ = (int *)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.TempIndexMap = (int *)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.ALeafCountsX = (int *)region.Allocate(sizeof(int) * nodeCount); resources.ALeafCountsY = (int *)region.Allocate(sizeof(int) * nodeCount); resources.ALeafCountsZ = (int *)region.Allocate(sizeof(int) * nodeCount); resources.AMergedX = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * nodeCount); resources.AMergedY = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * nodeCount); resources.AMergedZ = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * nodeCount); resources.BinBoundingBoxesX = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * MaximumBinCount); resources.BinBoundingBoxesY = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * MaximumBinCount); resources.BinBoundingBoxesZ = (BoundingBox *)region.Allocate(sizeof(BoundingBox) * MaximumBinCount); resources.BinLeafCountsX = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinLeafCountsY = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinLeafCountsZ = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsX = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsY = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsZ = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinStartIndices = (int *)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsSecondPass = (int *)region.Allocate(sizeof(int) * MaximumBinCount); }
/// <summary> /// Creates a new set. /// </summary> /// <param name="tablePool">Pool from which to retrieve integer arrays.</param> /// <param name="elementPool">Pool from which to retrieve typed arrays.</param> /// <param name="initialElementPoolIndex">Initial pool index to pull the object buffer from. The size of the initial buffer will be 2^initialElementPoolIndex.</param> /// <param name="tableSizePower">Initial pool index to pull the object buffer from. The size of the initial table buffer will be 2^(initialElementPoolIndex + tableSizePower).</param> public QuickSet(BufferPool <T> elementPool, BufferPool <int> tablePool, int initialElementPoolIndex = 2, int tableSizePower = 5) { if (tableSizePower <= 0) { throw new ArgumentException("The hash table must be larger than the element array.", "tableSizePower"); } if (initialElementPoolIndex < 0) { throw new ArgumentException("Initial pool index must be nonnegative.", "initialElementPoolIndex"); } this.tablePool = tablePool; this.elementPool = elementPool; elementPoolIndex = initialElementPoolIndex; tablePoolIndex = initialElementPoolIndex + tableSizePower; Elements = elementPool.TakeFromPoolIndex(elementPoolIndex); table = tablePool.TakeFromPoolIndex(tablePoolIndex); count = 0; tableMask = table.Length - 1; }
/// <summary> /// Creates a new set. /// </summary> /// <param name="tablePool">Pool from which to retrieve integer arrays.</param> /// <param name="keyPool">Pool from which to retrieve TKey arrays.</param> /// <param name="valuePool">Pool from which to retrieve TValue arrays.</param> /// <param name="initialElementPoolIndex">Initial pool index to pull the object buffer from. The size of the initial buffer will be 2^initialElementPoolIndex.</param> /// <param name="tableSizePower">Initial pool index to pull the object buffer from. The size of the initial table buffer will be 2^(initialElementPoolIndex + tableSizePower).</param> public QuickDictionary(BufferPool <TKey> keyPool, BufferPool <TValue> valuePool, BufferPool <int> tablePool, int initialElementPoolIndex = 2, int tableSizePower = 3) { if (tableSizePower <= 0) { throw new ArgumentException("The hash table must be larger than the element array.", "tableSizePower"); } if (initialElementPoolIndex < 0) { throw new ArgumentException("Initial pool index must be nonnegative.", "initialElementPoolIndex"); } this.tablePool = tablePool; this.keyPool = keyPool; this.valuePool = valuePool; pairPoolIndex = initialElementPoolIndex; tablePoolIndex = initialElementPoolIndex + tableSizePower; Keys = keyPool.TakeFromPoolIndex(pairPoolIndex); Values = valuePool.TakeFromPoolIndex(pairPoolIndex); table = tablePool.TakeFromPoolIndex(tablePoolIndex); count = 0; tableMask = table.Length - 1; }
public static unsafe void CreateBinnedResources(BufferPool<int> bufferPool, int maximumSubtreeCount, out int[] buffer, out MemoryRegion region, out BinnedResources resources) { int nodeCount = maximumSubtreeCount - 1; //Note alignment. Probably won't provide any actual benefit- if the CLR doesn't provide aligned memory by default, //it's highly unlikely that anything is built to expect or benefit from aligned memory (at the software level, anyway). //(And I don't think the vector types are aligned.) int bytesRequired = 16 * (3 + 3 + 1) + sizeof(BoundingBox) * (maximumSubtreeCount + 3 * nodeCount + 3 * MaximumBinCount) + 16 * (6 + 3 + 8) + sizeof(int) * (maximumSubtreeCount * 6 + nodeCount * 3 + MaximumBinCount * 8) + 16 * (1) + sizeof(Vector3) * maximumSubtreeCount + 16 * (1) + sizeof(SubtreeHeapEntry) * maximumSubtreeCount + 16 * (1) + sizeof(Node) * nodeCount; //Divide by 4 due to int. //We're using int buffers because they are the most commonly requested resource type, so the resource stands a higher chance of being reused. int poolIndex = BufferPool<int>.GetPoolIndex(bytesRequired / 4); buffer = bufferPool.TakeFromPoolIndex(poolIndex); region = new MemoryRegion(buffer); resources.BoundingBoxes = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * maximumSubtreeCount); resources.LeafCounts = (int*)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.IndexMap = (int*)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.Centroids = (Vector3*)region.Allocate(sizeof(Vector3) * maximumSubtreeCount); resources.SubtreeHeapEntries = (SubtreeHeapEntry*)region.Allocate(sizeof(SubtreeHeapEntry) * maximumSubtreeCount); resources.StagingNodes = (Node*)region.Allocate(sizeof(Node) * nodeCount); resources.SubtreeBinIndicesX = (int*)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.SubtreeBinIndicesY = (int*)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.SubtreeBinIndicesZ = (int*)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.TempIndexMap = (int*)region.Allocate(sizeof(int) * maximumSubtreeCount); resources.ALeafCountsX = (int*)region.Allocate(sizeof(int) * nodeCount); resources.ALeafCountsY = (int*)region.Allocate(sizeof(int) * nodeCount); resources.ALeafCountsZ = (int*)region.Allocate(sizeof(int) * nodeCount); resources.AMergedX = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * nodeCount); resources.AMergedY = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * nodeCount); resources.AMergedZ = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * nodeCount); resources.BinBoundingBoxesX = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * MaximumBinCount); resources.BinBoundingBoxesY = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * MaximumBinCount); resources.BinBoundingBoxesZ = (BoundingBox*)region.Allocate(sizeof(BoundingBox) * MaximumBinCount); resources.BinLeafCountsX = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinLeafCountsY = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinLeafCountsZ = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsX = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsY = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsZ = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinStartIndices = (int*)region.Allocate(sizeof(int) * MaximumBinCount); resources.BinSubtreeCountsSecondPass = (int*)region.Allocate(sizeof(int) * MaximumBinCount); }