< Summary

Class:GDX.Collections.NativeArraySparseSet
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Collections/NativeArraySparseSet.cs
Covered lines:477
Uncovered lines:2
Coverable lines:479
Total lines:965
Line coverage:99.5% (477 of 479)
Covered branches:0
Total branches:0
Covered methods:29
Total methods:29
Method coverage:100% (29 of 29)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
NativeArraySparseSet(...)0%220100%
NativeArraySparseSet(...)0%220100%
AddWithExpandCheck(...)0%330100%
AddWithExpandCheck(...)0%330100%
AddUnchecked(...)0%110100%
AddUnchecked(...)0%110100%
GetDenseIndexUnchecked(...)0%110100%
GetDenseIndexWithBoundsCheck(...)0%6.016092.86%
GetDenseIndexWithVersionCheck(...)0%220100%
GetDenseIndexWithBoundsAndVersionCheck(...)0%7.017093.33%
RemoveWithBoundsCheck(...)0%770100%
RemoveWithBoundsAndVersionChecks(...)0%880100%
RemoveUnchecked(...)0%110100%
RemoveUnchecked(...)0%110100%
RemoveUnchecked(...)0%110100%
RemoveUnchecked(...)0%110100%
RemoveUncheckedFromDenseIndex(...)0%110100%
RemoveUncheckedFromDenseIndex(...)0%110100%
RemoveUncheckedFromDenseIndex(...)0%110100%
RemoveUncheckedFromDenseIndex(...)0%110100%
RemoveWithVersionCheck(...)0%220100%
Clear()0%220100%
Clear(...)0%220100%
ClearWithVersionArrayReset(...)0%220100%
Expand(...)0%220100%
Expand(...)0%220100%
Reserve(...)0%330100%
Reserve(...)0%330100%
Dispose()0%330100%

File(s)

