예제 #1
0
        public void should_write_within_transaction()
        {
            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _pageSize, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, true, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            var databaseFactory  = SetupMock <IDatabaseFactory>();
            var pageStoreFactory = SetupMock <IPageStoreFactory>();

            var pageStore   = pageStoreFactory.Open(_fileSet);
            var database    = databaseFactory.Open(pageStore);
            var transaction = database.BeginTransaction(null);

            _fileSet.Write(
                transaction,
                Enumerable.Repeat(
                    new PageUpdate
            {
                SequenceNumber = 0,
                PageNumber     = 1,
                Offset         = 20,
                Data           = new byte[] { 5, 6, 7 }
            },
                    1));

            // Before the transaction is committed the page should be in its
            // original state

            using (var originalPage = _pagePool.Get(1))
            {
                _fileSet.Read(originalPage);

                Assert.AreEqual(0, originalPage.Data[20]);
                Assert.AreEqual(0, originalPage.Data[21]);
                Assert.AreEqual(0, originalPage.Data[22]);

                _fileSet.CommitTransaction(transaction).Wait();
                _fileSet.FinalizeTransaction(transaction).Wait();

                // After commiting and finalizing the transaction the page should be
                // changed in the data file

                using (var newPage = _pagePool.Get(1))
                {
                    _fileSet.Read(newPage);

                    Assert.AreEqual(5, newPage.Data[20]);
                    Assert.AreEqual(6, newPage.Data[21]);
                    Assert.AreEqual(7, newPage.Data[22]);
                }

                // Anyone with a reference to the original page should not see any change

                Assert.AreEqual(0, originalPage.Data[20]);
                Assert.AreEqual(0, originalPage.Data[21]);
                Assert.AreEqual(0, originalPage.Data[22]);
            }
        }
예제 #2
0
        public void should_write_directly_to_data()
        {
            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _pageSize, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, true, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            _fileSet.Write(
                null,
                Enumerable.Repeat(
                    new PageUpdate
            {
                SequenceNumber = 0,
                PageNumber     = 1,
                Offset         = 20,
                Data           = new byte[] { 5, 6, 7 }
            },
                    1));

            using (var page = _pagePool.Get(1))
            {
                _fileSet.Read(page);

                Assert.AreEqual(5, page.Data[20]);
                Assert.AreEqual(6, page.Data[21]);
                Assert.AreEqual(7, page.Data[22]);
            }
        }
예제 #3
0
        IPageCache IPageCache.Update(ITransaction transaction, IEnumerable <PageUpdate> updates)
        {
            if (transaction == null)
            {
                _fileSet.Write(null, updates);
            }

            _transactions.Update(transaction, updates, _pages);

            return(this);
        }
예제 #4
0
        public void should_roll_back_uncommitted_transactions_on_restart()
        {
            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _pageSize, _startUpLog), new DataFile(_dataFileInfo2, _pageSize, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, true, _startUpLog), new LogFile(_logFileInfo2, true, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            var databaseFactory  = SetupMock <IDatabaseFactory>();
            var pageStoreFactory = SetupMock <IPageStoreFactory>();

            var pageStore = pageStoreFactory.Open(_fileSet);
            var database  = databaseFactory.Open(pageStore);

            var transaction1 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction1,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 20,
                    Data           = new byte[] { 1, 2, 3 }
                }
            });
            database.CommitTransaction(transaction1);

            var transaction2 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction2,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 25,
                    Data           = new byte[] { 4, 5, 6 }
                }
            });
            database.CommitTransaction(transaction2);

            var transaction3 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction3,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 5,
                    Data           = new byte[] { 7, 8, 9 }
                },
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 30,
                    Data           = new byte[] { 10, 11, 12 }
                }
            });
            database.CommitTransaction(transaction3);

            // Before the transaction is committed the page should be in its original state

            using (var originalPage = _pagePool.Get(1))
            {
                _fileSet.Read(originalPage);

                for (var i = 0; i < _pageSize; i++)
                {
                    Assert.AreEqual(0, originalPage.Data[i]);
                }
            }

            // Commit transactions to the log files but do not update the data files

            _fileSet.CommitTransaction(transaction1).Wait();
            _fileSet.CommitTransaction(transaction2).Wait();
            _fileSet.CommitTransaction(transaction3).Wait();

            // Shut down and close all the files

            _fileSet.Dispose();

            // Reopen all of the files

            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _startUpLog), new DataFile(_dataFileInfo2, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, false, _startUpLog), new LogFile(_logFileInfo2, false, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            // Roll back all transactions

            ulong[] mustRollBackVersions;
            ulong[] canRollForwardVersions;
            _fileSet.GetIncompleteTransactions(out mustRollBackVersions, out canRollForwardVersions);

            _fileSet.RollBack(mustRollBackVersions);
            _fileSet.RollBack(canRollForwardVersions);

            // After rolling back the page should be unchanged in the data file

            using (var newPage = _pagePool.Get(1))
            {
                _fileSet.Read(newPage);

                for (var i = 0; i < _pageSize; i++)
                {
                    Assert.AreEqual(0, newPage.Data[i]);
                }
            }

            // There should be no incomplete transactions now

            _fileSet.GetIncompleteTransactions(out mustRollBackVersions, out canRollForwardVersions);

            Assert.AreEqual(0, mustRollBackVersions.Length);
            Assert.AreEqual(0, canRollForwardVersions.Length);
        }
