Пример #1
0
        /// <summary>
        /// Constructor with more options for derived classes
        /// </summary>
        /// <param name="filename">File name (or prefix) with path</param>
        /// <param name="preallocateFile"></param>
        /// <param name="deleteOnClose"></param>
        /// <param name="disableFileBuffering"></param>
        /// <param name="capacity">The maximum number of bytes this storage device can accommondate, or CAPACITY_UNSPECIFIED if there is no such limit </param>
        /// <param name="recoverDevice">Whether to recover device metadata from existing files</param>
        /// <param name="initialLogFileHandles">Optional set of preloaded safe file handles, which can speed up hydration of preexisting log file handles</param>
        protected internal LocalStorageDevice(string filename,
                                              bool preallocateFile      = false,
                                              bool deleteOnClose        = false,
                                              bool disableFileBuffering = true,
                                              long capacity             = Devices.CAPACITY_UNSPECIFIED,
                                              bool recoverDevice        = false,
                                              IEnumerable <KeyValuePair <int, SafeFileHandle> > initialLogFileHandles = null)
            : base(filename, GetSectorSize(filename), capacity)
        {
            Native32.EnableProcessPrivileges();
            string path = new FileInfo(filename).Directory.FullName;

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            this.preallocateFile      = preallocateFile;
            this.deleteOnClose        = deleteOnClose;
            this.disableFileBuffering = disableFileBuffering;
            logHandles = initialLogFileHandles != null
                ? new SafeConcurrentDictionary <int, SafeFileHandle>(initialLogFileHandles)
                : new SafeConcurrentDictionary <int, SafeFileHandle>();
            if (recoverDevice)
            {
                RecoverFiles();
            }
        }
Пример #2
0
        /// <summary>
        /// Constructor with more options for derived classes
        /// </summary>
        /// <param name="filename">File name (or prefix) with path</param>
        /// <param name="preallocateFile"></param>
        /// <param name="deleteOnClose"></param>
        /// <param name="disableFileBuffering"></param>
        /// <param name="capacity">The maximum number of bytes this storage device can accommondate, or CAPACITY_UNSPECIFIED if there is no such limit </param>
        /// <param name="recoverDevice">Whether to recover device metadata from existing files</param>
        /// <param name="initialLogFileHandles">Optional set of preloaded safe file handles, which can speed up hydration of preexisting log file handles</param>
        /// <param name="useIoCompletionPort">Whether we use IO completion port with polling</param>
        protected internal LocalStorageDevice(string filename,
                                              bool preallocateFile      = false,
                                              bool deleteOnClose        = false,
                                              bool disableFileBuffering = true,
                                              long capacity             = Devices.CAPACITY_UNSPECIFIED,
                                              bool recoverDevice        = false,
                                              IEnumerable <KeyValuePair <int, SafeFileHandle> > initialLogFileHandles = null,
                                              bool useIoCompletionPort = true)
            : base(filename, GetSectorSize(filename), capacity)
        {
#if NETSTANDARD || NET
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                throw new FasterException("Cannot use LocalStorageDevice from non-Windows OS platform, use ManagedLocalStorageDevice instead.");
            }
#endif
            ThrottleLimit            = 120;
            this.useIoCompletionPort = useIoCompletionPort;
            this._disposed           = false;

            if (useIoCompletionPort)
            {
                ThreadPool.GetMaxThreads(out int workerThreads, out _);
                ioCompletionPort = Native32.CreateIoCompletionPort(new SafeFileHandle(new IntPtr(-1), false), IntPtr.Zero, UIntPtr.Zero, (uint)(workerThreads + NumCompletionThreads));
                for (int i = 0; i < NumCompletionThreads; i++)
                {
                    var thread = new Thread(() => new LocalStorageDeviceCompletionWorker().Start(ioCompletionPort, _callback))
                    {
                        IsBackground = true
                    };
                    thread.Start();
                }
            }

            if (UsePrivileges && preallocateFile)
            {
                Native32.EnableProcessPrivileges();
            }

            string path = new FileInfo(filename).Directory.FullName;
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            this.preallocateFile      = preallocateFile;
            this.deleteOnClose        = deleteOnClose;
            this.disableFileBuffering = disableFileBuffering;
            this.results = new ConcurrentQueue <SimpleAsyncResult>();

            logHandles = initialLogFileHandles != null
                ? new SafeConcurrentDictionary <int, SafeFileHandle>(initialLogFileHandles)
                : new SafeConcurrentDictionary <int, SafeFileHandle>();
            if (recoverDevice)
            {
                RecoverFiles();
            }
        }
Пример #3
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="filename"></param>
 /// <param name="preallocateFile"></param>
 /// <param name="deleteOnClose"></param>
 /// <param name="disableFileBuffering"></param>
 public LocalStorageDevice(string filename, bool preallocateFile = false, bool deleteOnClose = false, bool disableFileBuffering = true)
     : base(filename, GetSectorSize(filename))
 {
     Native32.EnableProcessPrivileges();
     this.preallocateFile      = preallocateFile;
     this.deleteOnClose        = deleteOnClose;
     this.disableFileBuffering = disableFileBuffering;
     logHandles = new SafeConcurrentDictionary <int, SafeFileHandle>();
 }
