Exemple #1
0
        /// <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;
        }
Exemple #2
0
        /// <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;
        }
Exemple #3
0
        /// <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;
        }
Exemple #4
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);
        }
Exemple #6
0
        /// <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);
        }