예제 #5
0
        public void should_write_multiple_files_within_transaction()
        {
            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _pageSize, _startUpLog), new DataFile(_dataFileInfo2, _pageSize, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, true, _startUpLog), new LogFile(_logFileInfo2, true, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            var databaseFactory  = SetupMock <IDatabaseFactory>();
            var pageStoreFactory = SetupMock <IPageStoreFactory>();

            var pageStore    = pageStoreFactory.Open(_fileSet);
            var database     = databaseFactory.Open(pageStore);
            var transaction1 = database.BeginTransaction(null);
            var transaction2 = database.BeginTransaction(null);
            var transaction3 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction1,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 20,
                    Data           = new byte[] { 1, 2, 3 }
                }
            });

            _fileSet.Write(
                transaction2,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 25,
                    Data           = new byte[] { 4, 5, 6 }
                }
            });

            _fileSet.Write(
                transaction3,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 5,
                    Data           = new byte[] { 7, 8, 9 }
                },
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 30,
                    Data           = new byte[] { 10, 11, 12 }
                }
            });

            // Before the transaction is committed the page should be in its
            // original state

            using (var originalPage = _pagePool.Get(1))
            {
                _fileSet.Read(originalPage);

                for (var i = 0; i < _pageSize; i++)
                {
                    Assert.AreEqual(0, originalPage.Data[i]);
                }

                _fileSet.CommitTransaction(transaction1).Wait();
                _fileSet.CommitTransaction(transaction2).Wait();
                _fileSet.CommitTransaction(transaction3).Wait();
                _fileSet.FinalizeTransaction(transaction1).Wait();
                _fileSet.FinalizeTransaction(transaction2).Wait();
                _fileSet.FinalizeTransaction(transaction3).Wait();

                // After commiting and finalizing the transactions the page should be
                // changed in the data file

                using (var newPage = _pagePool.Get(1))
                {
                    _fileSet.Read(newPage);

                    Assert.AreEqual(1, newPage.Data[20]);
                    Assert.AreEqual(2, newPage.Data[21]);
                    Assert.AreEqual(3, newPage.Data[22]);

                    Assert.AreEqual(4, newPage.Data[25]);
                    Assert.AreEqual(5, newPage.Data[26]);
                    Assert.AreEqual(6, newPage.Data[27]);

                    Assert.AreEqual(7, newPage.Data[5]);
                    Assert.AreEqual(8, newPage.Data[6]);
                    Assert.AreEqual(9, newPage.Data[7]);

                    Assert.AreEqual(10, newPage.Data[30]);
                    Assert.AreEqual(11, newPage.Data[31]);
                    Assert.AreEqual(12, newPage.Data[32]);
                }

                // Anyone with a reference to the original page should not see any change

                for (var i = 0; i < _pageSize; i++)
                {
                    Assert.AreEqual(0, originalPage.Data[i]);
                }
            }
        }