Example #1
0
        public unsafe bool Allocate(ulong id, int vertexCount, out int start, out Buffer <Vector3> vertices)
        {
            if (TryGetExistingMesh(id, out start, out vertices))
            {
                return(false);
            }
            if (allocator.Allocate(id, vertexCount, out var longStart))
            {
                start    = (int)longStart;
                vertices = this.vertices.Slice(start, vertexCount);
                pendingUploads.Add(new UploadRequest {
                    Start = start, Count = vertexCount
                }, Pool);
                return(true);
            }
            //Didn't fit. We need to resize.
            var copyCount = TriangleBuffer.Capacity + vertexCount;
            var newSize   = 1 << SpanHelper.GetContainingPowerOf2(copyCount);

            Pool.ResizeToAtLeast(ref this.vertices, newSize, copyCount);
            allocator.Capacity = newSize;
            allocator.Allocate(id, vertexCount, out longStart);
            start    = (int)longStart;
            vertices = this.vertices.Slice(start, vertexCount);
            //A resize forces an upload of everything, so any previous pending uploads are unnecessary.
            pendingUploads.Count = 0;
            pendingUploads.Add(new UploadRequest {
                Start = 0, Count = copyCount
            }, Pool);
            return(true);
        }
Example #2
0
        public unsafe bool Allocate(ulong id, int vertexCount, out int start, out Buffer <Vector3> vertices)
        {
            if (allocator.TryGetAllocationRegion(id, out var allocation))
            {
                Debug.Assert(allocation.End - allocation.Start == vertexCount,
                             "If you're trying to allocate room for a bunch of triangles and we found it already, it better match the expected size.");
                start    = (int)allocation.Start;
                vertices = this.vertices.Slice(start, vertexCount);
                return(false);
            }
            if (allocator.Allocate(id, vertexCount, out var longStart))
            {
                start    = (int)longStart;
                vertices = this.vertices.Slice(start, vertexCount);
                pendingUploads.Add(new UploadRequest {
                    Start = start, Count = vertexCount
                }, Pool.SpecializeFor <UploadRequest>());
                return(true);
            }
            //Didn't fit. We need to resize.
            var copyCount = TriangleBuffer.Capacity + vertexCount;
            var newSize   = SpanHelper.GetContainingPowerOf2(copyCount);

            Pool.Resize(ref this.vertices, newSize, copyCount);
            allocator.Capacity = newSize;
            allocator.Allocate(id, vertexCount, out longStart);
            start    = (int)longStart;
            vertices = this.vertices.Slice(start, vertexCount);
            //A resize forces an upload of everything, so any previous pending uploads are unnecessary.
            pendingUploads.Count = 0;
            pendingUploads.Add(new UploadRequest {
                Start = 0, Count = copyCount
            }, Pool.SpecializeFor <UploadRequest>());
            return(true);
        }
