/// <summary> /// Save all dirty pages to disk /// </summary> public void Commit() { // get header page var header = _pager.GetPage <HeaderPage>(0); // set final datafile length (optimize page writes) _disk.SetLength(BasePage.GetSizeOfPages(header.LastPageID + 1)); // write all dirty pages in data file foreach (var page in _pager.GetDirtyPages()) { // first write in journal file original data _disk.WriteJournal(page.PageID, page.DiskData); // then writes no datafile new changed pages // page.WritePage() updated DiskData with new rendered buffer _disk.WritePage(page.PageID, _crypto == null || page.PageID == 0 ? page.WritePage() : _crypto.Encrypt(page.WritePage())); // mark page as clean (is now saved in disk) page.IsDirty = false; } // discard journal file _disk.ClearJournal(); }
/// <summary> /// Save all dirty pages to disk /// </summary> public void Commit() { // get header page var header = _pager.GetPage <HeaderPage>(0); // increase file changeID (back to 0 when overflow) header.ChangeID = header.ChangeID == ushort.MaxValue ? (ushort)0 : (ushort)(header.ChangeID + (ushort)1); // mark header as dirty _pager.SetDirty(header); // write journal file _disk.WriteJournal(_cache.GetDirtyPages() .Select(x => x.DiskData) .Where(x => x.Length > 0) .ToList()); // enter in exclusive lock mode to write on disk using (_locker.Exclusive()) { // set final datafile length (optimize page writes) _disk.SetLength(BasePage.GetSizeOfPages(header.LastPageID + 1)); foreach (var page in _cache.GetDirtyPages()) { // page.WritePage() updated DiskData with new rendered buffer var buffer = _crypto == null || page.PageID == 0 ? page.WritePage() : _crypto.Encrypt(page.WritePage()); _disk.WritePage(page.PageID, buffer); } // mark all dirty pages in clean pages (all are persisted in disk and are valid pages) _cache.MarkDirtyAsClean(); // ensure all pages from OS cache has been persisted on medium _disk.Flush(); // discard journal file _disk.ClearJournal(); } }
/// <summary> /// Save all dirty pages to disk - do not touch on lock disk /// </summary> private void Save() { // get header and mark as dirty var header = _pager.GetPage <HeaderPage>(0, true); // increase file changeID (back to 0 when overflow) header.ChangeID = header.ChangeID == ushort.MaxValue ? (ushort)0 : (ushort)(header.ChangeID + 1); // set final datafile length (optimize page writes) _disk.SetLength(BasePage.GetSizeOfPages(header.LastPageID + 1)); // write all dirty pages in data file foreach (var page in _cache.GetDirtyPages()) { _disk.WritePage(page.PageID, page.WritePage()); } }
/// <summary> /// Save all dirty pages to disk /// </summary> public void PersistDirtyPages() { // get header page var header = _pager.GetPage <HeaderPage>(0); // increase file changeID (back to 0 when overflow) header.ChangeID = header.ChangeID == ushort.MaxValue ? (ushort)0 : (ushort)(header.ChangeID + (ushort)1); // mark header as dirty _pager.SetDirty(header); _log.Write(Logger.Disk, "begin disk operations - changeID: {0}", header.ChangeID); // write journal file in desc order to header be last page in disk if (_disk.IsJournalEnabled) { _disk.WriteJournal(_cache.GetDirtyPages() .OrderByDescending(x => x.PageID) .Select(x => x.DiskData) .Where(x => x.Length > 0) .ToList(), header.LastPageID); // mark header as recovery before start writing (in journal, must keep recovery = false) header.Recovery = true; } else { // if no journal extend, resize file here to fast writes _disk.SetLength(BasePage.GetSizeOfPages(header.LastPageID + 1)); } // get all dirty page stating from Header page (SortedList) // header page (id=0) always must be first page to write on disk because it's will mark disk as "in recovery" foreach (var page in _cache.GetDirtyPages()) { // page.WritePage() updated DiskData with new rendered buffer var buffer = _crypto == null || page.PageID == 0 ? page.WritePage() : _crypto.Encrypt(page.WritePage()); _disk.WritePage(page.PageID, buffer); } if (_disk.IsJournalEnabled) { // re-write header page but now with recovery=false header.Recovery = false; _log.Write(Logger.Disk, "re-write header page now with recovery = false"); _disk.WritePage(0, header.WritePage()); } // mark all dirty pages as clean pages (all are persisted in disk and are valid pages) _cache.MarkDirtyAsClean(); // flush all data direct to disk _disk.Flush(); // discard journal file _disk.ClearJournal(header.LastPageID); }