/// <summary> /// Removes a page from storage. /// </summary> /// <param name="pageIndex">Index of removing page</param> public void RemovePage(long pageIndex) { CheckDisposed(); Lock(); try { CheckStorage(); if (_deferredUpdatesMode) { _recoveryFile.WriteDeletePageRecord(pageIndex); } else { if (pageIndex > _pagemap.GetMaxPageIndex()) { throw new ArgumentException("Too large page index"); } long pageAllocation = _pagemap.GetPageAllocation(pageIndex); if (pageAllocation == -1) { throw new PageMapException("Page is removed"); } CheckRemovalMarker(pageIndex); // prevent ThreadAbortException while vacuuming try { } finally { _pagemap.MarkPageAsFree(pageIndex); if (_pagemap.GetEmptyPageCount() > _maxEmptyPages) { Vacuum(); } else { _pagemap.Flush(); } } } } finally { Unlock(); } }
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]); } }