Example #3
0
        /// <summary>
        /// There are two files: sourceFile and targetFile. Blocks are merged, mergeFactor at the time, from source to target. When all blocks from source have
        /// been merged into a larger block one merge iteration is done and source and target are flipped. As long as source contain more than a single block more
        /// merge iterations are needed and we start over again.
        /// When source only contain a single block we are finished and the extra file is deleted and <seealso cref="blockFile"/> contains the result with a single sorted
        /// block.
        ///
        /// See <seealso cref="performSingleMerge(int, BlockReader, StoreChannel, Cancellation, ByteBuffer[], ByteBuffer)"/> for further details.
        /// </summary>
        /// <param name="mergeFactor"> See <seealso cref="performSingleMerge(int, BlockReader, StoreChannel, Cancellation, ByteBuffer[], ByteBuffer)"/>. </param>
        /// <param name="cancellation"> Injected so that this merge can be cancelled, if an external request to do that comes in.
        /// A cancelled merge will leave the same end state file/channel-wise, just not quite completed, which is fine because the merge
        /// was cancelled meaning that the result will not be used for anything other than deletion. </param>
        /// <exception cref="IOException"> If something goes wrong when reading from file. </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void merge(int mergeFactor, Cancellation cancellation) throws java.io.IOException
        public virtual void Merge(int mergeFactor, Cancellation cancellation)
        {
            _monitor.mergeStarted(_entryCount, CalculateNumberOfEntriesWrittenDuringMerges(_entryCount, _numberOfBlocksInCurrentFile, mergeFactor));
            File sourceFile = _blockFile;
            File tempFile   = new File(_blockFile.Parent, _blockFile.Name + ".b");

            try
            {
                using (Allocator mergeBufferAllocator = _bufferFactory.newLocalAllocator())
                {
                    File targetFile = tempFile;

                    // Allocate all buffers that will be used and reused for all merge iterations
                    ByteBuffer   writeBuffer = mergeBufferAllocator.Allocate(_bufferFactory.bufferSize());
                    ByteBuffer[] readBuffers = new ByteBuffer[mergeFactor];
                    for (int i = 0; i < readBuffers.Length; i++)
                    {
                        readBuffers[i] = mergeBufferAllocator.Allocate(_bufferFactory.bufferSize());
                    }

                    while (_numberOfBlocksInCurrentFile > 1)
                    {
                        // Perform one complete merge iteration, merging all blocks from source into target.
                        // After this step, target will contain fewer blocks than source, but may need another merge iteration.
                        using (BlockReader <KEY, VALUE> reader = reader(sourceFile), StoreChannel targetChannel = _fs.open(targetFile, OpenMode.READ_WRITE))
                        {
                            long blocksMergedSoFar  = 0;
                            long blocksInMergedFile = 0;
                            while (!cancellation.Cancelled() && blocksMergedSoFar < _numberOfBlocksInCurrentFile)
                            {
                                blocksMergedSoFar += PerformSingleMerge(mergeFactor, reader, targetChannel, cancellation, readBuffers, writeBuffer);
                                blocksInMergedFile++;
                            }
                            _numberOfBlocksInCurrentFile = blocksInMergedFile;
                            _monitor.mergeIterationFinished(blocksMergedSoFar, blocksInMergedFile);
                        }

                        // Flip and restore the channels
                        File tmpSourceFile = sourceFile;
                        sourceFile = targetFile;
                        targetFile = tmpSourceFile;
                    }
                }
            }
            finally
            {
                if (sourceFile == _blockFile)
                {
                    _fs.deleteFile(tempFile);
                }
                else
                {
                    _fs.deleteFile(_blockFile);
                    _fs.renameFile(tempFile, _blockFile);
                }
            }
        }
        public void Third_VarianceDistributionIsEvenTest()
        {
            Person firstPerson
                = new Person(1, 13);
            Person secondPerson
                = new Person(2, 14);
            Person thirdPerson
                = new Person(3, 15);
            Person fourthPerson
                = new Person(4, 14);
            Person fifthPerson
                = new Person(5, 34);
            Person sixthPerson
                = new Person(6, 4);

            List <Person> collectors = new List <Person>()
            {
                firstPerson, secondPerson, thirdPerson, fourthPerson, fifthPerson, sixthPerson
            };

            Allocator allocator = new Allocator();

            allocator.Allocate(100, collectors);

            Assert.IsTrue(firstPerson.NewSticksHolded == 19);
            Assert.IsTrue(secondPerson.NewSticksHolded == 18);
            Assert.IsTrue(thirdPerson.NewSticksHolded == 17);
            Assert.IsTrue(fourthPerson.NewSticksHolded == 18);
            Assert.IsTrue(fifthPerson.NewSticksHolded == 34);
            Assert.IsTrue(sixthPerson.NewSticksHolded == 28);
        }
