/// <summary> /// Returns a given span buffer back to the allocation pool /// </summary> /// <param name="buffer"></param> public void Return(ref TRexSpan <T> buffer) { if (!buffer.IsRented) { throw new TRexException("Buffer is not rented on return to pool"); } buffer.Count = 0; buffer.IsRented = false; #if CELLDEBUG buffer.IsReturned = true; #endif lock (_slabPagesLock) { if (_rentalTideLevel < 0) { // There is no more capacity to accept returns return; } // Note, buffer slab index in the span may not match the one it is being returned to, which is OK... _slabPages[_rentalTideLevel / SpanCountPerSlabPage].Arrays[_rentalTideLevel % SpanCountPerSlabPage] = buffer; _rentalTideLevel--; } }
/// <summary> /// Returns a given buffer back to the allocation pool /// </summary> /// <param name="buffer"></param> public void Return(ref TRexSpan <T> buffer) { if (!buffer.NeedsToBeReturned()) { return; } if (buffer.Capacity == 0) { // This is either a default initialized span, or the zero element. In both cases just ignore it return; } #if CELLDEBUG if (buffer.IsReturned) { throw new ArgumentException($"Buffer being return is not on rental: Offset = {buffer.Offset}, Count = {buffer.Count}, Capacity = {buffer.Capacity}"); } #endif // Find the appropriate pool and return an element from it var log2 = Utilities.Log2(buffer.Capacity) - 1; // Return the span to the pool if it is not the zero element _pools[log2].Return(ref buffer); }
/// <summary> /// Clones the content 'oldBuffer' by creating a new TRexSpan and copying the elements from oldBuffer into it /// </summary> /// <param name="oldBuffer"></param> /// <returns></returns> public TRexSpan <T> Clone(TRexSpan <T> oldBuffer) { #if CELLDEBUG if (oldBuffer.IsReturned) { throw new ArgumentException($"Buffer being cloned is not on rental: Offset = {oldBuffer.Offset}, Count = {oldBuffer.Count}, Capacity = {oldBuffer.Capacity}"); } #endif // Get a new buffer var newBuffer = Rent(oldBuffer.Count); newBuffer.Count = oldBuffer.Count; // Copy elements from the old buffer to the new buffer Array.Copy(oldBuffer.Elements, oldBuffer.Offset, newBuffer.Elements, newBuffer.Offset, oldBuffer.Count); // ... and return the newly resized result return(newBuffer); }
/// <summary> /// Copies a number of elements from the start of the source span to the start of the target span /// </summary> /// <param name="source"></param> /// <param name="sourceCount"></param> public void Copy(TRexSpan <T> source, int sourceCount) { #if CELLDEBUG if (!IsRented && SlabIndex != NO_SLAB_INDEX) { throw new Exception("Not rented!!!!"); } #endif if (sourceCount < 0 || sourceCount > source.Count) { throw new ArgumentException("Source count may not be negative or greater than the count of elements in the source"); } if (Capacity < sourceCount) { throw new ArgumentException($"Target has insufficient capacity ({Capacity}) to contain required items from source ({sourceCount})"); } Array.Copy(source.Elements, source.Offset, Elements, Offset, sourceCount); Count = source.Count; }