< Summary

Class:GDX.Collections.Generic.CoalesceArray[T]
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Collections/Generic/CoalesceArray.cs
Covered lines:0
Uncovered lines:77
Coverable lines:77
Total lines:156
Line coverage:0% (0 of 77)
Covered branches:0
Total branches:0
Covered methods:0
Total methods:9
Method coverage:0% (0 of 9)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
CoalesceArray(...)0%42600%
GetBucket(...)0%2100%
GetBucketCount()0%2100%
GetBucketLocation(...)0%2100%
Resize(...)0%42600%

File(s)

./Packages/com.dotbunny.gdx/GDX/Collections/Generic/CoalesceArray.cs

#LineLine coverage
 1// Copyright (c) 2020-2024 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System.Runtime.CompilerServices;
 6using Unity.Collections.LowLevel.Unsafe;
 7using Unity.Mathematics;
 8
 9namespace GDX.Collections.Generic
 10{
 11    /// <summary>
 12    ///     Multiple arrays acting as one uniform coalesced array.
 13    /// </summary>
 14    /// <remarks>Stores a maximum of 18,446,744,073,709,551,615 elements.</remarks>
 15    /// <typeparam name="T">The type of data to be stored.</typeparam>
 16    public struct CoalesceArray<T>
 17    {
 18        const ulong k_MaxByteSize = 2147483648;
 19
 20        /// <summary>
 21        ///     The internal arrays storage
 22        /// </summary>
 23        SimpleList<T[]> m_Buckets;
 24
 25        /// <summary>
 26        ///     The block size used to allocate new arrays.
 27        /// </summary>
 28        readonly ulong m_BucketSize;
 29
 30        /// <summary>
 31        ///     Cached version of the bucket size, minus one used in <see cref="GetBucketLocation" />.
 32        /// </summary>
 33        readonly ulong m_BucketSizeMinusOne;
 34
 35        public CoalesceArray(ulong length)
 036        {
 037            int sizeOf = UnsafeUtility.SizeOf(typeof(T));
 038            ulong expectedSize = length * (ulong)sizeOf;
 39
 40            // Check if we've wrapped around, if the size is bigger then our max data size, or if the length will exceed
 41            // the array address space.
 042            if (expectedSize < length || expectedSize > k_MaxByteSize || length >= k_MaxByteSize)
 043            {
 044                m_BucketSize = k_MaxByteSize / (ulong)sizeOf;
 045            }
 46            else
 047            {
 048                m_BucketSize = math.ceilpow2(length);
 049            }
 50
 051            m_BucketSizeMinusOne = m_BucketSize - 1;
 52
 53            // Build our empty arrays
 054            ulong remainder = length & m_BucketSizeMinusOne;
 055            int extraArray = 0;
 056            if (remainder > 0)
 057            {
 058                extraArray = 1;
 059            }
 60
 061            int placesToShift = math.tzcnt(m_BucketSize);
 062            int arrayCount = (int)(length >> placesToShift) + extraArray;
 063            m_Buckets = new SimpleList<T[]>(arrayCount);
 064            for (int i = 0; i < arrayCount; i++)
 065            {
 066                m_Buckets.Array[i] = new T[(int)m_BucketSize];
 067            }
 68
 069            Length = length;
 070        }
 71
 72        public T this[ulong index]
 73        {
 74            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 75            get
 076            {
 077                (int bucketIndex, int bucketOffset) info = GetBucketLocation(index);
 078                return m_Buckets.Array[info.bucketIndex][info.bucketOffset];
 079            }
 80
 81            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 82            set
 083            {
 084                (int bucketIndex, int bucketOffset) info = GetBucketLocation(index);
 085                m_Buckets.Array[info.bucketIndex][info.bucketOffset] = value;
 086            }
 87        }
 88
 89        /// <summary>
 90        ///     The number of elements the <see cref="CoalesceArray{T}" /> is capable of holding.
 91        /// </summary>
 092        public ulong Length { get; private set; }
 93
 94        public ref T[] GetBucket(int bucketIndex)
 095        {
 096            return ref m_Buckets.Array[bucketIndex];
 097        }
 98
 99        public int GetBucketCount()
 0100        {
 0101            return m_Buckets.Count;
 0102        }
 103
 104        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 105        public (int bucketIndex, int bucketOffset) GetBucketLocation(ulong index)
 0106        {
 0107            int bucketOffset = (int)(index & m_BucketSizeMinusOne);
 0108            int placesToShift = math.tzcnt(m_BucketSize);
 0109            int bucketIndex = (int)(index >> placesToShift);
 0110            return (bucketIndex, bucketOffset);
 0111        }
 112
 113        public bool Resize(ulong desiredLength)
 0114        {
 0115            ulong remainder = desiredLength & m_BucketSizeMinusOne;
 0116            int extraArray = 0;
 0117            if (remainder > 0)
 0118            {
 0119                extraArray = 1;
 0120            }
 121
 0122            int arrayCount = (int)((desiredLength - remainder) / m_BucketSize) + extraArray;
 0123            int previousCount = m_Buckets.Count;
 124
 125            // Grow
 0126            if (arrayCount > previousCount)
 0127            {
 0128                int additionalCount = arrayCount - previousCount;
 0129                for (int i = 0; i < additionalCount; i++)
 0130                {
 0131                    m_Buckets.AddWithExpandCheck(new T[m_BucketSize]);
 0132                }
 133
 0134                Length = desiredLength;
 0135                return true;
 136            }
 137
 138            // Shrink
 0139            if (arrayCount < previousCount)
 0140            {
 0141                int extraCount = previousCount - arrayCount;
 0142                for (int i = 0; i < extraCount; i++)
 0143                {
 0144                    m_Buckets.RemoveFromBack();
 0145                }
 146
 0147                Length = desiredLength;
 0148                return true;
 149            }
 150
 151            // Do nothing
 0152            Length = desiredLength;
 0153            return false;
 0154        }
 155    }
 156}

Coverage by test methods


Methods/Properties

CoalesceArray(System.UInt64)
Item(System.UInt64)
Item(System.UInt64, T)
Length()
Length(System.UInt64)
GetBucket(System.Int32)
GetBucketCount()
GetBucketLocation(System.UInt64)
Resize(System.UInt64)