Example #5
0
        public void TestSplitFirst()
        {
            var engine = new Engine();

            engine.LoadYaml("../../../fixtures/sink11.yaml", true);
            Assert.NotNull(engine.World);
            engine.World.Time.Restart();

            var stock1 = engine.World.Map.Cells[1, 0];
            var sink1  = engine.World.Map.Cells[0, 0];
            var sink2  = engine.World.Map.Cells[2, 0];

            Assert.AreEqual(300.0f, stock1.GetStock("coal"));
            Assert.AreEqual("sink", sink1.Jm2.Id);
            Assert.AreEqual("sink", sink2.Jm2.Id);

            foreach (var cell in engine.World.Map.Cells)
            {
                ((Cell)cell).StepPrepare((Time)engine.World.Time);
            }

            var allocator =
                Allocator.Allocate((Time)engine.World.Time, engine.World.Resources, (Map)engine.World.Map);
            var allocation = allocator.Allocations["coal"];

            // D1 demand:
            Assert.AreEqual(100.0f, allocation.AllocationTable[0, 0]);
            Assert.AreEqual(200.0f, allocation.AllocationTable[1, 0]);

            engine.World.Time.Step();

            Assert.AreEqual(0.0f, stock1.GetStock("coal"));
            Assert.AreEqual(33, Math.Round((double)sink1.Jm2.Efficiency * 100.0));
            Assert.AreEqual(33, Math.Round((double)sink2.Jm2.Efficiency * 100.0));
        }
Example #6
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private void writeScanUpdatesToTree(RecordingConflictDetector<KEY,VALUE> recordingConflictDetector, org.neo4j.kernel.impl.index.schema.ByteBufferFactory.Allocator allocator, int bufferSize) throws java.io.IOException, org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException
        private void WriteScanUpdatesToTree(RecordingConflictDetector <KEY, VALUE> recordingConflictDetector, Allocator allocator, int bufferSize)
        {
            using (MergingBlockEntryReader <KEY, VALUE> allEntries = new MergingBlockEntryReader <KEY, VALUE>(layout))
            {
                ByteBuffer singleBlockAssertionBuffer = allocator.Allocate(( int )kibiBytes(8));
                foreach (ThreadLocalBlockStorage part in _allScanUpdates)
                {
                    using (BlockReader <KEY, VALUE> reader = part.BlockStorage.reader())
                    {
                        BlockEntryReader <KEY, VALUE> singleMergedBlock = reader.NextBlock(allocator.Allocate(bufferSize));
                        if (singleMergedBlock != null)
                        {
                            allEntries.AddSource(singleMergedBlock);
                            // Pass in some sort of ByteBuffer here. The point is that there should be no more data to read,
                            // if there is then it's due to a bug in the code and must be fixed.
                            if (reader.NextBlock(singleBlockAssertionBuffer) != null)
                            {
                                throw new System.InvalidOperationException("Final BlockStorage had multiple blocks");
                            }
                        }
                    }
                }

                int asMuchAsPossibleToTheLeft = 1;
                using (Writer <KEY, VALUE> writer = tree.writer(asMuchAsPossibleToTheLeft))
                {
                    while (allEntries.Next() && !_cancellation.cancelled())
                    {
                        WriteToTree(writer, recordingConflictDetector, allEntries.Key(), allEntries.Value());
                        _numberOfAppliedScanUpdates++;
                    }
                }
            }
        }
        public NativeString(char *pointer, int length, Allocator allocator)
        {
            if (pointer == null && length == 0)
            {
                this = default;
                return;
            }

            if (pointer == null)
            {
                throw new ArgumentException("pointer is null");
            }

            if (length <= 0)
            {
                throw new ArgumentException("length cannot be negative or zero");
            }

            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("Allocator is not in cache");
            }

            char *buffer = allocator.Allocate <char>(length);

            Unsafe.CopyBlockUnaligned(buffer, pointer, (uint)(sizeof(char) * length));
            _buffer      = buffer;
            _length      = length;
            _allocatorID = allocator.ID;
        }
