예제 #1
0
        public void CorrectlyRecoverSequentiallyUpdatedPage()
        {
            long index;

            using (var fileSystemPageManager = new FileSystemPageManager(4096))
                using (var storage = new Storage(fileSystemPageManager))
                {
                    storage.OpenOrCreate(StoragePath);
                    var page = fileSystemPageManager.CreatePage();
                    index = page.Index;
                }

            string fileName;

            using (var fileSystemPageManager = new FileSystemPageManager(4096))
                using (var storage = new Storage(fileSystemPageManager))
                    using (var recoveryFile = new RecoveryFile(fileSystemPageManager, fileSystemPageManager.PageSize))
                    {
                        storage.OpenOrCreate(StoragePath);
                        var page = fileSystemPageManager.FetchPage(index);
                        index = page.Index;
                        fileSystemPageManager.Dispose();

                        Assert.AreEqual(index, page.Index);
                        Assert.AreNotEqual(0xff, page.Content[10]);

                        // Update twice with different bytes to make sure the latest one wins
                        page.Content[9]  = 0xaa;
                        page.Content[10] = 0xaa;
                        recoveryFile.WriteUpdatePageRecord(page);
                        page.Content[10] = 0xff;
                        recoveryFile.WriteUpdatePageRecord(page);

                        recoveryFile.WriteFinalMarker();
                        fileName = recoveryFile.FileName;
                    }

            Assert.True(File.Exists(fileName));
            Assert.GreaterOrEqual(new FileInfo(fileName).Length, 1);
            Assert.AreNotEqual(index, 0);

            using (var manager = new FileSystemPageManager(4096))
                using (var storage = new Storage(manager))
                {
                    storage.OpenOrCreate(StoragePath);
                    var page = manager.FetchPage(index);
                    Assert.AreEqual(index, page.Index);
                    Assert.AreEqual(0xaa, page.Content[9]);
                    Assert.AreEqual(0xff, page.Content[10]);
                }
        }
예제 #2
0
        /// <summary>
        /// Updates a page.
        /// </summary>
        /// <param name="page">A page instance to update</param>
        public void UpdatePage(IPage page)
        {
            CheckDisposed();

            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            Lock();
            try
            {
                CheckStorage();

                if (_deferredUpdatesMode)
                {
                    _recoveryFile.WriteUpdatePageRecord(page);
                }
                else
                {
                    long pageAllocation = _pagemap.GetPageAllocation(page.Index);
                    if (pageAllocation == -1)
                    {
                        throw new PageMapException("Page is removed");
                    }

                    CheckRemovalMarker(page.Index);
                    _storageStream.Seek(pageAllocation, SeekOrigin.Begin);
                    _storageStream.Write(page.ContentCopy, 0, _pageSize);

                    _pagemap.Flush();

                    Flush(_storageStream);
                }
            }
            finally
            {
                Unlock();
            }
        }
예제 #3
0
        public void CorrectlyRecoverResurrectedPage()
        {
            long index;
            long resurrectIndex;

            using (var fileSystemPageManager = new FileSystemPageManager(4096))
                using (var storage = new Storage(fileSystemPageManager))
                {
                    storage.OpenOrCreate(StoragePath);
                    var page = fileSystemPageManager.CreatePage();
                    index = page.Index;
                }

            using (var fileSystemPageManager = new FileSystemPageManager(4096))
                using (var storage = new Storage(fileSystemPageManager))
                {
                    storage.OpenOrCreate(StoragePath);
                    var page = fileSystemPageManager.FetchPage(index);
                    Assert.AreEqual(index, page.Index);
                    Assert.AreNotEqual(0xff, page.Content[10]);
                }

            string fileName;

            using (var fileSystemPageManager = new FileSystemPageManager(4096))
                using (var storage = new Storage(fileSystemPageManager))
                    using (var recoveryFile = new RecoveryFile(fileSystemPageManager, fileSystemPageManager.PageSize))
                    {
                        storage.OpenOrCreate(StoragePath);
                        var page = fileSystemPageManager.FetchPage(index);
                        index = page.Index;

                        page.Content[10] = 0xaf;

                        fileSystemPageManager.RemovePage(index);
                        var resurrectedPage = fileSystemPageManager.CreatePage();
                        resurrectIndex = resurrectedPage.Index;

                        //check we're not going wrong way
                        Assert.AreEqual(index, resurrectIndex);

                        resurrectedPage.Content[10] = 0xff;
                        Assert.AreNotEqual(0xff, page.Content[10]);

                        fileSystemPageManager.Dispose();

                        recoveryFile.WriteUpdatePageRecord(page);
                        recoveryFile.WriteDeletePageRecord(index);
                        recoveryFile.WriteUpdatePageRecord(resurrectedPage);

                        recoveryFile.WriteFinalMarker();

                        fileName = recoveryFile.FileName;
                    }

            Assert.True(File.Exists(fileName));
            Assert.GreaterOrEqual(new FileInfo(fileName).Length, 1);

            using (var manager = new FileSystemPageManager(4096))
                using (var storage = new Storage(manager))
                {
                    storage.OpenOrCreate(StoragePath);
                    var page = manager.FetchPage(index);
                    Assert.AreEqual(resurrectIndex, page.Index);
                    Assert.AreEqual(0xff, page.Content[10]);
                }
        }