/// <summary> /// Allocates a new SPSCRingbuffer. Capacity will be set to a power of 2. /// </summary> public static UnsafeSPSCQueue *Allocate <T>(int capacity) where T : unmanaged { if (capacity < 1) { throw new ArgumentOutOfRangeException(nameof(capacity), string.Format(ThrowHelper.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } // Requires one extra element to distinguish between empty and full queue. capacity++; int stride = sizeof(T); var alignment = Memory.GetAlignment(stride); var sizeOfQueue = Memory.RoundToAlignment(sizeof(UnsafeSPSCQueue), alignment); var sizeOfArray = stride * capacity; var ptr = Memory.MallocAndZero(sizeOfQueue + sizeOfArray, alignment); UnsafeSPSCQueue *queue = (UnsafeSPSCQueue *)ptr; // initialize fixed buffer from same block of memory as the stack UnsafeBuffer.InitFixed(&queue->_items, (byte *)ptr + sizeOfQueue, capacity, stride); queue->_headAndTail = new HeadAndTail(); queue->_typeHandle = typeof(T).TypeHandle.Value; return(queue); }
public static UnsafeRingBuffer *Allocate <T>(int capacity, bool overwrite) where T : unmanaged { if (capacity < 1) { throw new ArgumentOutOfRangeException(nameof(capacity), string.Format(ThrowHelper.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } int stride = sizeof(T); // fixedSize means we are allocating the memory for the collection header and the items in it as one block var alignment = Memory.GetAlignment(stride); // align header size to the elements alignment var sizeOfHeader = Memory.RoundToAlignment(sizeof(UnsafeRingBuffer), alignment); var sizeOfBuffer = stride * capacity; // allocate memory for list and array with the correct alignment var ptr = Memory.MallocAndZero(sizeOfHeader + sizeOfBuffer, alignment); // grab header ptr var ring = (UnsafeRingBuffer *)ptr; // initialize fixed buffer from same block of memory as the collection, offset by sizeOfHeader UnsafeBuffer.InitFixed(&ring->_items, (byte *)ptr + sizeOfHeader, capacity, stride); // initialize count to 0 ring->_count = 0; ring->_overwrite = overwrite ? 1 : 0; ring->_typeHandle = typeof(T).TypeHandle.Value; return(ring); }
public static UnsafeHashSet *Allocate <T>(int capacity, bool fixedSize = false) where T : unmanaged, IEquatable <T> { var valStride = sizeof(T); var entryStride = sizeof(UnsafeHashCollection.Entry); // round capacity up to next prime capacity = UnsafeHashCollection.GetNextPrime(capacity); var valAlignment = Memory.GetAlignment(valStride); // the alignment for entry/key/val, we can't have less than ENTRY_ALIGNMENT // bytes alignment because entries are 16 bytes with 1 x pointer + 2 x 4 byte integers var alignment = Math.Max(UnsafeHashCollection.Entry.ALIGNMENT, valAlignment); // calculate strides for all elements valStride = Memory.RoundToAlignment(valStride, alignment); entryStride = Memory.RoundToAlignment(sizeof(UnsafeHashCollection.Entry), alignment); // dictionary ptr UnsafeHashSet *set; if (fixedSize) { var sizeOfHeader = Memory.RoundToAlignment(sizeof(UnsafeHashSet), alignment); var sizeOfBucketsBuffer = Memory.RoundToAlignment(sizeof(UnsafeHashCollection.Entry * *) * capacity, alignment); var sizeofEntriesBuffer = (entryStride + valStride) * capacity; // allocate memory var ptr = Memory.MallocAndZero(sizeOfHeader + sizeOfBucketsBuffer + sizeofEntriesBuffer, alignment); // start of memory is the dict itself set = (UnsafeHashSet *)ptr; // buckets are offset by header size set->_collection.Buckets = (UnsafeHashCollection.Entry * *)((byte *)ptr + sizeOfHeader); // initialize fixed buffer UnsafeBuffer.InitFixed(&set->_collection.Entries, (byte *)ptr + (sizeOfHeader + sizeOfBucketsBuffer), capacity, entryStride + valStride); } else { // allocate dict, buckets and entries buffer separately set = Memory.MallocAndZero <UnsafeHashSet>(); set->_collection.Buckets = (UnsafeHashCollection.Entry * *)Memory.MallocAndZero(sizeof(UnsafeHashCollection.Entry * *) * capacity, sizeof(UnsafeHashCollection.Entry * *)); // init dynamic buffer UnsafeBuffer.InitDynamic(&set->_collection.Entries, capacity, entryStride + valStride); } set->_collection.FreeCount = 0; set->_collection.UsedCount = 0; set->_collection.KeyOffset = entryStride; set->_typeHandle = typeof(T).TypeHandle.Value; return(set); }
int _valueOffset; // Readonly public static UnsafeSortedDictionary *Allocate <K, V>(int capacity, bool fixedSize = false) where K : unmanaged, IComparable <K> where V : unmanaged { var keyStride = sizeof(K); var valStride = sizeof(V); var entryStride = sizeof(UnsafeHashCollection.Entry); var keyAlignment = Memory.GetAlignment(keyStride); var valAlignment = Memory.GetAlignment(valStride); var alignment = Math.Max(UnsafeHashCollection.Entry.ALIGNMENT, Math.Max(keyAlignment, valAlignment)); keyStride = Memory.RoundToAlignment(keyStride, alignment); valStride = Memory.RoundToAlignment(valStride, alignment); entryStride = Memory.RoundToAlignment(sizeof(UnsafeHashCollection.Entry), alignment); var totalStride = keyStride + valStride + entryStride; UnsafeSortedDictionary *map; if (fixedSize) { var sizeOfHeader = Memory.RoundToAlignment(sizeof(UnsafeDictionary), alignment); var sizeOfBucketsBuffer = Memory.RoundToAlignment(sizeof(UnsafeHashCollection.Entry * *) * capacity, alignment); var sizeofEntriesBuffer = totalStride * capacity; // allocate memory var ptr = Memory.MallocAndZero(sizeOfHeader + sizeOfBucketsBuffer + sizeofEntriesBuffer, alignment); map = (UnsafeSortedDictionary *)ptr; UnsafeBuffer.InitFixed(&map->_collection.Entries, (byte *)ptr + (sizeOfHeader + sizeOfBucketsBuffer), capacity, totalStride); } else { map = Memory.MallocAndZero <UnsafeSortedDictionary>(); UnsafeBuffer.InitDynamic(&map->_collection.Entries, capacity, totalStride); } // header init map->_collection.FreeCount = 0; map->_collection.UsedCount = 0; map->_collection.KeyOffset = entryStride; map->_typeHandleKey = typeof(K).TypeHandle.Value; map->_typeHandleValue = typeof(V).TypeHandle.Value; map->_valueOffset = entryStride + keyStride; return(map); }
public static UnsafeSortedSet *Allocate <T>(int capacity, bool fixedSize = false) where T : unmanaged, IComparable <T> { var valStride = sizeof(T); var entryStride = sizeof(UnsafeOrderedCollection.Entry); var valAlignment = Memory.GetAlignment(valStride); // the alignment for entry/key/val, we can't have less than ENTRY_ALIGNMENT // bytes alignment because entries are 12 bytes with 3 x 32 bit integers var alignment = Math.Max(UnsafeOrderedCollection.Entry.ALIGNMENT, valAlignment); // calculate strides for all elements valStride = Memory.RoundToAlignment(valStride, alignment); entryStride = Memory.RoundToAlignment(entryStride, alignment); // dictionary ptr UnsafeSortedSet *set; if (fixedSize) { var sizeOfHeader = Memory.RoundToAlignment(sizeof(UnsafeSortedSet), alignment); var sizeofEntriesBuffer = (entryStride + valStride) * capacity; // allocate memory var ptr = Memory.MallocAndZero(sizeOfHeader + sizeofEntriesBuffer, alignment); // start of memory is the set itself set = (UnsafeSortedSet *)ptr; // initialize fixed buffer UnsafeBuffer.InitFixed(&set->_collection.Entries, (byte *)ptr + sizeOfHeader, capacity, entryStride + valStride); } else { // allocate set separately set = Memory.MallocAndZero <UnsafeSortedSet>(); // init dynamic buffer UnsafeBuffer.InitDynamic(&set->_collection.Entries, capacity, entryStride + valStride); } set->_collection.FreeCount = 0; set->_collection.UsedCount = 0; set->_collection.KeyOffset = entryStride; set->_typeHandle = typeof(T).TypeHandle.Value; return(set); }
public static UnsafeStack *Allocate <T>(int capacity, bool fixedSize = false) where T : unmanaged { if (capacity < 1) { throw new ArgumentOutOfRangeException(nameof(capacity), string.Format(ThrowHelper.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } var stride = sizeof(T); UnsafeStack *stack; // fixedSize stack means we are allocating the memory // for the stack header and the items in it as one block if (fixedSize) { var alignment = Memory.GetAlignment(stride); // align stack header size to the elements alignment var sizeOfStack = Memory.RoundToAlignment(sizeof(UnsafeStack), alignment); var sizeOfArray = stride * capacity; // allocate memory for stack and array with the correct alignment var ptr = Memory.MallocAndZero(sizeOfStack + sizeOfArray, alignment); // grab stack ptr stack = (UnsafeStack *)ptr; // initialize fixed buffer from same block of memory as the stack UnsafeBuffer.InitFixed(&stack->_items, (byte *)ptr + sizeOfStack, capacity, stride); } // dynamic sized stack means we're allocating the stack header // and its memory separately else { // allocate stack separately stack = Memory.MallocAndZero <UnsafeStack>(); // initialize dynamic buffer with separate memory UnsafeBuffer.InitDynamic(&stack->_items, capacity, stride); } // just safety, make sure count is 0 stack->_count = 0; stack->_typeHandle = typeof(T).TypeHandle.Value; return(stack); }
public static UnsafeQueue *Allocate <T>(int capacity, bool fixedSize = false) where T : unmanaged { if (capacity < 1) { throw new ArgumentOutOfRangeException(nameof(capacity), string.Format(ThrowHelper.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } int stride = sizeof(T); UnsafeQueue *queue; // fixedSize queue means we are allocating the memory for the header and the items in it as one block if (fixedSize) { var alignment = Memory.GetAlignment(stride); var sizeOfQueue = Memory.RoundToAlignment(sizeof(UnsafeQueue), alignment); var sizeOfArray = stride * capacity; var ptr = Memory.MallocAndZero(sizeOfQueue + sizeOfArray, alignment); // cast ptr to queue queue = (UnsafeQueue *)ptr; // initialize fixed buffer from same block of memory as the stack UnsafeBuffer.InitFixed(&queue->_items, (byte *)ptr + sizeOfQueue, capacity, stride); } // dynamic sized queue means we're allocating the stack header and its memory separately else { // allocate memory for queue queue = Memory.MallocAndZero <UnsafeQueue>(); // initialize dynamic buffer with separate memory UnsafeBuffer.InitDynamic(&queue->_items, capacity, stride); } queue->_head = 0; queue->_tail = 0; queue->_count = 0; queue->_typeHandle = typeof(T).TypeHandle.Value; return(queue); }
public static UnsafeList *Allocate <T>(int capacity, bool fixedSize = false) where T : unmanaged { if (capacity < 1) { throw new ArgumentOutOfRangeException(nameof(capacity), string.Format(ThrowHelper.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } int stride = sizeof(T); UnsafeList *list; // fixedSize means we are allocating the memory for the collection header and the items in it as one block if (fixedSize) { var alignment = Memory.GetAlignment(stride); // align header size to the elements alignment var sizeOfHeader = Memory.RoundToAlignment(sizeof(UnsafeList), alignment); var sizeOfBuffer = stride * capacity; // allocate memory for list and array with the correct alignment var ptr = Memory.MallocAndZero(sizeOfHeader + sizeOfBuffer); // grab header ptr list = (UnsafeList *)ptr; // initialize fixed buffer from same block of memory as the collection, offset by sizeOfHeader UnsafeBuffer.InitFixed(&list->_items, (byte *)ptr + sizeOfHeader, capacity, stride); } else { // allocate collection separately list = Memory.MallocAndZero <UnsafeList>(); // initialize dynamic buffer with separate memory UnsafeBuffer.InitDynamic(&list->_items, capacity, stride); } list->_count = 0; list->_typeHandle = typeof(T).TypeHandle.Value; return(list); }
int _slotOffset; // Readonly /// <summary> /// Allocates a new SPSCRingbuffer. Capacity will be set to a power of 2. /// </summary> public static UnsafeMPSCQueue *Allocate <T>(int capacity) where T : unmanaged { if (capacity < 1) { throw new ArgumentOutOfRangeException(nameof(capacity), string.Format(ThrowHelper.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } capacity = Memory.RoundUpToPowerOf2(capacity); // Required to get the memory size of the Slot + Value int slotStride = Marshal.SizeOf(new QueueSlot <T>()); int slotAlign = Memory.GetMaxAlignment(sizeof(T), sizeof(int)); int slotOffset = Memory.RoundToAlignment(sizeof(T), slotAlign); int alignment = Memory.GetAlignment(slotStride); var sizeOfQueue = Memory.RoundToAlignment(sizeof(UnsafeMPSCQueue), alignment); var sizeOfArray = slotStride * capacity; var ptr = Memory.MallocAndZero(sizeOfQueue + sizeOfArray, alignment); UnsafeMPSCQueue *queue = (UnsafeMPSCQueue *)ptr; // initialize fixed buffer from same block of memory as the stack UnsafeBuffer.InitFixed(&queue->_items, (byte *)ptr + sizeOfQueue, capacity, slotStride); // Read-only values queue->_mask = capacity - 1; queue->_slotOffset = slotOffset; queue->_typeHandle = typeof(T).TypeHandle.Value; // Reset the queue for use. Clear(queue); return(queue); }
int _valueOffset; // Readonly public static UnsafeDictionary *Allocate <K, V>(int capacity, bool fixedSize = false) where K : unmanaged, IEquatable <K> where V : unmanaged { var keyStride = sizeof(K); var valStride = sizeof(V); var entryStride = sizeof(UnsafeHashCollection.Entry); // round capacity up to next prime capacity = UnsafeHashCollection.GetNextPrime(capacity); var keyAlignment = Memory.GetAlignment(keyStride); var valAlignment = Memory.GetAlignment(valStride); // the alignment for entry/key/val, we can't have less than ENTRY_ALIGNMENT // bytes alignment because entries are 8 bytes with 2 x 32 bit integers var alignment = Math.Max(UnsafeHashCollection.Entry.ALIGNMENT, Math.Max(keyAlignment, valAlignment)); // calculate strides for all elements keyStride = Memory.RoundToAlignment(keyStride, alignment); valStride = Memory.RoundToAlignment(valStride, alignment); entryStride = Memory.RoundToAlignment(sizeof(UnsafeHashCollection.Entry), alignment); // map ptr UnsafeDictionary *map; if (fixedSize) { var sizeOfHeader = Memory.RoundToAlignment(sizeof(UnsafeDictionary), alignment); var sizeOfBucketsBuffer = Memory.RoundToAlignment(sizeof(UnsafeHashCollection.Entry * *) * capacity, alignment); var sizeofEntriesBuffer = (entryStride + keyStride + valStride) * capacity; // allocate memory var ptr = Memory.MallocAndZero(sizeOfHeader + sizeOfBucketsBuffer + sizeofEntriesBuffer, alignment); // start of memory is the dict itself map = (UnsafeDictionary *)ptr; // buckets are offset by header size map->_collection.Buckets = (UnsafeHashCollection.Entry * *)((byte *)ptr + sizeOfHeader); // initialize fixed buffer UnsafeBuffer.InitFixed(&map->_collection.Entries, (byte *)ptr + (sizeOfHeader + sizeOfBucketsBuffer), capacity, entryStride + keyStride + valStride); } else { // allocate dict, buckets and entries buffer separately map = Memory.MallocAndZero <UnsafeDictionary>(); map->_collection.Buckets = (UnsafeHashCollection.Entry * *)Memory.MallocAndZero(sizeof(UnsafeHashCollection.Entry * *) * capacity, sizeof(UnsafeHashCollection.Entry * *)); // init dynamic buffer UnsafeBuffer.InitDynamic(&map->_collection.Entries, capacity, entryStride + keyStride + valStride); } // header init map->_collection.FreeCount = 0; map->_collection.UsedCount = 0; map->_collection.KeyOffset = entryStride; map->_typeHandleKey = typeof(K).TypeHandle.Value; map->_typeHandleValue = typeof(V).TypeHandle.Value; map->_valueOffset = entryStride + keyStride; return(map); }