Example #8
0
        public void TestSinksNearest()
        {
            var engine = new Engine();

            engine.LoadYaml("../../../fixtures/sink15.yaml", true);
            Assert.NotNull(engine.World);
            engine.World.Time.Restart();

            var stock1 = engine.World.Map.Cells[1, 0];
            var sink1  = engine.World.Map.Cells[0, 0];
            var sink2  = engine.World.Map.Cells[3, 0];

            Assert.AreEqual(100.0f, stock1.GetStock("coal"));
            Assert.AreEqual("sink", sink1.Jm2.Id);
            Assert.AreEqual("sink", sink2.Jm2.Id);

            foreach (var cell in engine.World.Map.Cells)
            {
                ((Cell)cell).StepPrepare((Time)engine.World.Time);
            }

            var allocator =
                Allocator.Allocate((Time)engine.World.Time, engine.World.Resources, (Map)engine.World.Map);
            var allocation = allocator.Allocations["coal"];

            // D1 demand:
            Assert.AreEqual(50.0f, allocation.AllocationTable[0, 0]);
            // D2 demand:
            Assert.AreEqual(50.0f, allocation.AllocationTable[1, 0]);
        }
Example #9
0
        /// <summary>
        /// Checks whether the buffer size for a file about to be loaded is sufficient and
        /// conditonally returns an address to a new buffer with adequate size.
        /// </summary>
        /// <returns>The address of a new buffer for the game to decompress a file to</returns>
        private static void *CheckBufferSize(int fileIndex, void *addressToDecompressTo, ONEFILE *thisPointer)
        {
            if (fileIndex >= 2)
            {
                // Get pointer and length.
                IntPtr onePointer = (IntPtr)thisPointer[0].InternalDataPointer - 0xC; // The start of file pointer is sometimes unused, so we use the InternalDataPointer instead and offset.
                int    fileLength = thisPointer[0].FileLength;

                // Now the ONE File
                MemoryONEArchive memoryOneFile = MemoryONEArchive.ParseONEFromMemory(onePointer, fileLength);

                // Now we estimate the size of it.
                int           actualFileIndex = fileIndex - 2;
                MemoryONEFile oneFile         = memoryOneFile.Files[actualFileIndex];
                byte[]        oneFileCopy     = GameProcess.ReadMemory((IntPtr)oneFile.CompressedDataPointer, oneFile.DataLength);
                int           oneFileLength   = Prs.Estimate(ref oneFileCopy);

                // Check if the size of allocation is sufficient.
                MemoryAddressDetails addressDetails = Allocator.GetAddressDetails((int)addressToDecompressTo);

                if (addressDetails.MemorySize < oneFileLength)
                {
                    // Allocate some new data for me please
                    addressToDecompressTo = (void *)Allocator.Allocate((int)addressToDecompressTo, oneFileLength);
                }
            }

            return(addressToDecompressTo);
        }
Example #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeDeque{T}"/> struct.
        /// </summary>
        /// <param name="elements">The elements.</param>
        /// <param name="allocator">The allocator.</param>
        /// <exception cref="ArgumentException">If the allocator is no in cache.
        public NativeDeque(Span <T> elements, Allocator allocator)
        {
            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("Allocator is not in cache.", nameof(allocator));
            }

            if (elements.IsEmpty)
            {
                this = default;
            }
            else
            {
                int length = elements.Length;
                _buffer = allocator.Allocate <T>(length);

                void *source = Unsafe.AsPointer(ref elements.GetPinnableReference());
                Unsafe.CopyBlock(_buffer, source, (uint)(sizeof(T) * length));
                _capacity    = length;
                _count       = length;
                _allocatorID = allocator.ID;
                _head        = 0;
                _tail        = _capacity - 1;
            }
        }
