示例#1
0
 public void ReleaseBuffer()
 {
     if (_buffer != null)
     {
         _buffersPool.Return(_buffer);
         _buffer = null;
     }
 }
示例#2
0
        public static uint AddressWillCauseHardPageFault(byte *address, long length, bool performCount = false)
        {
            uint count  = 0;
            var  remain = length % PageSize == 0 ? 0 : 1;
            var  pages  = (length / PageSize) + remain;
            AllocatedMemoryData memData = null;

            IntPtr wsInfo = IntPtr.Zero;
            PPSAPI_WORKING_SET_EX_INFORMATION *pWsInfo;
            var p = stackalloc PPSAPI_WORKING_SET_EX_INFORMATION[2];

            if (pages > 2)
            {
                memData = BuffersPool.Allocate((int)(sizeof(PPSAPI_WORKING_SET_EX_INFORMATION) * pages));
                wsInfo  = new IntPtr(memData.Address);
                pWsInfo = (PPSAPI_WORKING_SET_EX_INFORMATION *)wsInfo.ToPointer();
            }
            else
            {
                pWsInfo = p;
            }

            try
            {
                for (var i = 0; i < pages; i++)
                {
                    pWsInfo[i].VirtualAddress = address + (i * PageSize);
                }

                if (QueryWorkingSetEx(GetCurrentProcess(), (byte *)pWsInfo, (uint)(sizeof(PPSAPI_WORKING_SET_EX_INFORMATION) * pages)) == false)
                {
                    throw new MemoryInfoException($"Failed to QueryWorkingSetEx address: {new IntPtr(address).ToInt64()}, with length: {length}. processId = {GetCurrentProcess()}");
                }

                for (int i = 0; i < pages; i++)
                {
                    var flag = pWsInfo[i].VirtualAttributes & 0x00000001;
                    if (flag == 0)
                    {
                        if (performCount == false)
                        {
                            return(1);
                        }
                        count += PageSize;
                    }
                }
                return(count);
            }
            finally
            {
                if (memData != null)
                {
                    BuffersPool.Return(memData);
                }
            }
        }
示例#3
0
        private void CopyToBuffer(byte *value, int size)
        {
            if (_bufferPos + size > _buffer.SizeInBytes)
            {
                var newBuffer = _buffersPool.Allocate(Bits.NextPowerOf2(_bufferPos + size));
                Memory.Copy((byte *)newBuffer.Address, (byte *)_buffer.Address, _buffer.SizeInBytes);

                _buffersPool.Return(_buffer);
                _buffer = newBuffer;
            }

            Memory.Copy((byte *)_buffer.Address + _bufferPos, value, size);
            _bufferPos += size;
        }
示例#4
0
 public ReduceKeyProcessor(int numberOfReduceFields, UnmanagedBuffersPoolWithLowMemoryHandling buffersPool)
 {
     _numberOfReduceFields = numberOfReduceFields;
     _buffersPool          = buffersPool;
     if (numberOfReduceFields == 1)
     {
         _mode = Mode.SingleValue;
     }
     else
     {
         _mode      = Mode.MultipleValues;
         _buffer    = _buffersPool.Allocate(16);
         _bufferPos = 0;
     }
 }
示例#5
0
        public void Reset(object root)
        {
            if (_currentStateBuffer != null)
            {
                _ctx.ReturnMemory(_currentStateBuffer);
                _currentStateBuffer = null;
            }

            _elements.Clear();
            _seenValues.Clear();

            if (root != null)
            {
                _elements.Push(root);
            }
        }
        public void Return(AllocatedMemoryData returned)
        {
            if (returned == null)
            {
                throw new ArgumentNullException(nameof(returned));
            }
            var index = GetIndexFromSize(returned.SizeInBytes);

            if (index == -1)
            {
                NativeMemory.Free(returned.Address, returned.SizeInBytes, returned.AllocatingThread);

                return; // strange size, just free it
            }
            _freeSegments[index].Push(returned);
        }
示例#7
0
        public UnmanagedWriteBuffer(JsonOperationContext context, AllocatedMemoryData allocatedMemoryData)
        {
            Debug.Assert(context != null);
            Debug.Assert(allocatedMemoryData != null);

            _context = context;
            _head    = new Segment
            {
                Previous = null,
                DeallocationPendingPrevious = null,
                Allocation             = allocatedMemoryData,
                Address                = allocatedMemoryData.Address,
                Used                   = 0,
                AccumulatedSizeInBytes = 0
            };
        }