Пример #4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="preallocateFile"></param>
        /// <param name="deleteOnClose"></param>
        /// <param name="disableFileBuffering"></param>
        /// <param name="capacity">The maximum number of bytes this storage device can accommondate, or CAPACITY_UNSPECIFIED if there is no such limit </param>
        public LocalStorageDevice(string filename,
                                  bool preallocateFile      = false,
                                  bool deleteOnClose        = false,
                                  bool disableFileBuffering = true,
                                  long capacity             = Devices.CAPACITY_UNSPECIFIED)
            : base(filename, GetSectorSize(filename), capacity)

        {
            Native32.EnableProcessPrivileges();
            this.preallocateFile      = preallocateFile;
            this.deleteOnClose        = deleteOnClose;
            this.disableFileBuffering = disableFileBuffering;
            logHandles = new SafeConcurrentDictionary <int, SafeFileHandle>();
            RecoverFiles();
        }
Пример #5
0
        /// <summary>
        /// Constructor with more options for derived classes
        /// </summary>
        /// <param name="filename">File name (or prefix) with path</param>
        /// <param name="preallocateFile"></param>
        /// <param name="deleteOnClose"></param>
        /// <param name="disableFileBuffering"></param>
        /// <param name="capacity">The maximum number of bytes this storage device can accommondate, or CAPACITY_UNSPECIFIED if there is no such limit </param>
        /// <param name="recoverDevice">Whether to recover device metadata from existing files</param>
        /// <param name="initialLogFileHandles">Optional set of preloaded safe file handles, which can speed up hydration of preexisting log file handles</param>
        protected internal LocalStorageDevice(string filename,
                                              bool preallocateFile      = false,
                                              bool deleteOnClose        = false,
                                              bool disableFileBuffering = true,
                                              long capacity             = Devices.CAPACITY_UNSPECIFIED,
                                              bool recoverDevice        = false,
                                              IEnumerable <KeyValuePair <int, SafeFileHandle> > initialLogFileHandles = null)
            : base(filename, GetSectorSize(filename), capacity)
        {
#if NETSTANDARD
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                throw new FasterException("Cannot use LocalStorageDevice from non-Windows OS platform, use ManagedLocalStorageDevice instead.");
            }
#endif

            if (UsePrivileges && preallocateFile)
            {
                Native32.EnableProcessPrivileges();
            }

            string path = new FileInfo(filename).Directory.FullName;
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            this.preallocateFile      = preallocateFile;
            this.deleteOnClose        = deleteOnClose;
            this.disableFileBuffering = disableFileBuffering;
            this.results = new ConcurrentQueue <SimpleAsyncResult>();

            logHandles = initialLogFileHandles != null
                ? new SafeConcurrentDictionary <int, SafeFileHandle>(initialLogFileHandles)
                : new SafeConcurrentDictionary <int, SafeFileHandle>();
            if (recoverDevice)
            {
                RecoverFiles();
            }
        }
Пример #6
0
        private void InternalRecover(Guid indexToken, Guid hybridLogToken)
        {
            Debug.WriteLine("********* Primary Recovery Information ********");
            Debug.WriteLine("Index Checkpoint: {0}", indexToken);
            Debug.WriteLine("HybridLog Checkpoint: {0}", hybridLogToken);

            // Assert corresponding checkpoints are safe to recover from
            Debug.Assert(IsCheckpointSafe(indexToken, CheckpointType.INDEX_ONLY),
                         "Cannot recover from incomplete index checkpoint " + indexToken.ToString());

            Debug.Assert(IsCheckpointSafe(hybridLogToken, CheckpointType.HYBRID_LOG_ONLY),
                         "Cannot recover from incomplete hybrid log checkpoint " + hybridLogToken.ToString());

            // Recovery appropriate context information
            var recoveredICInfo = new IndexCheckpointInfo();

            recoveredICInfo.Recover(indexToken, directoryConfiguration);
            recoveredICInfo.info.DebugPrint();

            var recoveredHLCInfo = new HybridLogCheckpointInfo();

            recoveredHLCInfo.Recover(hybridLogToken, directoryConfiguration);
            recoveredHLCInfo.info.DebugPrint();

            // Check if the two checkpoints are compatible for recovery
            if (!IsCompatible(recoveredICInfo.info, recoveredHLCInfo.info))
            {
                throw new Exception("Cannot recover from (" + indexToken.ToString() + "," + hybridLogToken.ToString() + ") checkpoint pair!\n");
            }

            // Set new system state after recovery
            var v = recoveredHLCInfo.info.version;

            _systemState.phase   = Phase.REST;
            _systemState.version = (v + 1);

            // Recover fuzzy index from checkpoint
            RecoverFuzzyIndex(recoveredICInfo);

            // Recover segment offsets for object log
            if (recoveredHLCInfo.info.objectLogSegmentOffsets != null)
            {
                Array.Copy(recoveredHLCInfo.info.objectLogSegmentOffsets,
                           hlog.GetSegmentOffsets(),
                           recoveredHLCInfo.info.objectLogSegmentOffsets.Length);
            }


            // Make index consistent for version v
            if (FoldOverSnapshot)
            {
                RecoverHybridLog(recoveredICInfo.info, recoveredHLCInfo.info);
            }
            else
            {
                RecoverHybridLogFromSnapshotFile(recoveredICInfo.info, recoveredHLCInfo.info);
            }


            // Read appropriate hybrid log pages into memory
            RestoreHybridLog(recoveredHLCInfo.info.finalLogicalAddress);

            // Recover session information
            _recoveredSessions = new SafeConcurrentDictionary <Guid, long>();
            foreach (var sessionInfo in recoveredHLCInfo.info.continueTokens)
            {
                _recoveredSessions.GetOrAdd(sessionInfo.Key, sessionInfo.Value);
            }
        }