Example #11
0
        public NativeQuery <T> Take(int count)
        {
            if (_length == 0)
            {
                return(new NativeQuery <T>(GetAllocator()));
            }

            if (count == 0)
            {
                var emptyQuery = new NativeQuery <T>(GetAllocator());
                Dispose();
                return(emptyQuery);
            }

            if (count < 0)
            {
                Dispose();
                throw new ArgumentException(count.ToString(), nameof(count));
            }

            int       length    = count >= _length ? _length : count;
            Allocator allocator = GetAllocator() !;
            void *    src       = _buffer;
            void *    dst       = allocator.Allocate <T>(length);

            Unsafe.CopyBlockUnaligned(dst, src, (uint)(sizeof(T) * length));
            Dispose();
            return(new NativeQuery <T>(dst, length, allocator));
        }
        private NativeStack(ref NativeStack <T> stack)
        {
            Debug.Assert(stack.IsValid);

            Allocator allocator = stack.GetAllocator() !;
            T *       buffer    = allocator.Allocate <T>(stack._capacity);

            Unsafe.CopyBlockUnaligned(buffer, stack._buffer, (uint)(sizeof(T) * stack._capacity));

            _buffer      = buffer;
            _capacity    = stack._capacity;
            _count       = stack._count;
            _allocatorID = stack._allocatorID;
        }
        /// <summary>
        /// Gets a <see cref="NativeQuery{T}"/> with the default value if this query is empty, otherwise get the same query.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        /// <param name="query">The query.</param>
        /// <param name="defaultValue">The default value.</param>
        /// <returns>A query with the default value if empty, otherwise the same query will be returned.</returns>
        public static NativeQuery <T> DefaultIfEmpty <T>(this NativeQuery <T> query, T defaultValue) where T : unmanaged
        {
            if (query.IsEmpty)
            {
                unsafe
                {
                    Allocator allocator = query.GetAllocator() ?? Allocator.Default;
                    T *       value     = allocator.Allocate <T>(1);
                    *         value     = defaultValue;
                    return(new NativeQuery <T>(value, 1, allocator));
                }
            }

            return(query);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeArray{T}" /> struct.
        /// </summary>
        /// <param name="capacity">The capacity of the array.</param>
        /// <param name="allocator">The allocator used for this array.</param>
        public NativeArray(int capacity, Allocator allocator)
        {
            if (capacity <= 0)
            {
                throw new ArgumentException($"capacity must be greater than 0: {capacity}");
            }

            if (allocator.ID <= 0)
            {
                throw new ArgumentException("Allocator is not in cache.", "allocator");
            }

            _buffer      = allocator.Allocate <T>(capacity);
            _capacity    = capacity;
            _allocatorID = allocator.ID;
        }
Example #15
0
        private NativeDeque(ref NativeDeque <T> deque)
        {
            Debug.Assert(deque.IsValid);

            Allocator allocator = deque.GetAllocator() !;
            T *       buffer    = allocator.Allocate <T>(deque._capacity);

            Unsafe.CopyBlockUnaligned(buffer, deque._buffer, (uint)(sizeof(T) * deque._capacity));

            _buffer      = buffer;
            _count       = deque._count;
            _capacity    = deque._capacity;
            _allocatorID = deque._allocatorID;
            _head        = deque._head;
            _tail        = deque._tail;
        }
        private NativeString(ref NativeString str)
        {
            if (!str.IsValid)
            {
                throw new ArgumentException("string is invalid");
            }

            Allocator allocator = str.GetAllocator() !;
            char *    buffer    = allocator.Allocate <char>(str._length);

            Unsafe.CopyBlockUnaligned(buffer, str._buffer, (uint)(sizeof(char) * str._length));

            _buffer      = buffer;
            _length      = str._length;
            _allocatorID = str._allocatorID;
        }
Example #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeQueue{T}"/> struct.
        /// </summary>
        /// <param name="initialCapacity">The initial capacity.</param>
        /// <param name="allocator">The allocator.</param>
        /// <exception cref="ArgumentException">capacity must be greater than 0: {initialCapacity}</exception>
        public NativeQueue(int initialCapacity, Allocator allocator)
        {
            if (initialCapacity <= 0)
            {
                throw new ArgumentException($"capacity must be greater than 0: {initialCapacity}");
            }

            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("Allocator is not in cache.", nameof(allocator));
            }

            _buffer      = (T *)allocator.Allocate(initialCapacity, sizeof(T));
            _capacity    = initialCapacity;
            _count       = _head = _tail = 0;
            _allocatorID = allocator.ID;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeBuffer"/> struct.
        /// </summary>
        /// <param name="bytesCount">The number of bytes to allocate.</param>
        /// <param name="allocator">The allocator.</param>
        /// <exception cref="ArgumentException">If bytes count is negative or zero, or the allocator is not in cache.</exception>
        public NativeBuffer(int bytesCount, Allocator allocator)
        {
            if (bytesCount <= 0)
            {
                throw new ArgumentException("bytesCount cannot be negative or zero");
            }

            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("The allocator is not in cache");
            }

            _buffer      = (byte *)allocator.Allocate(bytesCount);
            _length      = bytesCount;
            _offset      = 0;
            _allocatorID = allocator.ID;
        }