示例#8
0
        private void CopyToBuffer(byte *value, int size)
        {
            if (_buffer == null ||
                _bufferPos + size > _buffer.SizeInBytes)
            {
                var newBuffer = _buffersPool.Allocate(Bits.PowerOf2(_bufferPos + size));
                if (_buffer != null)
                {
                    Memory.Copy(newBuffer.Address, _buffer.Address, _buffer.SizeInBytes);
                    _buffersPool.Return(_buffer);
                }
                _buffer = newBuffer;
            }

            Memory.Copy(_buffer.Address + _bufferPos, value, size);
            _bufferPos += size;
        }
示例#9
0
        public void Reset(object root)
        {
            _seenIndex = ++ThreadLocalSeenIndex;
            if (ThreadLocalSeenIndex > short.MaxValue)
            {
                ThreadLocalSeenIndex = 1;
            }

            if (_currentStateBuffer != null)
            {
                _ctx.ReturnMemory(_currentStateBuffer);
                _currentStateBuffer = null;
            }

            _elements.Clear();

            if (root != null)
            {
                _elements.Push(root);
            }
        }
示例#10
0
        private void SetStringBuffer(string str)
        {
            // max possible size - we avoid using GetByteCount because profiling showed it to take 2% of runtime
            // the buffer might be a bit longer, but we'll reuse it, and it is better than the computing cost

            int escapePositionsSize = JsonParserState.FindEscapePositionsMaxSize(str, out _);

            int byteCount = str.Length * 5 + escapePositionsSize;

            if (_currentStateBuffer == null || _currentStateBuffer.SizeInBytes < byteCount)
            {
                byteCount = Encodings.Utf8.GetMaxByteCount(str.Length);

                // If we do not have a buffer or the buffer is too small, return the memory and get more.
                var size = byteCount + escapePositionsSize;
                if (_currentStateBuffer == null || _currentStateBuffer.SizeInBytes < size)
                {
                    if (_currentStateBuffer != null)
                    {
                        _ctx.ReturnMemory(_currentStateBuffer);
                    }
                    _currentStateBuffer = _ctx.GetMemory(size);
                    Debug.Assert(_currentStateBuffer != null && _currentStateBuffer.Address != null);
                }
            }

            _state.StringBuffer = _currentStateBuffer.Address;

            fixed(char *pChars = str)
            {
                _state.StringSize     = Encodings.Utf8.GetBytes(pChars, str.Length, _state.StringBuffer, _currentStateBuffer.SizeInBytes);
                _state.CompressedSize = null; // don't even try
                _state.FindEscapePositionsIn(_state.StringBuffer, ref _state.StringSize, escapePositionsSize);

                var escapePos = _state.StringBuffer + _state.StringSize;

                _state.WriteEscapePositionsTo(escapePos);
            }
        }
示例#11
0
            public void Release()
            {
                if (Interlocked.Decrement(ref Usages) > 0)
                {
                    return;
                }

                if (Interlocked.CompareExchange(ref Usages, -(1000 * 1000), 0) != 0)
                {
                    return;
                }

                Cache._unmanagedBuffersPool.Return(Allocation);
                Interlocked.Add(ref Cache._totalSize, -Size);
                Allocation = null;
#if DEBUG
                GC.SuppressFinalize(this);
#endif

                if (Logger.IsInfoEnabled)
                {
                    Logger.Info($"Released item from cache. Total cache size: {Cache._totalSize}");
                }
            }