./Packages/com.dotbunny.gdx/GDX/Collections/NativeArraySparseSet.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;
 6using System.Runtime.CompilerServices;
 7using Unity.Collections;
 8
 9namespace GDX.Collections
 10{
 11    /// <summary>
 12    ///     An adapter collection for external data arrays that allows constant-time insertion, deletion, and lookup by
 13    ///     handle, as well as array-like iteration.
 14    /// </summary>
 15    public struct NativeArraySparseSet : IDisposable
 16    {
 17        /// <summary>
 18        ///     Holds references to the sparse array for swapping indices.
 19        /// </summary>
 20        public NativeArray<int> DenseArray;
 21
 22        /// <summary>
 23        ///     Holds references to dense array indices.
 24        /// </summary>
 25        /// <remarks>
 26        ///     Its own indices are claimed and freed via a free-list.
 27        /// </remarks>
 28        public NativeArray<int> SparseArray;
 29
 30        /// <summary>
 31        ///     How many indices are being used currently?
 32        /// </summary>
 33        public int Count;
 34
 35        /// <summary>
 36        ///     The first free (currently unused) index in the sparse array.
 37        /// </summary>
 38        public int FreeIndex;
 39
 40        /// <summary>
 41        ///     Create a <see cref="NativeArraySparseSet" /> with an <paramref name="initialCapacity" />.
 42        /// </summary>
 43        /// <param name="initialCapacity">The initial capacity of the sparse and dense int arrays.</param>
 44        /// <param name="allocator">The <see cref="Unity.Collections.Allocator" /> type to use.</param>
 45        public NativeArraySparseSet(int initialCapacity, Allocator allocator)
 1446        {
 1447            DenseArray = new NativeArray<int>(initialCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1448            SparseArray = new NativeArray<int>(initialCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1449            Count = 0;
 1450            FreeIndex = 0;
 51
 10052            for (int i = 0; i < initialCapacity; i++)
 3653            {
 3654                DenseArray[i] = -1;
 3655                SparseArray[i] = i + 1;
 3656            }
 1457        }
 58
 59        /// <summary>
 60        ///     Create a <see cref="NativeArraySparseSet" /> with an <paramref name="initialCapacity" />.
 61        /// </summary>
 62        /// <param name="initialCapacity">The initial capacity of the sparse and dense int arrays.</param>
 63        /// <param name="allocator">The <see cref="Unity.Collections.Allocator" /> type to use.</param>
 64        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 65        public NativeArraySparseSet(int initialCapacity, Allocator allocator, out NativeArray<ulong> versionArray)
 1766        {
 1767            DenseArray = new NativeArray<int>(initialCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1768            SparseArray = new NativeArray<int>(initialCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1769            versionArray = new NativeArray<ulong>(initialCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1770            Count = 0;
 1771            FreeIndex = 0;
 72
 12473            for (int i = 0; i < initialCapacity; i++)
 4574            {
 4575                DenseArray[i] = -1;
 4576                SparseArray[i] = i + 1;
 4577                versionArray[i] = 1;
 4578            }
 1779        }
 80
 81        /// <summary>
 82        ///     Adds a sparse/dense index pair to the set and expands the arrays if necessary.
 83        /// </summary>
 84        /// <param name="expandBy">How many indices to expand by.</param>
 85        /// <param name="sparseIndex">The sparse index allocated.</param>
 86        /// <param name="denseIndex">The dense index allocated.</param>
 87        /// <param name="allocator">The <see cref="Unity.Collections.Allocator" /> type to use.</param>
 88        /// <returns>True if the index pool expanded.</returns>
 89        public bool AddWithExpandCheck(int expandBy, out int sparseIndex, out int denseIndex, Allocator allocator)
 490        {
 491            int indexToClaim = FreeIndex;
 492            int currentCapacity = SparseArray.Length;
 493            bool needsExpansion = false;
 94
 495            if (indexToClaim >= currentCapacity)
 296            {
 97                // We're out of space, the last free index points to nothing. Allocate more indices.
 298                needsExpansion = true;
 99
 2100                int newCapacity = currentCapacity + expandBy;
 101
 2102                NativeArray<int> newSparseArray =
 103                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 2104                NativeSlice<int> newSparseArraySlice = new NativeSlice<int>(newSparseArray, 0, currentCapacity);
 2105                newSparseArraySlice.CopyFrom(SparseArray);
 2106                SparseArray.Dispose();
 2107                SparseArray = newSparseArray;
 108
 2109                NativeArray<int> newDenseArray =
 110                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 2111                NativeSlice<int> newDenseArraySlice = new NativeSlice<int>(newDenseArray, 0, currentCapacity);
 2112                newDenseArraySlice.CopyFrom(DenseArray);
 2113                DenseArray.Dispose();
 2114                DenseArray = newDenseArray;
 115
 24116                for (int i = currentCapacity; i < newCapacity; i++)
 10117                {
 10118                    SparseArray[i] = i + 1; // Build the free list chain.
 10119                    DenseArray[i] = -1; // Set new dense indices as unclaimed.
 10120                }
 2121            }
 122
 4123            int nextFreeIndex = SparseArray[indexToClaim];
 4124            DenseArray[Count] = indexToClaim; // Point the next dense id at our newly claimed sparse index.
 4125            SparseArray[indexToClaim] = Count; // Point our newly claimed sparse index at the dense index.
 4126            denseIndex = Count;
 127
 4128            ++Count;
 4129            FreeIndex = nextFreeIndex; // Set the free list head for next time.
 130
 4131            sparseIndex = indexToClaim;
 4132            return needsExpansion;
 4133        }
 134
 135        /// <summary>
 136        ///     Adds a sparse/dense index pair to the set and expands the arrays if necessary.
 137        /// </summary>
 138        /// <param name="expandBy">How many indices to expand by.</param>
 139        /// <param name="sparseIndex">The sparse index allocated.</param>
 140        /// <param name="denseIndex">The dense index allocated.</param>
 141        /// <param name="allocator">The <see cref="Unity.Collections.Allocator" /> type to use.</param>
 142        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 143        /// <returns>True if the index pool expanded.</returns>
 144        public bool AddWithExpandCheck(int expandBy, out int sparseIndex, out int denseIndex, Allocator allocator,
 145            ref NativeArray<ulong> versionArray)
 2146        {
 2147            int indexToClaim = FreeIndex;
 2148            int currentCapacity = SparseArray.Length;
 2149            bool needsExpansion = false;
 150
 2151            if (indexToClaim >= currentCapacity)
 1152            {
 153                // We're out of space, the last free index points to nothing. Allocate more indices.
 1154                needsExpansion = true;
 155
 1156                int newCapacity = currentCapacity + expandBy;
 157
 1158                NativeArray<int> newSparseArray =
 159                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1160                NativeSlice<int> newSparseArraySlice = new NativeSlice<int>(newSparseArray, 0, currentCapacity);
 1161                newSparseArraySlice.CopyFrom(SparseArray);
 1162                SparseArray.Dispose();
 1163                SparseArray = newSparseArray;
 164
 1165                NativeArray<int> newDenseArray =
 166                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1167                NativeSlice<int> newDenseArraySlice = new NativeSlice<int>(newDenseArray, 0, currentCapacity);
 1168                newDenseArraySlice.CopyFrom(DenseArray);
 1169                DenseArray.Dispose();
 1170                DenseArray = newDenseArray;
 171
 1172                NativeArray<ulong> newVersionArray =
 173                    new NativeArray<ulong>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1174                NativeSlice<ulong> newVersionArraySlice = new NativeSlice<ulong>(newVersionArray, 0, currentCapacity);
 1175                newVersionArraySlice.CopyFrom(versionArray);
 1176                versionArray.Dispose();
 1177                versionArray = newVersionArray;
 178
 12179                for (int i = currentCapacity; i < newCapacity; i++)
 5180                {
 5181                    SparseArray[i] = i + 1; // Build the free list chain.
 5182                    DenseArray[i] = -1; // Set new dense indices as unclaimed.
 5183                    versionArray[i] = 1;
 5184                }
 1185            }
 186
 2187            int nextFreeIndex = SparseArray[indexToClaim];
 2188            DenseArray[Count] = indexToClaim; // Point the next dense id at our newly claimed sparse index.
 2189            SparseArray[indexToClaim] = Count; // Point our newly claimed sparse index at the dense index.
 2190            denseIndex = Count;
 191
 2192            ++Count;
 2193            FreeIndex = nextFreeIndex; // Set the free list head for next time.
 194
 2195            sparseIndex = indexToClaim;
 2196            return needsExpansion;
 2197        }
 198
 199        /// <summary>
 200        ///     Adds a sparse/dense index pair to the set without checking if the set needs to expand.
 201        /// </summary>
 202        /// <param name="sparseIndex">The sparse index allocated.</param>
 203        /// <param name="denseIndex">The dense index allocated.</param>
 204        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 205        public void AddUnchecked(out int sparseIndex, out int denseIndex)
 20206        {
 20207            int indexToClaim = FreeIndex;
 20208            int nextFreeIndex = SparseArray[indexToClaim];
 19209            DenseArray[Count] = indexToClaim; // Point the next dense id at our newly claimed sparse index.
 19210            SparseArray[indexToClaim] = Count; // Point our newly claimed sparse index at the dense index.
 211
 19212            sparseIndex = indexToClaim;
 19213            denseIndex = Count;
 19214            ++Count;
 19215            FreeIndex = nextFreeIndex; // Set the free list head for next time.
 19216        }
 217
 218        /// <summary>
 219        ///     Adds a sparse/dense index pair to the set without checking if the set needs to expand.
 220        /// </summary>
 221        /// <param name="sparseIndex">The sparse index allocated.</param>
 222        /// <param name="denseIndex">The dense index allocated.</param>
 223        /// <param name="versionArray">The array containing the version number to check against.</param>
 224        /// <param name="version">Enables detection of use-after-free errors when using the sparse index as a reference.
 225        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 226        public void AddUnchecked(out int sparseIndex, out int denseIndex, NativeArray<ulong> versionArray,
 227            out ulong version)
 24228        {
 24229            int indexToClaim = FreeIndex;
 24230            int nextFreeIndex = SparseArray[indexToClaim];
 23231            DenseArray[Count] = indexToClaim; // Point the next dense id at our newly claimed sparse index.
 23232            SparseArray[indexToClaim] = Count; // Point our newly claimed sparse index at the dense index.
 233
 23234            version = versionArray[indexToClaim];
 23235            sparseIndex = indexToClaim;
 23236            denseIndex = Count;
 237
 23238            ++Count;
 23239            FreeIndex = nextFreeIndex; // Set the free list head for next time.
 23240        }
 241
 242        /// <summary>
 243        ///     Gets the value of the sparse array at the given index without any data validation.
 244        /// </summary>
 245        /// <param name="sparseIndex">The index to check in the sparse array.</param>
 246        /// <returns>The dense index at the given sparse index.</returns>
 247        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 248        public int GetDenseIndexUnchecked(int sparseIndex)
 1249        {
 1250            return SparseArray[sparseIndex];
 1251        }
 252
 253        /// <summary>
 254        ///     Gets the value of the sparse array at the given index,
 255        ///     or -1 if the dense and sparse indices don't point to each other or if the dense index is outside the den
 256        /// </summary>
 257        /// <param name="sparseIndex">The index in the sparse array to check against.</param>
 258        /// <returns>The dense index pointed to by the current sparse index, or -1 if invalid.</returns>
 259        public int GetDenseIndexWithBoundsCheck(int sparseIndex)
 4260        {
 4261            if (sparseIndex >= 0 && sparseIndex < SparseArray.Length)
 2262            {
 2263                int denseIndex = SparseArray[sparseIndex];
 264
 2265                if (denseIndex < Count && denseIndex >= 0)
 1266                {
 1267                    int sparseIndexAtDenseIndex = DenseArray[denseIndex];
 268
 1269                    if (sparseIndex == sparseIndexAtDenseIndex)
 1270                    {
 1271                        return denseIndex;
 272                    }
 0273                }
 1274            }
 275
 3276            return -1;
 4277        }
 278
 279        /// <summary>
 280        ///     Gets the value of the sparse array at the given index,
 281        ///     or -1 if the version number does not match.
 282        /// </summary>
 283        /// <param name="sparseIndex">The index in the sparse array to check against.</param>
 284        /// <param name="version">The version number associated with the sparse index.</param>
 285        /// <param name="versionArray">The array containing the version number to check against.</param>
 286        /// <returns>The dense index pointed to by the current sparse index, or -1 if invalid.</returns>
 287        public int GetDenseIndexWithVersionCheck(int sparseIndex, ulong version, NativeArray<ulong> versionArray)
 4288        {
 4289            int denseIndex = SparseArray[sparseIndex];
 4290            ulong versionAtSparseIndex = versionArray[sparseIndex];
 291
 4292            if (version == versionAtSparseIndex)
 2293            {
 2294                return denseIndex;
 295            }
 296
 2297            return -1;
 4298        }
 299
 300        /// <summary>
 301        ///     Gets the value of the sparse array at the given index,
 302        ///     or -1 if the given sparse index is invalid..
 303        /// </summary>
 304        /// <param name="sparseIndex">The index in the sparse array to check against.</param>
 305        /// <param name="version">The version number associated with the sparse index.</param>
 306        /// <param name="versionArray">The array containing the version number to check against.</param>
 307        /// <returns>The dense index pointed to by the current sparse index, or -1 if invalid.</returns>
 308        public int GetDenseIndexWithBoundsAndVersionCheck(int sparseIndex, ulong version,
 309            NativeArray<ulong> versionArray)
 7310        {
 7311            if (sparseIndex >= 0 && sparseIndex < SparseArray.Length)
 5312            {
 5313                int denseIndex = SparseArray[sparseIndex];
 5314                ulong versionAtSparseIndex = versionArray[sparseIndex];
 315
 5316                if (versionAtSparseIndex == version && denseIndex < Count && denseIndex >= 0)
 2317                {
 2318                    int sparseIndexAtDenseIndex = DenseArray[denseIndex];
 319
 2320                    if (sparseIndex == sparseIndexAtDenseIndex)
 2321                    {
 2322                        return denseIndex;
 323                    }
 0324                }
 3325            }
 326
 5327            return -1;
 7328        }
 329
 330        /// <summary>
 331        ///     Removes the entry corresponding to the sparse index if the entry is within bounds and currently in use.
 332        /// </summary>
 333        /// <param name="sparseIndexToRemove">
 334        ///     The sparse index corresponding to the entry to remove. Cleared to -1 in this
 335        ///     operation.
 336        /// </param>
 337        /// <param name="dataIndexToSwapFrom">
 338        ///     Set the data array value at this index to default after swapping with the data array
 339        ///     value at indexToSwapTo.
 340        /// </param>
 341        /// <param name="dataIndexToSwapTo">
 342        ///     Replace the data array value at this index with the data array value at
 343        ///     indexToSwapFrom.
 344        /// </param>
 345        /// <returns>True if the index reference was valid, and thus removed.</returns>
 346        public bool RemoveWithBoundsCheck(ref int sparseIndexToRemove, out int dataIndexToSwapFrom,
 347            out int dataIndexToSwapTo)
 4348        {
 4349            dataIndexToSwapFrom = -1;
 4350            dataIndexToSwapTo = -1;
 4351            bool didRemove = false;
 4352            if (sparseIndexToRemove >= 0 && sparseIndexToRemove < SparseArray.Length)
 2353            {
 2354                int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 355
 2356                if (denseIndexToRemove >= 0 && denseIndexToRemove < Count)
 1357                {
 1358                    int sparseIndexAtDenseIndex = DenseArray[denseIndexToRemove];
 1359                    int newLength = Count - 1;
 1360                    int sparseIndexBeingSwapped = DenseArray[newLength];
 361
 1362                    if (denseIndexToRemove < Count && sparseIndexAtDenseIndex == sparseIndexToRemove)
 1363                    {
 1364                        didRemove = true;
 365                        // Swap the entry being removed with the last entry.
 1366                        SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1367                        DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 368
 1369                        dataIndexToSwapFrom = newLength;
 1370                        dataIndexToSwapTo = denseIndexToRemove;
 371
 372                        // Clear the dense index, for debugging purposes
 1373                        DenseArray[newLength] = -1;
 374
 375                        // Add the sparse index to the free list.
 1376                        SparseArray[sparseIndexToRemove] = FreeIndex;
 1377                        FreeIndex = sparseIndexToRemove;
 378
 1379                        Count = newLength;
 1380                    }
 1381                }
 2382            }
 383
 4384            sparseIndexToRemove = -1;
 385
 4386            return didRemove;
 4387        }
 388
 389        /// <summary>
 390        ///     Removes the associated sparse/dense index pair from active use.
 391        ///     calls.
 392        /// </summary>
 393        /// <param name="sparseIndexToRemove">The sparse index to remove.</param>
 394        /// <param name="version">
 395        ///     The version number of the int used to access the sparse index. Used to guard against accessing
 396        ///     indices that have been removed and reused.
 397        /// </param>
 398        /// <param name="versionArray">The array containing the version number to check against.</param>
 399        /// <param name="indexToSwapFrom">
 400        ///     Set the data array value at this index to default after swapping with the data array
 401        ///     value at indexToSwapTo.
 402        /// </param>
 403        /// <param name="indexToSwapTo">Replace the data array value at this index with the data array value at indexToS
 404        /// <returns>True if the element was successfully removed.</returns>
 405        public bool RemoveWithBoundsAndVersionChecks(ref int sparseIndexToRemove, ulong version,
 406            NativeArray<ulong> versionArray, out int indexToSwapFrom, out int indexToSwapTo)
 6407        {
 6408            indexToSwapFrom = -1;
 6409            indexToSwapTo = -1;
 6410            bool didRemove = false;
 6411            if (sparseIndexToRemove >= 0 && sparseIndexToRemove < SparseArray.Length)
 3412            {
 3413                ulong sparseIndexVersion = versionArray[sparseIndexToRemove];
 3414                int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 415
 3416                if (sparseIndexVersion == version && denseIndexToRemove >= 0 && denseIndexToRemove < Count)
 2417                {
 2418                    int sparseIndexAtDenseIndex = DenseArray[denseIndexToRemove];
 2419                    int newLength = Count - 1;
 2420                    int sparseIndexBeingSwapped = DenseArray[newLength];
 421
 2422                    if (denseIndexToRemove < Count && sparseIndexAtDenseIndex == sparseIndexToRemove)
 2423                    {
 2424                        didRemove = true;
 2425                        versionArray[sparseIndexToRemove] = sparseIndexVersion + 1;
 426                        // Swap the entry being removed with the last entry.
 2427                        SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 2428                        DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 429
 2430                        indexToSwapFrom = newLength;
 2431                        indexToSwapTo = denseIndexToRemove;
 432
 433                        // Clear the dense index, for debugging purposes
 2434                        DenseArray[newLength] = -1;
 435
 436                        // Add the sparse index to the free list.
 2437                        SparseArray[sparseIndexToRemove] = FreeIndex;
 2438                        FreeIndex = sparseIndexToRemove;
 439
 2440                        Count = newLength;
 2441                    }
 2442                }
 3443            }
 444
 6445            sparseIndexToRemove = -1;
 446
 6447            return didRemove;
 6448        }
 449
 450        /// <summary>
 451        ///     Removes the associated sparse/dense index pair from active use.
 452        /// </summary>
 453        /// <param name="sparseIndexToRemove">The sparse index to remove.</param>
 454        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 455        public void RemoveUnchecked(int sparseIndexToRemove)
 1456        {
 1457            int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 1458            int newLength = Count - 1;
 1459            int sparseIndexBeingSwapped = DenseArray[newLength];
 460
 461            // Swap the entry being removed with the last entry.
 1462            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1463            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 464
 465            // Clear the dense  index, for debugging purposes
 1466            DenseArray[newLength] = -1;
 467
 468            // Add the sparse index to the free list.
 1469            SparseArray[sparseIndexToRemove] = FreeIndex;
 1470            FreeIndex = sparseIndexToRemove;
 471
 1472            Count = newLength;
 1473        }
 474
 475        /// <summary>
 476        ///     Removes the associated sparse/dense index pair from active use and increments the version.
 477        /// </summary>
 478        /// <param name="sparseIndexToRemove">The sparse index to remove.</param>
 479        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 480        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 481        public void RemoveUnchecked(int sparseIndexToRemove, NativeArray<ulong> versionArray)
 1482        {
 1483            int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 1484            int newLength = Count - 1;
 1485            int sparseIndexBeingSwapped = DenseArray[newLength];
 486
 487            // Swap the entry being removed with the last entry.
 1488            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1489            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 490
 491            // Clear the dense  index, for debugging purposes
 1492            DenseArray[newLength] = -1;
 493
 494            // Add the sparse index to the free list.
 1495            SparseArray[sparseIndexToRemove] = FreeIndex;
 1496            versionArray[sparseIndexToRemove] += 1;
 1497            FreeIndex = sparseIndexToRemove;
 498
 1499            Count = newLength;
 1500        }
 501
 502        /// <summary>
 503        ///     Removes the associated sparse/dense index pair from active use.
 504        ///     Out parameters used to manage parallel data arrays.
 505        /// </summary>
 506        /// <param name="sparseIndexToRemove">The sparse index to remove.</param>
 507        /// <param name="indexToSwapTo">Replace the data array value at this index with the data array value at indexToS
 508        /// <param name="indexToSwapFrom">
 509        ///     Set the data array value at this index to default after swapping with the data array
 510        ///     value at indexToSwapTo.
 511        /// </param>
 512        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 513        public void RemoveUnchecked(int sparseIndexToRemove, out int indexToSwapFrom, out int indexToSwapTo)
 1514        {
 1515            int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 1516            int newLength = Count - 1;
 1517            int sparseIndexBeingSwapped = DenseArray[newLength];
 518
 519            // Swap the entry being removed with the last entry.
 1520            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1521            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 522
 523            // Clear the dense  index, for debugging purposes
 1524            DenseArray[newLength] = -1;
 525
 526            // Add the sparse index to the free list.
 1527            SparseArray[sparseIndexToRemove] = FreeIndex;
 1528            FreeIndex = sparseIndexToRemove;
 529
 1530            Count = newLength;
 531
 1532            indexToSwapTo = denseIndexToRemove;
 1533            indexToSwapFrom = newLength;
 1534        }
 535
 536        /// <summary>
 537        ///     Removes the associated sparse/dense index pair from active use and increments the version.
 538        ///     Out parameters used to manage parallel data arrays.
 539        /// </summary>
 540        /// <param name="sparseIndexToRemove">The sparse index to remove.</param>
 541        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 542        /// <param name="indexToSwapTo">Replace the data array value at this index with the data array value at indexToS
 543        /// <param name="indexToSwapFrom">
 544        ///     Set the data array value at this index to default after swapping with the data array
 545        ///     value at indexToSwapTo.
 546        /// </param>
 547        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 548        public void RemoveUnchecked(int sparseIndexToRemove, NativeArray<ulong> versionArray, out int indexToSwapFrom,
 549            out int indexToSwapTo)
 2550        {
 2551            int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 2552            int newLength = Count - 1;
 2553            int sparseIndexBeingSwapped = DenseArray[newLength];
 554
 555            // Swap the entry being removed with the last entry.
 2556            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 2557            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 558
 559            // Clear the dense  index, for debugging purposes
 2560            DenseArray[newLength] = -1;
 561
 562            // Add the sparse index to the free list.
 2563            SparseArray[sparseIndexToRemove] = FreeIndex;
 2564            versionArray[sparseIndexToRemove] += 1;
 2565            FreeIndex = sparseIndexToRemove;
 566
 2567            Count = newLength;
 568
 2569            indexToSwapTo = denseIndexToRemove;
 2570            indexToSwapFrom = newLength;
 2571        }
 572
 573        /// <summary>
 574        ///     Removes the associated sparse/dense index pair from active use.
 575        /// </summary>
 576        /// <param name="denseIndexToRemove">The dense index associated with the sparse index to remove.</param>
 577        public void RemoveUncheckedFromDenseIndex(int denseIndexToRemove)
 1578        {
 1579            int sparseIndexToRemove = DenseArray[denseIndexToRemove];
 1580            int newLength = Count - 1;
 1581            int sparseIndexBeingSwapped = DenseArray[newLength];
 582
 583            // Swap the entry being removed with the last entry.
 1584            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1585            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 586
 587            // Clear the dense  index, for debugging purposes
 1588            DenseArray[newLength] = -1;
 589
 590            // Add the sparse index to the free list.
 1591            SparseArray[sparseIndexToRemove] = FreeIndex;
 1592            FreeIndex = sparseIndexToRemove;
 593
 1594            Count = newLength;
 1595        }
 596
 597        /// <summary>
 598        ///     Removes the associated sparse/dense index pair from active use.
 599        /// </summary>
 600        /// <param name="denseIndexToRemove">The dense index associated with the sparse index to remove.</param>
 601        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 602        public void RemoveUncheckedFromDenseIndex(int denseIndexToRemove, NativeArray<ulong> versionArray)
 1603        {
 1604            int sparseIndexToRemove = DenseArray[denseIndexToRemove];
 1605            int newLength = Count - 1;
 1606            int sparseIndexBeingSwapped = DenseArray[newLength];
 607
 608            // Swap the entry being removed with the last entry.
 1609            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1610            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 611
 612            // Clear the dense  index, for debugging purposes
 1613            DenseArray[newLength] = -1;
 614
 615            // Add the sparse index to the free list.
 1616            SparseArray[sparseIndexToRemove] = FreeIndex;
 1617            versionArray[sparseIndexToRemove] += 1;
 1618            FreeIndex = sparseIndexToRemove;
 619
 1620            Count = newLength;
 1621        }
 622
 623        /// <summary>
 624        ///     Removes the associated sparse/dense index pair from active use.
 625        ///     Out parameter used to manage parallel data arrays.
 626        /// </summary>
 627        /// <param name="denseIndexToRemove">The sparse index to remove.</param>
 628        /// <param name="indexToSwapFrom">
 629        ///     Set the data array value at this index to default after swapping with the data array
 630        ///     value at denseIndexToRemove.
 631        /// </param>
 632        public void RemoveUncheckedFromDenseIndex(int denseIndexToRemove, out int indexToSwapFrom)
 1633        {
 1634            int sparseIndexToRemove = DenseArray[denseIndexToRemove];
 1635            int newLength = Count - 1;
 1636            int sparseIndexBeingSwapped = DenseArray[newLength];
 637
 638            // Swap the entry being removed with the last entry.
 1639            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1640            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 641
 642            // Clear the dense  index, for debugging purposes
 1643            DenseArray[newLength] = -1;
 644
 645            // Add the sparse index to the free list.
 1646            SparseArray[sparseIndexToRemove] = FreeIndex;
 1647            FreeIndex = sparseIndexToRemove;
 648
 1649            Count = newLength;
 650
 1651            indexToSwapFrom = newLength;
 1652        }
 653
 654        /// <summary>
 655        ///     Removes the associated sparse/dense index pair from active use.
 656        ///     Out parameter used to manage parallel data arrays.
 657        /// </summary>
 658        /// <param name="denseIndexToRemove">The sparse index to remove.</param>
 659        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 660        /// <param name="indexToSwapFrom">
 661        ///     Set the data array value at this index to default after swapping with the data array
 662        ///     value at denseIndexToRemove.
 663        /// </param>
 664        public void RemoveUncheckedFromDenseIndex(int denseIndexToRemove, NativeArray<ulong> versionArray,
 665            out int indexToSwapFrom)
 1666        {
 1667            int sparseIndexToRemove = DenseArray[denseIndexToRemove];
 1668            int newLength = Count - 1;
 1669            int sparseIndexBeingSwapped = DenseArray[newLength];
 670
 671            // Swap the entry being removed with the last entry.
 1672            SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1673            DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 674
 675            // Clear the dense  index, for debugging purposes
 1676            DenseArray[newLength] = -1;
 677
 678            // Add the sparse index to the free list.
 1679            SparseArray[sparseIndexToRemove] = FreeIndex;
 1680            versionArray[sparseIndexToRemove] += 1;
 1681            FreeIndex = sparseIndexToRemove;
 682
 1683            Count = newLength;
 684
 1685            indexToSwapFrom = newLength;
 1686        }
 687
 688        /// <summary>
 689        ///     Attempts to remove the associated sparse/dense index pair from active use and increments the version if 
 690        ///     Out parameters used to manage parallel data arrays.
 691        /// </summary>
 692        /// <param name="sparseIndexToRemove">The sparse index to remove.</param>
 693        /// <param name="version">
 694        ///     The version number of the int used to access the sparse index. Used to guard against accessing
 695        ///     indices that have been removed and reused.
 696        /// </param>
 697        /// <param name="versionArray">The array containing the version number to check against.</param>
 698        /// <param name="indexToSwapTo">Replace the data array value at this index with the data array value at indexToS
 699        /// <param name="indexToSwapFrom">
 700        ///     Set the data array value at this index to default after swapping with the data array
 701        ///     value at indexToSwapTo.
 702        /// </param>
 703        /// <returns>True if the entry was valid and thus removed.</returns>
 704        public bool RemoveWithVersionCheck(int sparseIndexToRemove, ulong version, NativeArray<ulong> versionArray,
 705            out int indexToSwapFrom, out int indexToSwapTo)
 2706        {
 2707            int denseIndexToRemove = SparseArray[sparseIndexToRemove];
 2708            ulong versionAtSparseIndex = versionArray[sparseIndexToRemove];
 709
 2710            indexToSwapFrom = -1;
 2711            indexToSwapTo = -1;
 712
 2713            bool succeeded = versionAtSparseIndex == version;
 714
 2715            if (succeeded)
 1716            {
 1717                int newLength = Count - 1;
 1718                int sparseIndexBeingSwapped = DenseArray[newLength];
 719
 720                // Swap the entry being removed with the last entry.
 1721                SparseArray[sparseIndexBeingSwapped] = denseIndexToRemove;
 1722                DenseArray[denseIndexToRemove] = sparseIndexBeingSwapped;
 723
 724                // Clear the dense  index, for debugging purposes
 1725                DenseArray[newLength] = -1;
 726
 727                // Add the sparse index to the free list.
 1728                SparseArray[sparseIndexToRemove] = FreeIndex;
 1729                versionArray[sparseIndexToRemove] += 1;
 1730                FreeIndex = sparseIndexToRemove;
 731
 1732                Count = newLength;
 733
 1734                indexToSwapTo = denseIndexToRemove;
 1735                indexToSwapFrom = newLength;
 1736            }
 737
 2738            return succeeded;
 2739        }
 740
 741        /// <summary>
 742        ///     Clear the dense and sparse arrays.
 743        /// </summary>
 744        public void Clear()
 1745        {
 1746            int capacity = SparseArray.Length;
 8747            for (int i = 0; i < capacity; i++)
 3748            {
 3749                DenseArray[i] = -1;
 3750                SparseArray[i] = i + 1;
 3751            }
 752
 1753            FreeIndex = 0;
 1754            Count = 0;
 1755        }
 756
 757        /// <summary>
 758        ///     Clear the dense and sparse arrays.
 759        /// </summary>
 760        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 761        public void Clear(NativeArray<ulong> versionArray)
 1762        {
 1763            int capacity = SparseArray.Length;
 8764            for (int i = 0; i < capacity; i++)
 3765            {
 3766                DenseArray[i] = -1;
 3767                SparseArray[i] = i + 1;
 3768                versionArray[i] += 1;
 3769            }
 770
 1771            FreeIndex = 0;
 1772            Count = 0;
 1773        }
 774
 775        /// <summary>
 776        ///     Clear the dense and sparse arrays and reset the version array.
 777        ///     Note: Only clear the version array if you are sure there are no outstanding dependencies on version numb
 778        /// </summary>
 779        /// ///
 780        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 781        public void ClearWithVersionArrayReset(NativeArray<ulong> versionArray)
 1782        {
 1783            int capacity = SparseArray.Length;
 8784            for (int i = 0; i < capacity; i++)
 3785            {
 3786                DenseArray[i] = -1;
 3787                SparseArray[i] = i + 1;
 3788                versionArray[i] = 1;
 3789            }
 790
 1791            FreeIndex = 0;
 1792            Count = 0;
 1793        }
 794
 795        /// <summary>
 796        ///     Reallocate the dense and sparse arrays with additional capacity.
 797        /// </summary>
 798        /// <param name="extraCapacity">How many indices to expand the dense and sparse arrays by.</param>
 799        /// <param name="allocator">The <see cref="Unity.Collections.Allocator" /> type to use.</param>
 800        public void Expand(int extraCapacity, Allocator allocator)
 1801        {
 1802            int currentCapacity = SparseArray.Length;
 1803            int newCapacity = currentCapacity + extraCapacity;
 804
 1805            NativeArray<int> newSparseArray =
 806                new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1807            NativeSlice<int> newSparseArraySlice = new NativeSlice<int>(newSparseArray, 0, currentCapacity);
 1808            newSparseArraySlice.CopyFrom(SparseArray);
 1809            SparseArray.Dispose();
 1810            SparseArray = newSparseArray;
 811
 1812            NativeArray<int> newDenseArray =
 813                new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1814            NativeSlice<int> newDenseArraySlice = new NativeSlice<int>(newDenseArray, 0, currentCapacity);
 1815            newDenseArraySlice.CopyFrom(DenseArray);
 1816            DenseArray.Dispose();
 1817            DenseArray = newDenseArray;
 818
 8819            for (int i = currentCapacity; i < newCapacity; i++)
 3820            {
 3821                DenseArray[i] = -1; // Set new dense indices as unclaimed.
 3822                SparseArray[i] = i + 1; // Build the free list chain.
 3823            }
 1824        }
 825
 826        /// <summary>
 827        ///     Reallocate the dense and sparse arrays with additional capacity.
 828        /// </summary>
 829        /// <param name="extraCapacity">How many indices to expand the dense and sparse arrays by.</param>
 830        /// <param name="allocator">Which Unity memory allocator to use with the backing array.</param>
 831        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 832        public void Expand(int extraCapacity, Allocator allocator, ref NativeArray<ulong> versionArray)
 1833        {
 1834            int currentCapacity = SparseArray.Length;
 1835            int newCapacity = currentCapacity + extraCapacity;
 836
 1837            NativeArray<int> newSparseArray =
 838                new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1839            NativeSlice<int> newSparseArraySlice = new NativeSlice<int>(newSparseArray, 0, currentCapacity);
 1840            newSparseArraySlice.CopyFrom(SparseArray);
 1841            SparseArray.Dispose();
 1842            SparseArray = newSparseArray;
 843
 1844            NativeArray<int> newDenseArray =
 845                new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1846            NativeSlice<int> newDenseArraySlice = new NativeSlice<int>(newDenseArray, 0, currentCapacity);
 1847            newDenseArraySlice.CopyFrom(DenseArray);
 1848            DenseArray.Dispose();
 1849            DenseArray = newDenseArray;
 850
 1851            NativeArray<ulong> newVersionArray =
 852                new NativeArray<ulong>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1853            NativeSlice<ulong> newVersionArraySlice = new NativeSlice<ulong>(newVersionArray, 0, currentCapacity);
 1854            newVersionArraySlice.CopyFrom(versionArray);
 1855            versionArray.Dispose();
 1856            versionArray = newVersionArray;
 857
 8858            for (int i = currentCapacity; i < newCapacity; i++)
 3859            {
 3860                DenseArray[i] = -1; // Set new dense indices as unclaimed.
 3861                SparseArray[i] = i + 1; // Build the free list chain.
 3862                versionArray[i] = 1;
 3863            }
 1864        }
 865
 866        /// <summary>
 867        ///     Reallocate the dense and sparse arrays with additional capacity if there are not at least
 868        ///     <paramref name="numberToReserve" /> unused entries.
 869        /// </summary>
 870        /// <param name="numberToReserve">The number of unused entries to ensure capacity for.</param>
 871        /// <param name="allocator">The allocator to use on expansion.</param>
 872        public void Reserve(int numberToReserve, Allocator allocator)
 1873        {
 1874            int currentCapacity = SparseArray.Length;
 1875            int currentCount = Count;
 1876            int newCapacity = currentCount + numberToReserve;
 877
 1878            if (newCapacity > currentCapacity)
 1879            {
 1880                NativeArray<int> newSparseArray =
 881                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1882                NativeSlice<int> newSparseArraySlice = new NativeSlice<int>(newSparseArray, 0, currentCapacity);
 1883                newSparseArraySlice.CopyFrom(SparseArray);
 1884                SparseArray.Dispose();
 1885                SparseArray = newSparseArray;
 886
 1887                NativeArray<int> newDenseArray =
 888                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1889                NativeSlice<int> newDenseArraySlice = new NativeSlice<int>(newDenseArray, 0, currentCapacity);
 1890                newDenseArraySlice.CopyFrom(DenseArray);
 1891                DenseArray.Dispose();
 1892                DenseArray = newDenseArray;
 893
 4894                for (int i = currentCapacity; i < newCapacity; i++)
 1895                {
 1896                    DenseArray[i] = -1; // Set new dense indices as unclaimed.
 1897                    SparseArray[i] = i + 1; // Build the free list chain.
 1898                }
 1899            }
 1900        }
 901
 902        /// <summary>
 903        ///     Reallocate the dense and sparse arrays with additional capacity if there are not at least
 904        ///     <paramref name="numberToReserve" /> unused entries.
 905        /// </summary>
 906        /// <param name="numberToReserve">The number of unused entries to ensure capacity for.</param>
 907        /// <param name="allocator">The allocator to use on expansion.</param>
 908        /// <param name="versionArray">Enables detection of use-after-free errors when using sparse indices as reference
 909        public void Reserve(int numberToReserve, Allocator allocator, ref NativeArray<ulong> versionArray)
 1910        {
 1911            int currentCapacity = SparseArray.Length;
 1912            int currentCount = Count;
 1913            int newCapacity = currentCount + numberToReserve;
 914
 1915            if (newCapacity > currentCapacity)
 1916            {
 1917                NativeArray<int> newSparseArray =
 918                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1919                NativeSlice<int> newSparseArraySlice = new NativeSlice<int>(newSparseArray, 0, currentCapacity);
 1920                newSparseArraySlice.CopyFrom(SparseArray);
 1921                SparseArray.Dispose();
 1922                SparseArray = newSparseArray;
 923
 1924                NativeArray<int> newDenseArray =
 925                    new NativeArray<int>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1926                NativeSlice<int> newDenseArraySlice = new NativeSlice<int>(newDenseArray, 0, currentCapacity);
 1927                newDenseArraySlice.CopyFrom(DenseArray);
 1928                DenseArray.Dispose();
 1929                DenseArray = newDenseArray;
 930
 1931                NativeArray<ulong> newVersionArray =
 932                    new NativeArray<ulong>(newCapacity, allocator, NativeArrayOptions.UninitializedMemory);
 1933                NativeSlice<ulong> newVersionArraySlice = new NativeSlice<ulong>(newVersionArray, 0, currentCapacity);
 1934                newVersionArraySlice.CopyFrom(versionArray);
 1935                versionArray.Dispose();
 1936                versionArray = newVersionArray;
 937
 4938                for (int i = currentCapacity; i < newCapacity; i++)
 1939                {
 1940                    DenseArray[i] = -1; // Set new dense indices as unclaimed.
 1941                    SparseArray[i] = i + 1; // Build the free list chain.
 1942                    versionArray[i] = 1;
 1943                }
 1944            }
 1945        }
 946
 947        public void Dispose()
 1948        {
 1949            if (SparseArray.IsCreated)
 1950            {
 1951                SparseArray.Dispose();
 1952            }
 953
 1954            SparseArray = default;
 1955            if (DenseArray.IsCreated)
 1956            {
 1957                DenseArray.Dispose();
 1958            }
 959
 1960            DenseArray = default;
 1961            Count = 0;
 1962            FreeIndex = 0;
 1963        }
 964    }
 965}

Coverage by test methods
































Methods/Properties

NativeArraySparseSet(System.Int32, Unity.Collections.Allocator)
NativeArraySparseSet(System.Int32, Unity.Collections.Allocator, Unity.Collections.NativeArray`1[[System.UInt64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]&)
AddWithExpandCheck(System.Int32, System.Int32&, System.Int32&, Unity.Collections.Allocator)
AddWithExpandCheck(System.Int32, System.Int32&, System.Int32&, Unity.Collections.Allocator, Unity.Collections.NativeArray`1[[System.UInt64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]&)
AddUnchecked(System.Int32&, System.Int32&)
AddUnchecked(System.Int32&, System.Int32&, Unity.Collections.NativeArray[UInt64], System.UInt64&)
GetDenseIndexUnchecked(System.Int32)
GetDenseIndexWithBoundsCheck(System.Int32)
GetDenseIndexWithVersionCheck(System.Int32, System.UInt64, Unity.Collections.NativeArray[UInt64])
GetDenseIndexWithBoundsAndVersionCheck(System.Int32, System.UInt64, Unity.Collections.NativeArray[UInt64])
RemoveWithBoundsCheck(System.Int32&, System.Int32&, System.Int32&)
RemoveWithBoundsAndVersionChecks(System.Int32&, System.UInt64, Unity.Collections.NativeArray[UInt64], System.Int32&, System.Int32&)
RemoveUnchecked(System.Int32)
RemoveUnchecked(System.Int32, Unity.Collections.NativeArray[UInt64])
RemoveUnchecked(System.Int32, System.Int32&, System.Int32&)
RemoveUnchecked(System.Int32, Unity.Collections.NativeArray[UInt64], System.Int32&, System.Int32&)
RemoveUncheckedFromDenseIndex(System.Int32)
RemoveUncheckedFromDenseIndex(System.Int32, Unity.Collections.NativeArray[UInt64])
RemoveUncheckedFromDenseIndex(System.Int32, System.Int32&)
RemoveUncheckedFromDenseIndex(System.Int32, Unity.Collections.NativeArray[UInt64], System.Int32&)
RemoveWithVersionCheck(System.Int32, System.UInt64, Unity.Collections.NativeArray[UInt64], System.Int32&, System.Int32&)
Clear()
Clear(Unity.Collections.NativeArray[UInt64])
ClearWithVersionArrayReset(Unity.Collections.NativeArray[UInt64])
Expand(System.Int32, Unity.Collections.Allocator)
Expand(System.Int32, Unity.Collections.Allocator, Unity.Collections.NativeArray`1[[System.UInt64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]&)
Reserve(System.Int32, Unity.Collections.Allocator)
Reserve(System.Int32, Unity.Collections.Allocator, Unity.Collections.NativeArray`1[[System.UInt64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]&)
Dispose()