Example #19
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeList{T}"/> struct.
        /// </summary>
        /// <param name="initialCapacity">The initial capacity of the list.</param>
        /// <param name="allocator">The allocator used for this list.</param>
        /// <exception cref="ArgumentException">If the capacity is negative or zero.</exception>
        public NativeList(int initialCapacity, Allocator allocator)
        {
            if (initialCapacity <= 0)
            {
                throw new ArgumentException($"initialCapacity should be greater than 0: {initialCapacity}");
            }

            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("Allocator is not in cache.", nameof(allocator));
            }

            _buffer      = allocator.Allocate <T>(initialCapacity);
            _capacity    = initialCapacity;
            _count       = 0;
            _allocatorID = allocator.ID;
        }
        private static void *AllocateCopy <T>(void *pointer, int elementCount, Allocator allocator) where T : unmanaged
        {
            if (pointer == null)
            {
                throw new ArgumentException("pointer is null");
            }

            if (elementCount <= 0)
            {
                throw new ArgumentException($"elementCount cannot be negative or 0: {elementCount}");
            }

            void *destination = allocator.Allocate <T>(elementCount);

            Unsafe.CopyBlockUnaligned(destination, pointer, (uint)(sizeof(T) * elementCount));
            return(destination);
        }
Example #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeSortedSet{T}"/> struct.
        /// </summary>
        /// <param name="initialCapacity">The initial capacity.</param>
        /// <param name="allocator">The allocator.</param>
        /// <exception cref="System.ArgumentException">If the initialCapacity is negative or zero, or the allocator is not in cache.</exception>
        public NativeSortedSet(int initialCapacity, Allocator allocator)
        {
            if (initialCapacity <= 0)
            {
                throw new ArgumentException("initialCapacity cannot be negative or zero", nameof(initialCapacity));
            }

            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("allocator is not in cache", nameof(allocator));
            }

            _buffer      = allocator.Allocate <T>(initialCapacity);
            _capacity    = initialCapacity;
            _allocatorID = allocator.ID;
            _count       = 0;
        }
Example #22
0
        private NativeMultiValueMap(ref NativeMultiValueMap <TKey, TValue> multiValueMap)
        {
            Debug.Assert(multiValueMap.IsValid);

            Allocator allocator   = multiValueMap.GetAllocator() !;
            int       slots       = multiValueMap.Slots;
            int       sizeOfEntry = sizeof(NativeMap <TKey, NativeList <TValue> > .Entry);
            var       buffer      = allocator.Allocate <NativeMap <TKey, NativeList <TValue> > .Entry>(slots);
            var       source      = multiValueMap._map._buffer;

            Unsafe.CopyBlockUnaligned(buffer, source, (uint)(sizeOfEntry * slots));

            for (int i = 0; i < slots; ++i)
            {
                ref var entry = ref buffer[i];
                if (entry.hashCode >= 0)
                {
                    entry.value = entry.value.Clone();
                }
            }
Example #23
0
        private static void AllocateServer(List <Server> servers)
        {
            Allocator allocator = new Allocator(servers);

            try
            {
                var allocatedServer = allocator.Allocate();
                if (allocatedServer != null)
                {
                    Console.WriteLine($"New connection from Server{allocatedServer?.Id + 1}.");
                }
                else
                {
                    Console.WriteLine("Server not found.");
                }
            }
            catch (Exception)
            {
                Console.WriteLine("Server not found.");
            }
        }
Example #24
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeSet{T}"/> struct.
        /// </summary>
        /// <param name="initialCapacity">The initial capacity.</param>
        /// <param name="allocator">The allocator.</param>
        /// <exception cref="ArgumentException">If the capacity is negative or 0, or if the allocator is not in cache.</exception>
        public NativeSet(int initialCapacity, Allocator allocator)
        {
            if (initialCapacity <= 0)
            {
                throw new ArgumentException("initialCapacity should be greater than 0.", nameof(initialCapacity));
            }

            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("Allocator is not in cache.", nameof(allocator));
            }

            _buffer      = (Slot *)allocator.Allocate(initialCapacity, sizeof(Slot));
            _capacity    = initialCapacity;
            _count       = 0;
            _freeList    = -1;
            _freeCount   = 0;
            _allocatorID = allocator.ID;

            Initializate();
        }
