public void Resize(uint newSize, byte filler) { if (m_buffer == null) { ThrowAlreadyDisposed(); } if (newSize <= m_count) { m_count = newSize; } else { if (newSize > m_buffer.Length) { GrowBuffer(newSize); } // fill the extra space with zeroes uint pos = m_count; uint r = checked ((uint)m_buffer.Length - newSize); if (r > 0) { UnmanagedHelpers.FillUnsafe(this.Data + pos, r, 0); } m_count = newSize; } }
public byte[] GetBytes(uint offset, uint count) { Contract.Requires(this.Count >= 0); if (offset > this.Count) { throw new ArgumentOutOfRangeException("offset"); } if (offset + count >= this.Count) { throw new ArgumentOutOfRangeException("count"); } var tmp = new byte[count]; if (count > 0) { Contract.Assert(this.Data != null); fixed(byte *ptr = tmp) { UnmanagedHelpers.CopyUnsafe(ptr, this.Data + offset, count); } } return(tmp); }
private byte *AllocateInternal(uint size, bool zeroed) { if (m_buffer == null) { ThrowAlreadyDisposed(); } Contract.Requires(size != 0, "size == 0"); Contract.Assert(m_buffer != null && m_count <= m_buffer.Length, "Builder is corrupted"); uint remaining = checked (((uint)m_buffer.Length) - m_count); if (remaining < size) { GrowBuffer(m_count + size); } uint pos = m_count; m_count = pos + size; byte *ptr = this.Data + pos; if (zeroed) { UnmanagedHelpers.FillUnsafe(ptr, size, 0); } return(ptr); }
/// <summary>Return a builder into the pool</summary> /// <param name="builder">Builder that is no longer in use</param> internal void Return(UnmanagedSliceBuilder builder) { if (m_disposed || builder == null) { return; } lock (m_buckets) { if (m_disposed) { return; } var size = builder.Capacity; Contract.Assert(size == UnmanagedHelpers.NextPowerOfTwo(size), "builder size should always be a power of two"); Interlocked.Add(ref m_memoryLoaned, -((long)builder.Capacity)); Contract.Assert(m_memoryUsed >= 0, "m_memoryLoaned desync"); if (m_buckets.Count < m_maxCount) { m_buckets.Push(builder); Interlocked.Add(ref m_memoryUsed, builder.Capacity); } else { builder.Dispose(); } } }
public UnmanagedSliceBuilder(Slice slice) { if (slice.Count < 0 || slice.Offset < 0) { ThrowMalformedManagedSlice(); } uint size = (uint)slice.Count; if (size > 0) { if (slice.Array == null || slice.Array.Length < slice.Offset + slice.Count) { ThrowMalformedManagedSlice(); } GrowBuffer(size); fixed(byte *ptr = slice.Array) { UnmanagedHelpers.CopyUnsafe(this.Data, ptr + slice.Offset, size); } m_count = size; } }
public void Append(Slice source) { if (source.Count > 0) { if (source.Array == null || source.Offset < 0) { ThrowInvalidSource(); } var ptr = AllocateInternal((uint)source.Count, zeroed: false); Contract.Assert(ptr != null, "AllocateInternal() => null"); UnmanagedHelpers.CopyUnsafe(ptr, source); } }
public void Set(USlice source) { m_count = 0; if (source.Count > 0) { if (source.Data == null) { ThrowInvalidSource(); } var ptr = AllocateInternal(source.Count, zeroed: false); Contract.Assert(ptr != null); UnmanagedHelpers.CopyUnsafe(ptr, source); } }
public byte[] GetBytes() { Contract.Requires(this.Count >= 0); var tmp = new byte[this.Count]; if (this.Count > 0) { Contract.Assert(this.Data != null); fixed(byte *ptr = tmp) { UnmanagedHelpers.CopyUnsafe(ptr, this.Data, this.Count); } } return(tmp); }
/// <summary>Copy the content of an unmanaged slice of memory, using a specific alignment</summary> /// <param name="data">Slice of unmanaged memory to copy</param> /// <param name="align">Required memory alignment. MUST BE A POWER OF 2 !</param> /// <returns>New slice pointing to the copied bytes in the allocator memory. The start address should be aligned to either 4 or 8 bytes, depending on the platform architecture.</returns> private USlice Memoize(USlice data, uint align) { if (data.Count == 0) { return(default(USlice)); } byte *ptr = Allocate(data.Count, align); if (ptr == null) { throw new OutOfMemoryException(); } UnmanagedHelpers.CopyUnsafe(ptr, data); return(new USlice(ptr, data.Count)); }
public void Append(USlice source) { if (source.Count == 0) { return; } if (source.Data == null) { ThrowInvalidSource(); } byte *ptr = AllocateInternal(source.Count, zeroed: false); Contract.Assert(ptr != null); UnmanagedHelpers.CopyUnsafe(ptr, source); }
public void Append(byte *source, uint size) { if (size == 0) { return; } if (source == null) { ThrowInvalidSource(); } byte *ptr = AllocateInternal(size, zeroed: false); Contract.Assert(ptr != null, "AllocateInternal() => null"); UnmanagedHelpers.CopyUnsafe(ptr, source, size); }
public Page(int id, IntPtr handle, uint size) { Contract.Requires(handle != IntPtr.Zero && size > 0); m_id = id; m_handle = handle; m_size = size; m_begin = (byte *)handle; // fill with zeroes ! UnmanagedHelpers.FillUnsafe(m_begin, size, 0); GC.AddMemoryPressure(size); Contract.Ensures(m_handle != IntPtr.Zero && m_size > 0 && m_nextFree == 0); }
public byte[] ToArray() { if (m_begin == null) { ThrowDisposed(); } var tmp = new byte[m_size]; if (tmp.Length > 0) { fixed(byte *ptr = tmp) { UnmanagedHelpers.CopyUnsafe(ptr, m_begin, (uint)m_size); } } return(tmp); }
public UnmanagedSliceBuilder(byte *data, uint size) { if (data == null && size != 0) { throw new ArgumentNullException("data"); } if (size == 0) { m_buffer = s_empty; } else { GrowBuffer(size); UnmanagedHelpers.CopyUnsafe(m_data, data, size); m_count = size; } }
/// <summary>Copy a segment of the buffer to an unmanaged pointer, and return the corresponding slice</summary> /// <param name="count">Number of bytes to copy</param> /// <param name="dest">Destination pointer where the buffer will be copied. Caution: the destination buffer must be large enough!</param> /// <returns>Slice that points to the copied segment in the destination buffer</returns> internal USlice CopyTo(byte *dest, uint count) { if (m_buffer == null) { ThrowAlreadyDisposed(); } if (count == 0) { return(default(USlice)); } if (count > m_count) { throw new ArgumentOutOfRangeException("count"); } UnmanagedHelpers.CopyUnsafe(dest, m_data, count); return(new USlice(dest, count)); }
public bool Equals(USlice other) { if (this.Count != other.Count) { return(false); } if (this.Data == other.Data) { return(true); } if (this.Data == null || other.Data == null) { return(false); } //TODO: optimize! return(0 == UnmanagedHelpers.CompareUnsafe(this.Data, this.Count, other.Data, other.Count)); }
public byte[] GetBytes() { if (m_buffer == null) { ThrowAlreadyDisposed(); } var tmp = new byte[m_count]; if (m_count >= 0) { fixed(byte *ptr = tmp) { UnmanagedHelpers.CopyUnsafe(ptr, m_data, m_count); } } return(tmp); }
public override int Read(byte[] buffer, int offset, int count) { if (m_begin == null) { ThrowDisposed(); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || offset + count >= buffer.Length) { throw new ArgumentOutOfRangeException("count"); } uint pos = m_pos; if (pos >= m_size) { return(0); // EOF } uint chunk; checked { chunk = (uint)Math.Max(m_size - pos, count); } if (chunk > 0) { fixed(byte *ptr = buffer) { UnmanagedHelpers.CopyUnsafe(ptr + offset, m_begin + pos, chunk); } m_pos = pos + chunk; } return((int)chunk); }
/// <summary>Grow the buffer to be able to hold the specified number of bytes</summary> /// <param name="required">Minimum capacity required</param> /// <remarks>The buffer may be resize to more than <paramref name="required"/></remarks> private void GrowBuffer(uint required) { try { } finally { if (!m_handle.IsAllocated) { // initial allocation of the buffer uint newsize = UnmanagedHelpers.NextPowerOfTwo(Math.Max(required, DEFAULT_CAPACITY)); var buffer = new byte[newsize]; m_buffer = buffer; m_count = 0; } else { // resize an existing buffer uint newsize = (uint)m_buffer.Length; newsize = UnmanagedHelpers.NextPowerOfTwo(Math.Max(required, newsize << 1)); if (newsize > int.MaxValue) { // cannot alloc more than 2GB in managed code! newsize = int.MaxValue; if (newsize < required) { throw new OutOfMemoryException("Cannot grow slice builder above 2GB"); } } // temporary release the handle m_data = null; m_handle.Free(); // resize to the new capacity, and re-pin Array.Resize(ref m_buffer, (int)newsize); } m_handle = GCHandle.Alloc(m_buffer, GCHandleType.Pinned); m_data = (byte *)m_handle.AddrOfPinnedObject(); } Contract.Ensures(m_buffer != null && m_handle.IsAllocated && m_data != null && m_count >= 0 && m_count <= m_buffer.Length, "GrowBuffer corruption"); }
/// <summary>Lexicographically compare two slices and returns an indication of their relative sort order</summary> /// <param name="x">Slice compared with <paramref name="y"/></param> /// <param name="y">Slice compared with <paramref name="x"/></param> /// <returns>Returns a NEGATIVE value if <paramref name="x"/> is LESS THAN <paramref name="y"/>, ZERO if <paramref name="x"/> is EQUAL TO <paramref name="y"/>, and a POSITIVE value if <paramref name="x"/> is GREATER THAN <paramref name="y"/>.</returns> /// <remarks>If both <paramref name="x"/> and <paramref name="y"/> are nil or empty, the comparison will return ZERO. If only <paramref name="y"/> is nil or empty, it will return a NEGATIVE value. If only <paramref name="x"/> is nil or empty, it will return a POSITIVE value.</remarks> public int Compare(USlice x, USlice y) { return(UnmanagedHelpers.CompareUnsafe(x.Data, x.Count, y.Data, y.Count)); }
public UnmanagedSliceBuilderPool(uint initialCapacity, int maxCount) { m_initialCapacity = UnmanagedHelpers.NextPowerOfTwo(Math.Min(initialCapacity, 64)); m_maxCount = Math.Max(1, maxCount); m_buckets = new Stack <UnmanagedSliceBuilder>(Math.Max(m_maxCount, 100)); }
/// <summary>Checks if two slices are equal.</summary> /// <param name="x">Slice compared with <paramref name="y"/></param> /// <param name="y">Slice compared with <paramref name="x"/></param> /// <returns>true if <paramref name="x"/> and <paramref name="y"/> have the same size and contain the same sequence of bytes; otherwise, false.</returns> public bool Equals(USlice x, USlice y) { return(x.Count == y.Count && 0 == UnmanagedHelpers.CompareUnsafe(x.Data, x.Count, y.Data, y.Count)); }
public override int GetHashCode() { return(UnmanagedHelpers.ComputeHashCode(ref this)); }
public int CompareTo(USlice other) { return(UnmanagedHelpers.CompareUnsafe(this.Data, this.Count, other.Data, other.Count)); }
int IComparer <KeyValuePair <USlice, USlice> > .Compare(KeyValuePair <USlice, USlice> x, KeyValuePair <USlice, USlice> y) { return(UnmanagedHelpers.CompareUnsafe(x.Key.Data, x.Key.Count, y.Key.Data, y.Key.Count)); }