示例#12
0
        public void Process(ByteStringContext context, object value, bool internalCall = false)
        {
            if (internalCall == false)
            {
                _processedFields++;
            }

            if (value == null || value is DynamicNullObject)
            {
                return;
            }

            _hadAnyNotNullValue = true;

            var lsv = value as LazyStringValue;

            if (lsv != null)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = Hashing.XXHash64.Calculate(lsv.Buffer, (ulong)lsv.Size);
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer(lsv.Buffer, lsv.Size);
                    break;
                }

                return;
            }

            var s = value as string;

            if (s != null)
            {
                using (Slice.From(context, s, out Slice str))
                {
                    switch (_mode)
                    {
                    case Mode.SingleValue:
                        _singleValueHash = Hashing.XXHash64.Calculate(str.Content.Ptr, (ulong)str.Size);
                        break;

                    case Mode.MultipleValues:
                        CopyToBuffer(str.Content.Ptr, str.Size);
                        break;
                    }
                }

                return;
            }

            var lcsv = value as LazyCompressedStringValue;

            if (lcsv != null)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = Hashing.XXHash64.Calculate(lcsv.Buffer, (ulong)lcsv.CompressedSize);
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer(lcsv.Buffer, lcsv.CompressedSize);
                    break;
                }

                return;
            }

            if (value is long l)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    unchecked
                    {
                        _singleValueHash = (ulong)l;
                    }
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer((byte *)&l, sizeof(long));
                    break;
                }

                return;
            }

            if (value is decimal d)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = Hashing.XXHash64.Calculate((byte *)&d, sizeof(decimal));
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer((byte *)&d, sizeof(decimal));
                    break;
                }

                return;
            }

            if (value is int num)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = (ulong)num;
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer((byte *)&num, sizeof(int));
                    break;
                }

                return;
            }

            if (value is bool b)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = b ? 0 : 1UL;
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer((byte *)&b, sizeof(bool));
                    break;
                }

                return;
            }

            if (value is double dbl)
            {
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = (ulong)dbl;
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer((byte *)&d, sizeof(double));
                    break;
                }

                return;
            }

            if (value is LazyNumberValue lnv)
            {
                Process(context, lnv.Inner, true);
                return;
            }

            long?ticks = null;

            if (value is DateTime)
            {
                ticks = ((DateTime)value).Ticks;
            }
            if (value is DateTimeOffset)
            {
                ticks = ((DateTimeOffset)value).Ticks;
            }
            if (value is TimeSpan)
            {
                ticks = ((TimeSpan)value).Ticks;
            }

            if (ticks.HasValue)
            {
                var t = ticks.Value;
                switch (_mode)
                {
                case Mode.SingleValue:
                    _singleValueHash = (ulong)t;
                    break;

                case Mode.MultipleValues:
                    CopyToBuffer((byte *)&t, sizeof(long));
                    break;
                }

                return;
            }

            if (value is BlittableJsonReaderObject json)
            {
                _mode = Mode.MultipleValues;

                if (_buffer == null)
                {
                    _buffer = _buffersPool.Allocate(16);
                }

                var prop = new BlittableJsonReaderObject.PropertyDetails();

                for (int i = 0; i < json.Count; i++)
                {
                    // this call ensures properties to be returned in the same order, regardless their storing order
                    json.GetPropertyByIndex(i, ref prop);

                    Process(context, prop.Value, true);
                }

                return;
            }

            if (value is IEnumerable enumerable)
            {
                _mode = Mode.MultipleValues;

                if (_buffer == null)
                {
                    _buffer = _buffersPool.Allocate(16);
                }

                foreach (var item in enumerable)
                {
                    Process(context, item, true);
                }

                return;
            }

            throw new NotSupportedException($"Unhandled type: {value.GetType()}");
        }
示例#13
0
        /// <summary>
        /// This function Processes the to string format of the form "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffff" for date times in
        /// invariant culture scenarios. This implementation takes 20% of the time of a regular .ToString(format) call
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="context"></param>
        /// <param name="memory"></param>
        /// <param name="isUtc"></param>
        /// <returns></returns>
        public static unsafe int GetDefaultFormat(this DateTime dt, JsonOperationContext context, out AllocatedMemoryData memory, bool isUtc = false)
        {
            int size  = 27 + (isUtc ? 1 : 0);
            var ticks = dt.Ticks;

            memory = context.GetMemory(size);

            byte *ptr = memory.Address;

            ProcessDefaultFormat(ticks, ptr);

            if (isUtc)
            {
                ptr[size - 1] = (byte)'Z';
            }

            return(size);
        }
示例#14
0
 public ReleaseMemory(DocumentsOperationContext context, AllocatedMemoryData copyOfMemory)
 {
     _context      = context;
     _copyOfMemory = copyOfMemory;
 }