Example #25
0
        public NativeQuery <TResult> Select <TResult>(Func <T, TResult> selector) where TResult : unmanaged
        {
            if (_length == 0)
            {
                return(new NativeQuery <TResult>(GetAllocator()));
            }

            int        length     = _length;
            Allocator  allocator  = GetAllocator() !;
            TResult *  buffer     = allocator.Allocate <TResult>(length);
            Enumerator enumerator = GetEnumerator(disposing: false);

            int i = 0;

            foreach (ref var e in this)
            {
                buffer[i++] = selector(e);
            }

            return(new NativeQuery <TResult>(buffer, length, allocator));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NativeStack{T}"/> struct.
        /// </summary>
        /// <param name="elements">The initial elements.</param>
        /// <param name="allocator">The allocator.</param>
        public NativeStack(Span <int> elements, Allocator allocator)
        {
            if (Allocator.IsCached(allocator) is false)
            {
                throw new ArgumentException("Allocator is not in cache.", nameof(allocator));
            }

            if (elements.IsEmpty)
            {
                this = default;
            }
            else
            {
                _buffer      = allocator.Allocate <T>(elements.Length);
                _capacity    = elements.Length;
                _count       = _capacity;
                _allocatorID = allocator.ID;

                void *source = Unsafe.AsPointer(ref MemoryMarshal.GetReference(elements));
                Unsafe.CopyBlock(_buffer, source, (uint)(sizeof(T) * _capacity));
            }
        }
        public void VarianceDistributionIsMinimum()
        {
            Person firstPerson
                = new Person(1, 5);
            Person secondPerson
                = new Person(1, 6);
            Person thirdPerson
                = new Person(1, 8);

            List <Person> collectors = new List <Person>()
            {
                firstPerson, secondPerson, thirdPerson
            };

            Allocator allocator = new Allocator();

            allocator.Allocate(50, collectors);

            Assert.IsTrue(firstPerson.NewSticksHolded == 18);
            Assert.IsTrue(secondPerson.NewSticksHolded == 17);
            Assert.IsTrue(thirdPerson.NewSticksHolded == 15);
        }
        public void Second_VarianceDistributionIsBigTest()
        {
            Person firstPerson
                = new Person(1, 50);
            Person secondPerson
                = new Person(1, 0);
            Person thirdPerson
                = new Person(1, 0);

            List <Person> collectors = new List <Person>()
            {
                firstPerson, secondPerson, thirdPerson
            };

            Allocator allocator = new Allocator();

            allocator.Allocate(60, collectors);

            Assert.IsTrue(firstPerson.NewSticksHolded == 50);
            Assert.IsTrue(secondPerson.NewSticksHolded == 30);
            Assert.IsTrue(thirdPerson.NewSticksHolded == 30);
        }
        /// <summary>
        /// Gets a <see cref="NativeQuery{T}"/> with the default values if this query is empty, otherwise get the same query.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        /// <param name="query">The query.</param>
        /// <param name="defaultValues">The default values.</param>
        /// <returns>A query with the default value if empty, otherwise the same query will be returned.</returns>
        public static NativeQuery <T> DefaultIfEmpty <T>(this NativeQuery <T> query, Span <T> defaultValues) where T : unmanaged
        {
            if (query.IsEmpty)
            {
                if (defaultValues.IsEmpty)
                {
                    return(new NativeQuery <T>(query.GetAllocator()));
                }

                unsafe
                {
                    int       length    = defaultValues.Length;
                    Allocator allocator = query.GetAllocator() ?? Allocator.Default;
                    T *       buffer    = allocator.Allocate <T>(length);
                    void *    src       = Unsafe.AsPointer(ref defaultValues[0]);
                    Unsafe.CopyBlockUnaligned(buffer, src, (uint)(sizeof(T) * length));
                    return(new NativeQuery <T>(buffer, length, allocator));
                }
            }

            return(query);
        }
Example #30
0
        public static void TestChurnStability()
        {
            var   allocator = new Allocator(2048);
            var   random    = new Random(5);
            ulong idCounter = 0;
            var   pool      = new PassthroughArrayPool <ulong>();

            QuickList <ulong, Array <ulong> > .Create(pool, 8, out var allocatedIds);

            QuickList <ulong, Array <ulong> > .Create(pool, 8, out var unallocatedIds);

            for (int i = 0; i < 512; ++i)
            {
                long start;
                var  id = idCounter++;
                //allocator.ValidatePointers();
                if (allocator.Allocate(id, 1 + random.Next(5), out start))
                {
                    allocatedIds.Add(id, pool);
                }
                else
                {
                    unallocatedIds.Add(id, pool);
                }
                //allocator.ValidatePointers();
            }
            for (int timestepIndex = 0; timestepIndex < 100000; ++timestepIndex)
            {
                //First add and remove a bunch randomly.
                for (int i = random.Next(Math.Min(allocatedIds.Count, 15)); i >= 0; --i)
                {
                    var indexToRemove = random.Next(allocatedIds.Count);
                    //allocator.ValidatePointers();
                    var deallocated = allocator.Deallocate(allocatedIds[indexToRemove]);
                    Debug.Assert(deallocated);
                    //allocator.ValidatePointers();
                    unallocatedIds.Add(allocatedIds[indexToRemove], pool);
                    allocatedIds.FastRemoveAt(indexToRemove);
                }
                for (int i = random.Next(Math.Min(unallocatedIds.Count, 15)); i >= 0; --i)
                {
                    var indexToAllocate = random.Next(unallocatedIds.Count);
                    //allocator.ValidatePointers();
                    if (allocator.Allocate(unallocatedIds[indexToAllocate], random.Next(3), out long start))
                    {
                        //allocator.ValidatePointers();
                        allocatedIds.Add(unallocatedIds[indexToAllocate], pool);
                        unallocatedIds.FastRemoveAt(indexToAllocate);
                    }
                    //allocator.ValidatePointers();
                }
                //Check to ensure that everything's still coherent.
                for (int i = 0; i < allocatedIds.Count; ++i)
                {
                    Debug.Assert(allocator.Contains(allocatedIds[i]));
                }
                for (int i = 0; i < unallocatedIds.Count; ++i)
                {
                    Debug.Assert(!allocator.Contains(unallocatedIds[i]));
                }
            }
            //Wind it down.
            for (int i = 0; i < allocatedIds.Count; ++i)
            {
                var deallocated = allocator.Deallocate(allocatedIds[i]);
                Debug.Assert(deallocated);
            }
            //Confirm cleanup.
            for (int i = 0; i < allocatedIds.Count; ++i)
            {
                Debug.Assert(!allocator.Contains(allocatedIds[i]));
            }
            for (int i = 0; i < unallocatedIds.Count; ++i)
            {
                Debug.Assert(!allocator.Contains(unallocatedIds[i]));
            }
        }