public DataFile(string filePath, long initialSize, int growthIncrement)
        {
            try
            {
                bool isNew = !File.Exists(filePath);
                memoryMapper          = new MemoryMapper(filePath, initialSize);
                mapping               = MemoryMapping.Create(memoryMapper.fs, Constants.AllocationGranularity);
                dataFileHeaderPointer = (DataFileHeader *)mapping.GetBaseAddress();
                this.growthIncrement  = (growthIncrement + Constants.AllocationGranularityMask) / Constants.AllocationGranularity * Constants.AllocationGranularity;

                if (isNew)
                {
                    InitializeHeader();
                }
                else
                {
                    ValidateHeader();
                }
            }
            catch
            {
                Dispose();
                throw;
            }
        }
        public MemoryMapper(string filePath, long initialFileSize)
        {
            try
            {
                if (initialFileSize <= 0 || initialFileSize % Constants.AllocationGranularity != 0)
                {
                    throw new ArgumentException("The initial file size must be a multiple of 64Kb and grater than zero");
                }

                bool existingFile = File.Exists(filePath);
                fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
                if (existingFile)
                {
                    if (fs.Length <= 0 || fs.Length % Constants.AllocationGranularity != 0)
                    {
                        throw new ArgumentException("Invalid file. Its lenght must be a multiple of 64Kb and greater than zero");
                    }
                }
                else
                {
                    fs.SetLength(initialFileSize);
                }
                mapping = MemoryMapping.Create(fs);
            }
            catch
            {
                Dispose();
                throw;
            }
        }
 internal void AddMapping(MemoryMapping mapping)
 {
     try { }
     // prevent ThreadAbortException from corrupting mappings collection
     finally
     {
         mappings.Add(mapping);
         mapping.AddRef();
         baseAddress = mapping.GetBaseAddress();
         BaseAddressChanged?.Invoke(this, new BaseAddressChangedEventArgs(baseAddress));
     }
 }
Beispiel #4
0
        internal static MemoryMapping Grow(long bytesToGrow, MemoryMapping mapping)
        {
            if (bytesToGrow <= 0 || bytesToGrow % Constants.AllocationGranularity != 0)
            {
                throw new ArgumentException("The growth must be a multiple of 64Kb and greater than zero");
            }
            long offset = mapping.fileStream.Length;

            mapping.fileStream.SetLength(mapping.fileStream.Length + bytesToGrow);
            var   mmf            = MemoryMappedFile.CreateFromFile(mapping.fileStream, null, mapping.fileStream.Length, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true);
            uint *offsetPointer  = (uint *)&offset;
            var   lastArea       = mapping.areas[mapping.areas.Count - 1];
            byte *desiredAddress = lastArea.Address + lastArea.Size;
            ulong bytesToMap     = (ulong)bytesToGrow;
            var   address        = Win32FileMapping.MapViewOfFileEx(mmf.SafeMemoryMappedFileHandle.DangerousGetHandle(),
                                                                    Win32FileMapping.FileMapAccess.Read | Win32FileMapping.FileMapAccess.Write,
                                                                    offsetPointer[1], offsetPointer[0], new UIntPtr(bytesToMap), desiredAddress);

            if (address == null)
            {
                bytesToMap = (ulong)mapping.fileStream.Length;
                address    = Win32FileMapping.MapViewOfFileEx(mmf.SafeMemoryMappedFileHandle.DangerousGetHandle(),
                                                              Win32FileMapping.FileMapAccess.Read | Win32FileMapping.FileMapAccess.Write,
                                                              0, 0, new UIntPtr(bytesToMap), null);
                if (address == null)
                {
                    throw new Win32Exception();
                }
                mapping = new MemoryMapping()
                {
                    baseAddress = address,
                    fileStream  = mapping.fileStream,
                    refCount    = 1
                };
            }

            var area = new MemoryMappedArea
            {
                Address = address,
                Mmf     = mmf,
                Size    = (long)bytesToMap
            };

            mapping.areas.Add(area);
            return(mapping);
        }
 public void Dispose()
 {
     if (IsDisposed)
     {
         return;
     }
     lock (SyncObject)
     {
         if (IsDisposed)
         {
             return;
         }
         IsDisposed = true;
         List <Exception> exceptions = new List <Exception>();
         if (mapping != null)
         {
             try
             {
                 mapping.Release();
                 mapping = null;
             }
             catch (Exception ex)
             {
                 exceptions.Add(ex);
             }
         }
         if (fs != null)
         {
             try
             {
                 fs.Dispose();
                 fs = null;
             }
             catch (Exception ex)
             {
                 exceptions.Add(ex);
             }
         }
         if (exceptions.Count > 0)
         {
             throw new AggregateException(exceptions);
         }
     }
 }
 public byte *Grow(long bytesToGrow)
 {
     CheckDisposed();
     lock (SyncObject)
     {
         CheckDisposed();
         var newMapping = MemoryMapping.Grow(bytesToGrow, mapping);
         if (mapping != newMapping)
         {
             var oldMapping = mapping;
             mapping = newMapping;
             oldMapping.Release();
             foreach (var session in sessions)
             {
                 session.AddMapping(newMapping);
             }
         }
         return(mapping.GetBaseAddress());
     }
 }
        public void Dispose()
        {
            if (IsDisposed)
            {
                return;
            }
            IsDisposed = true;
            List <Exception> exceptions = new List <Exception>();

            if (mapping != null)
            {
                try
                {
                    mapping.Release();
                    mapping = null;
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                }
            }
            if (memoryMapper != null)
            {
                try
                {
                    memoryMapper.Dispose();
                    memoryMapper = null;
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                }
            }

            if (exceptions.Count > 0)
            {
                throw new AggregateException(exceptions);
            }
        }
Beispiel #8
0
        internal static MemoryMapping Create(FileStream fs, long bytesToMap = 0)
        {
            var mmf     = MemoryMappedFile.CreateFromFile(fs, null, fs.Length, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true);
            var address = Win32FileMapping.MapViewOfFileEx(mmf.SafeMemoryMappedFileHandle.DangerousGetHandle(),
                                                           Win32FileMapping.FileMapAccess.Read | Win32FileMapping.FileMapAccess.Write,
                                                           0, 0, new UIntPtr((ulong)bytesToMap), null);

            if (address == null)
            {
                throw new Win32Exception();
            }

            var mapping = new MemoryMapping()
            {
                refCount    = 1,
                fileStream  = fs,
                baseAddress = address
            };

            mapping.areas.Add(new MemoryMappedArea(mmf, address, fs.Length));
            return(mapping);
        }