public void WriteBytes(long offset, byte[] array, int arrayOffset, int sizeBytes)
        {
            var readPtr = _memoryPtr + offset - _bufferOffset;

            fixed(byte *dest = array)
            {
                AccessorHelper.Memcpy(readPtr, dest + arrayOffset, sizeBytes);
            }
        }
        public void WriteBytes(long offset, byte *array, int sizeBytes)
        {
            while (sizeBytes > 0)
            {
                byte *ptr = GetFilePart(offset);
                //         Page size       - absolute offset % Page siez
                long end = (1 << _bitHint) - ((offset + FILE_HEADER_LENGTH) & ((1 << _bitHint) - 1));

                // Respect buffer size.
                var readSize1 = (int)Math.Min(end, sizeBytes);
                AccessorHelper.Memcpy(ptr, array, readSize1);

                offset    += readSize1;
                sizeBytes -= readSize1;
                array     += readSize1;
            }
        }
        public void WriteBytes(long offset, byte *array, int sizeBytes)
        {
            var readPtr = _memoryPtr + offset - _bufferOffset;

            AccessorHelper.Memcpy(readPtr, array, sizeBytes);
        }
        public unsafe void ReadBytes(long offset, byte *array, int sizeBytes)
        {
            var readPtr = _memoryPtr + offset - _bufferOffset;

            AccessorHelper.Memcpy(array, readPtr, sizeBytes);
        }
        private byte *MapBuffer(long bufferIndex, long offset)
        {
            lock (_buffSync)
            {
                if (bufferIndex < _pointersArrayLen)
                {
                    var ptr = _pointersArray[bufferIndex];
                    if (ptr != null)
                    {
                        return(ptr + offset);
                    }
                }
                else
                {
                    // Add empty.
                    long newLen     = bufferIndex + ADDITIONAL_BUFFER_ARRAY_CAPACITY;
                    var  newBuffers = new IRawFilePart[newLen];
                    Array.Copy(_buffers, 0, newBuffers, 0, _pointersArrayLen);

                    var newPtrArray = LongAllocate((int)newLen);

                    AccessorHelper.Memcpy((byte *)newPtrArray, (byte *)_pointersArray, (int)(sizeof(byte *) * _pointersArrayLen));

                    var oldPtrArray = _pointersArray;

                    Thread.MemoryBarrier();
                    _pointersArray = newPtrArray;

                    Thread.MemoryBarrier();
                    _pointersArrayLen      = newLen;
                    _pointersArrayFixedLen = newLen;
                    _buffers = newBuffers;

                    Marshal.FreeHGlobal((IntPtr)oldPtrArray);
                }

                // Create.
                int  bufferSize   = 1 << _bitHint;
                long bufferOffset = bufferIndex * bufferSize;

                IRawFilePart view;
                if (Access == EFileAccess.Read)
                {
                    var maxSize = _compositeFile.CheckSize();
                    if (bufferOffset + bufferSize > maxSize)
                    {
                        if (maxSize < bufferOffset)
                        {
                            // Only last buffer can be incompletely mapped.
                            // The file should be re-mapped on higher level.
                            throw new NFSdbInvalidReadException(
                                      "Attempt to read chunk in the middle of the file '{0}' with mismatched offset. File size {1}, buffer offset {2}.",
                                      Filename, maxSize, bufferOffset);
                        }

                        if (_incompleteBufferMapped)
                        {
                            // Only last buffer can be incompletely mapped.
                            // The file should be re-mapped on higher level.
                            throw new NFSdbInvalidReadException(
                                      "Attempt to read file '{0}' at {1}. Only one incomplete buffer allowed.",
                                      Filename, bufferOffset + offset);
                        }

                        bufferSize = (int)(maxSize - bufferOffset);
                        _incompleteBufferMapped = true;
                        _pointersArrayFixedLen  = bufferIndex;
                    }
                }
                view = _compositeFile.CreateViewAccessor(bufferOffset, bufferSize);

                _buffers[bufferIndex] = view;
                var address = view.Pointer - view.BufferOffset + FILE_HEADER_LENGTH;

                Thread.MemoryBarrier();
                _pointersArray[bufferIndex] = address;

                Interlocked.Add(ref _mappedSize, bufferSize);
                return(_pointersArray[bufferIndex] + offset);
            }
        }