Beispiel #1
0
        internal static SafeMapViewHandle MapViewOfFile(
            SafeMapHandle hMap, long fileOffset, long mapViewSize,
            FileMapAccess desiredAccess)
        {
            if (hMap == null || hMap.IsInvalid)
            {
                throw new ArgumentNullException("hMap");
            }
            if (fileOffset < 0)
            {
                throw new ArgumentOutOfRangeException("fileOffset", fileOffset, "Must be >= 0");
            }
            if (mapViewSize <= 0)
            {
                throw new ArgumentOutOfRangeException("mapViewSize", mapViewSize, "Must be > 0");
            }

            return
                (ThrowOnError(
                     MapViewOfFile(
                         hMap,
                         desiredAccess,
                         (uint)((fileOffset >> 32) & 0xFFFFFFFF),
                         (uint)(fileOffset & 0xFFFFFFFF),
                         (IntPtr)mapViewSize)));
        }
Beispiel #2
0
 private static extern SafeMapViewHandle MapViewOfFile(
     SafeMapHandle hFileMappingObject,
     FileMapAccess dwDesiredAccess,
     uint dwFileOffsetHigh,
     uint dwFileOffsetLow,
     IntPtr dwNumberOfBytesToMap);
Beispiel #3
0
        private int ProcessMemoryMappedFile(long firstItemIdx, ArraySegment <T> buffer, bool isWriting, long fileSize)
        {
            SafeMapHandle hMap = null;

            try
            {
                bool isAligned;
                long fileCount = CalculateItemCountFromFilePosition(fileSize, out isAligned);
                if (!isAligned && isWriting)
                {
                    throw new BinaryFileException(
                              "Cannot write to a file when its length does not align to item size ({0})",
                              ToString());
                }

                long idxToStopAt = firstItemIdx + buffer.Count;

                if (!isWriting && idxToStopAt > fileCount)
                {
                    idxToStopAt = fileCount;
                }

                long offsetToStopAt = ItemIdxToOffset(idxToStopAt);
                long idxCurrent     = firstItemIdx;

                // Grow file if needed
                if (isWriting && offsetToStopAt > fileSize)
                {
                    fileSize = offsetToStopAt;
                }

                hMap = NativeWinApis.CreateFileMapping(
                    (FileStream)BaseStream, fileSize,
                    isWriting ? FileMapProtection.PageReadWrite : FileMapProtection.PageReadOnly);

                while (idxCurrent < idxToStopAt)
                {
                    SafeMapViewHandle ptrMapViewBaseAddr = null;
                    try
                    {
                        long offsetCurrent     = ItemIdxToOffset(idxCurrent);
                        long mapViewFileOffset = Utils.RoundDownToMultiple(offsetCurrent, MinPageSize);

                        long mapViewSize           = offsetToStopAt - mapViewFileOffset;
                        long itemsToProcessThisRun = idxToStopAt - idxCurrent;
                        if (mapViewSize > MaxLargePageSize)
                        {
                            mapViewSize           = MaxLargePageSize;
                            itemsToProcessThisRun = (mapViewFileOffset + mapViewSize) / ItemSize - idxCurrent -
                                                    CalculateHeaderSizeAsItemCount();
                        }

                        // The size of the new map view.
                        ptrMapViewBaseAddr = NativeWinApis.MapViewOfFile(
                            hMap, mapViewFileOffset, mapViewSize,
                            isWriting ? FileMapAccess.Write : FileMapAccess.Read);

                        long totalItemsDone = idxCurrent - firstItemIdx;
                        long bufItemOffset  = buffer.Offset + totalItemsDone;

                        // Access file using memory-mapped pages
                        Serializer.ProcessMemoryPtr(
                            (IntPtr)(ptrMapViewBaseAddr.Address + offsetCurrent - mapViewFileOffset),
                            new ArraySegment <T>(buffer.Array, (int)bufItemOffset, (int)itemsToProcessThisRun),
                            isWriting);

                        idxCurrent += itemsToProcessThisRun;
                    }
                    finally
                    {
                        if (ptrMapViewBaseAddr != null)
                        {
                            ptrMapViewBaseAddr.Dispose();
                        }
                    }
                }

                return((int)(idxCurrent - firstItemIdx));
            }
            finally
            {
                if (hMap != null)
                {
                    hMap.Dispose();
                }
            }
        }