public DataFile(FileInfo file, IStartupLog startupLog) { _file = file; _startupLog = startupLog; startupLog.WriteLine("Opening existing data file " + file.FullName); var fileStream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); var buffer = new byte[4]; fileStream.Read(buffer, 0, 4); var version = BitConverter.ToUInt32(buffer, 0); startupLog.WriteLine("Data file " + file.FullName + " is version " + version); if (version == 1) { _versionDataFile = new DataFileV1(fileStream); } else { startupLog.WriteLine("Data file version " + version + " is not supported in this version of the software, please install the latest software", true); fileStream.Close(); throw new UnsupportedVersionException(version, 1, "Data file", file.FullName); } }
public VersionHeadCollection( IStartupLog startupLog, IErrorLog errorLog, IDatabase database) { _versions = new Dictionary <ulong, VersionHead>(); _startupLog = startupLog; _errorLog = errorLog; _database = database; _cleanupThread = new Thread(() => { _startupLog.WriteLine("Version clean up thread starting"); while (!_disposing) { try { Thread.Sleep(50); List <VersionHead> versions; lock (_versions) versions = _versions.Values.OrderBy(v => v.VersionNumber).ToList(); foreach (var version in versions) { if (version.IsReferenced || version.VersionNumber == _database.CurrentVersion) { break; } lock (_versions) _versions.Remove(version.VersionNumber); version.Dispose(); } } catch (ThreadAbortException) { return; } catch (Exception ex) { _errorLog.WriteLine("Exception in page collection cleanup thread. " + ex.Message, ex); } } _startupLog.WriteLine("Version clean up thread exiting"); }) { IsBackground = true, Name = "Version collection cleanup", Priority = ThreadPriority.AboveNormal }; _cleanupThread.Start(); }
public FileSet( IEnumerable <IDataFile> dataFiles, IEnumerable <ILogFile> logFiles, IPagePoolFactory pagePoolFactory, IStartupLog startUpLog) { _startUpLog = startUpLog; _dataFiles = dataFiles.ToArray(); _logFiles = logFiles.ToArray(); startUpLog.WriteLine("Opening a file set with " + _dataFiles.Length + " data files and " + _logFiles.Length + " log files", _dataFiles.Length < 1 || _logFiles.Length < 1); if (_dataFiles.Length < 1) { throw new FileLayerException("You must have at least 1 data file"); } if (_logFiles.Length < 1) { throw new FileLayerException("You must have at least 1 log file"); } foreach (var dataFile in _dataFiles) { startUpLog.WriteLine("- " + dataFile); } foreach (var logFile in _logFiles) { startUpLog.WriteLine("- " + logFile); } _pageSize = _dataFiles[0].PageSize; if (_dataFiles.Any(df => df.PageSize != _pageSize)) { startUpLog.WriteLine("Data files can not be mixed, these files are not a file set", true); throw new FileLayerException("All of the data files must have the same page size"); } if (_dataFiles.Length > 64) { startUpLog.WriteLine("You can not have more than 64 data files in a file set", true); throw new FileLayerException("The maximum number of data files is 64"); } _pagePool = pagePoolFactory.Create(_pageSize); _transactions = new Dictionary <ITransaction, TransactionDetail>(); }
public PagePool(uint pageSize, IStartupLog startUpLog) { startUpLog.WriteLine("Creating a page pool for " + pageSize + " byte pages"); _pageSize = pageSize; _pages = new LinkedList <Page>(); }
public PageHeadCollection( IFileSet fileSet, IStartupLog startupLog, IErrorLog errorLog, IPagePool pagePool) { _pages = new Dictionary <ulong, PageHead>(); _fileSet = fileSet; _startupLog = startupLog; _errorLog = errorLog; _pagePool = pagePool; _cleanupThread = new Thread(() => { _startupLog.WriteLine("Stale page clean up thread starting"); while (!_disposing) { try { Thread.Sleep(50); // TODO: Delete pages that have not been touched for a while and // have no cached versions } catch (ThreadAbortException) { return; } catch (Exception ex) { _errorLog.WriteLine("Exception in page collection cleanup thread. " + ex.Message, ex); } } _startupLog.WriteLine("Stale page clean up thread exiting"); }) { IsBackground = true, Name = "Page collection cleanup", Priority = ThreadPriority.AboveNormal }; _cleanupThread.Start(); }
public void Dispose() { _startUpLog.WriteLine("Disposing of " + this); if (_pageCache != null) { _pageCache.Dispose(); } }
public void Dispose() { _startupLog.WriteLine("Closing page cache for " + _fileSet); _fileSet.Dispose(); _transactions.Dispose(); _versions.Dispose(); _pages.Dispose(); }
public TransactionHeadCollection( IStartupLog startupLog, IErrorLog errorLog, IPagePool pagePool) { _transactions = new Dictionary <ulong, TransactionHead>(); _startupLog = startupLog; _errorLog = errorLog; _pagePool = pagePool; _cleanupThread = new Thread(() => { _startupLog.WriteLine("Transaction clean up thread starting"); while (!_disposing) { try { Thread.Sleep(50); // TODO: Kill long running and deadlocked transactions } catch (ThreadAbortException) { return; } catch (Exception ex) { _errorLog.WriteLine("Exception in page cache stale page cleanup thread. " + ex.Message, ex); } } _startupLog.WriteLine("Transaction clean up thread exiting"); }) { IsBackground = true, Name = "Transaction collection cleanup", Priority = ThreadPriority.AboveNormal }; _cleanupThread.Start(); }
public DataFile(FileInfo file, uint pageSize, IStartupLog startupLog) { _file = file; _startupLog = startupLog; startupLog.WriteLine("Creating/overwriting version 1 data file " + file.FullName + " with page size " + pageSize); var fileStream = file.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None); var version = 1U; fileStream.Write(BitConverter.GetBytes(version), 0, 4); _versionDataFile = new DataFileV1(fileStream, pageSize); }
public void Dispose() { _startupLog.WriteLine("Disposing of page head collection"); _disposing = true; _cleanupThread.Join(200); lock (_pages) { foreach (var pageHead in _pages.Values) { pageHead.Dispose(); } _pages.Clear(); } }
public void Dispose() { _startupLog.WriteLine("Disposing of transaction collection"); _disposing = true; _cleanupThread.Join(200); lock (_transactions) { foreach (var transactionHead in _transactions.Values) { transactionHead.Dispose(); } _transactions.Clear(); } }
public PageCache( IFileSet fileSet, IDatabase database, IPagePoolFactory pagePoolFactory, IStartupLog startupLog, IErrorLog errorLog) { _startupLog = startupLog; _errorLog = errorLog; _fileSet = fileSet; _database = database; startupLog.WriteLine("Creating a new page cache for " + _fileSet); _pagePool = pagePoolFactory.Create(fileSet.PageSize); _pages = new PageHeadCollection(fileSet, startupLog, errorLog, _pagePool); _versions = new VersionHeadCollection(startupLog, errorLog, database); _transactions = new TransactionHeadCollection(startupLog, errorLog, _pagePool); }
public LogFile(FileInfo file, bool initialize, IStartupLog startupLog) { _file = file; _startupLog = startupLog; startupLog.WriteLine((initialize ? "Initializing" : "Opening") + " log file " + file.FullName); if (!file.Exists) { startupLog.WriteLine("Log file does not exist, we will try to create it"); initialize = true; } if (initialize) { if (!file.Directory.Exists) { startupLog.WriteLine("The log file directory " + file.Directory.FullName + " does not exist, we will try to create it"); file.Directory.Create(); } startupLog.WriteLine("Creating a version 1 log file in " + file.FullName); var fileStream = file.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None); _versionLogFile = new LogFileV1(fileStream, true); } else { var fileStream = file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); var buffer = new byte[4]; fileStream.Read(buffer, 0, 4); var version = BitConverter.ToUInt32(buffer, 0); startupLog.WriteLine("Log file " + file.FullName + " is version " + version + " format"); if (version == 1) { _versionLogFile = new LogFileV1(fileStream, false); } else { fileStream.Close(); startupLog.WriteLine("Log file version " + version + " is not supported in this version of the software, please install the latest software", true); throw new UnsupportedVersionException(version, 1, "Log file", file.FullName); } } }
public PageStore(IPageCache pageCache, IStartupLog startUpLog) { _pageCache = pageCache; _startUpLog = startUpLog; _indexPages = new Dictionary <ushort, ulong>(); // The index master page is always page 0 // This page contains the starting page numbers for other indexes _indexHead = _pageCache.Get(null, 0, CacheHints.None); if (_indexHead == null) { startUpLog.WriteLine("Creating a new page store in a set of empty data files from " + _pageCache); _indexHead = _pageCache.NewPage(0); } else { startUpLog.WriteLine("Opening a page store on " + _pageCache); var offset = 0; ushort objectType; ulong startPage; do { objectType = BitConverter.ToUInt16(_indexHead.Data, offset); startPage = BitConverter.ToUInt64(_indexHead.Data, offset + 2); if (objectType > 0) { startUpLog.WriteLine("- the index for type " + objectType + " objects starts at page " + startPage); _indexPages[objectType] = startPage; } else { break; } offset += 10; } while (offset < _indexHead.Data.Length); } // The free page map is always page 1 // This is the first in a chain of pages used to manage // unused space in the file set _freePageHead = _pageCache.Get(null, 1, CacheHints.None); if (_freePageHead == null) { startUpLog.WriteLine("Initializing a new free page map in this page store"); _freePageHead = _pageCache.NewPage(1); _highestPageNumber = 1; _pageCache.Update(null, new[] { new PageUpdate { PageNumber = _freePageHead.PageNumber, Data = BitConverter.GetBytes((ulong)_highestPageNumber) } }); } else { _highestPageNumber = (long)BitConverter.ToUInt64(_freePageHead.Data, 0); startUpLog.WriteLine("This page store contains " + _highestPageNumber + " pages"); } }
void IDisposable.Dispose() { _startupLog.WriteLine("Closing log file " + _file.FullName); _versionLogFile.Dispose(); }
void IDisposable.Dispose() { _startupLog.WriteLine("Closing data file " + _file.FullName); _versionDataFile.Dispose(); }