/// <summary> /// Switches page manager instance to normal mode. /// All the changes made since the last EnterAtomicOperation() call are applied. /// </summary> public void ExitAtomicOperation() { if (_deferredUpdatesMode) { // write end marker to indicate that // one can playback the recovery records // without risking to corrupt the storage _recoveryFile.WriteFinalMarker(); // switch off deferred update mode for normal page management operation _deferredUpdatesMode = false; foreach (var pageIndex in _recoveryFile.UpdatedPageIndexes) { UpdatePage(new Page(this, pageIndex, _recoveryFile.GetUpdatedPageContent(pageIndex))); } foreach (var index in _recoveryFile.DeletedPageIndexes) { RemovePage(index); } Flush(_storageStream); _pagemap.Flush(); // now all are done, reset the recovery file _recoveryFile.Reset(); } }
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]); } }
public void CorrectlyApplyDeleteRecord() { long deleteIndex; using (var fileSystemPageManager = new FileSystemPageManager(4096)) using (var storage = new Storage(fileSystemPageManager)) { storage.OpenOrCreate(StoragePath); deleteIndex = fileSystemPageManager.CreatePage().Index; } using (var fileSystemPageManager = new FileSystemPageManager(4096)) using (var storage = new Storage(fileSystemPageManager)) { storage.OpenOrCreate(StoragePath); Assert.True(fileSystemPageManager.PageExists(deleteIndex)); } 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); fileSystemPageManager.Dispose(); recoveryFile.WriteDeletePageRecord(deleteIndex); 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); Assert.False(manager.PageExists(deleteIndex)); Assert.AreEqual(deleteIndex, manager.CreatePage().Index); } }
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]); } }