Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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();
        }
Exemple #3
0
        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>();
        }
Exemple #4
0
        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();
        }
Exemple #6
0
        public void Dispose()
        {
            _startUpLog.WriteLine("Disposing of " + this);

            if (_pageCache != null)
            {
                _pageCache.Dispose();
            }
        }
Exemple #7
0
        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();
        }
Exemple #9
0
        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();
            }
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        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);
                }
            }
        }
Exemple #14
0
        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");
            }
        }
Exemple #15
0
 void IDisposable.Dispose()
 {
     _startupLog.WriteLine("Closing log file " + _file.FullName);
     _versionLogFile.Dispose();
 }
Exemple #16
0
 void IDisposable.Dispose()
 {
     _startupLog.WriteLine("Closing data file " + _file.FullName);
     _versionDataFile.Dispose();
 }