private void WriteDBRoot(DBHdr dbRoot) { StoragePage rootPage = new StoragePage(); rootPage.AddRecord(dbRoot); rootPage.WritePageData(this.dataFile, RootPage); }
/// <summary> /// Remarks: /// No locking needed beause this method cannot be invoked on the object. /// It is only called during initialization before the object is returned /// from the object factory method. /// </summary> /// <param name="filePath"></param> private void Init(string filePath) { // open the file this.dataFile = FileStreamWrapper.CreateObject(filePath); DBHdr dbRoot = this.ReadDBRoot(); if (null == dbRoot) { // setup the data file this.InitializeDataFile(); // flush the file this.dataFile.Flush(true); } else { // read the prepared transaction data this.preparedContextMap.ReadTransactionTableData( this.dataFile, dbRoot.PrepedTransactions); // read the data manager this.pageManager.ReadPageManagerData( this.dataFile, dbRoot.PageManager); } }
// implements the abort of a transaction private void aAbort(Transaction context) { lock (ManagerLock) { List <int> oldStorageContextPages = new List <int>(); StorageContext storageContext = null; if (this.activeContextMap.TryGetValue(context, out storageContext)) { // found transaction in active transactions list this.activeContextMap.Remove(context); } else { TransItem contextData = this.preparedContextMap.Remove(context); if (null == contextData) { // transaction must already have been commited or aborted // nothing to do return; } // found transaction in prepared transaction list oldStorageContextPages = contextData.StoragePageList; storageContext = contextData.TransactionData; if (null == storageContext) { storageContext = ReadStorageContext(contextData, out oldStorageContextPages); } } DBHdr dbRoot = this.ReadDBRoot(); if (null == dbRoot) { throw new Exception(); } // write the updated prepared transaction list List <int> oldPrepedContextMapPages = null; dbRoot.PrepedTransactions = this.preparedContextMap.WriteTransactionTableData( this.dataFile, this.pageManager, out oldPrepedContextMapPages); // update the page manager this.pageManager.SetFreePages(oldStorageContextPages); this.pageManager.SetFreePages(oldPrepedContextMapPages); this.pageManager.SetFreePages(storageContext.AllocatedPageList); dbRoot.PageManager = this.pageManager.WritePageManagerData( this.dataFile); this.WriteDBRoot(dbRoot); this.dataFile.Flush(true); } }
// prepares a transaction for commit by serialializing the data to disk private void aPrepare(Transaction context) { lock (ManagerLock) { if (this.preparedContextMap.Contains(context)) { // transaction already prepared for commit // nothing to do return; } StorageContext storageContext = null; if (!this.activeContextMap.TryGetValue(context, out storageContext)) { // oops ... we don't know anything about this transaction // something must have gone wrong throw new Exception(); } this.activeContextMap.Remove(context); // add the new item to the table TransItem contextData = WriteStorageContext(storageContext); contextData.Transaction = context; contextData.TransactionData = storageContext; this.preparedContextMap.Add(contextData); // update the DB root for the free list page and // commited transaction list DBHdr dbRoot = this.ReadDBRoot(); if (null == dbRoot) { throw new InvalidDataException(); } // write the prepared transactions table List <int> oldContextMapPages = null; dbRoot.PrepedTransactions = this.preparedContextMap.WriteTransactionTableData( this.dataFile, this.pageManager, out oldContextMapPages); // write the page manager this.pageManager.SetFreePages(oldContextMapPages); dbRoot.PageManager = this.pageManager.WritePageManagerData( this.dataFile); this.WriteDBRoot(dbRoot); this.dataFile.Flush(true); } }
private DBHdr ReadDBRoot() { DBHdr dbRoot = null; try { StoragePage rootPage = new StoragePage(); rootPage.ReadPageData(this.dataFile, RootPage); dbRoot = (DBHdr)rootPage.ReadRecord(0); } catch (Exception) { dbRoot = null; } return(dbRoot); }
private StorageContext aGetStorageContext(Transaction context) { lock (dataFile) { // look for the context in the map StorageContext storageContext = null; if (this.activeContextMap.TryGetValue(context, out storageContext)) { return(storageContext); } // create a brand new storage context // read the DBRoot record DBHdr dbRoot = ReadDBRoot(); if (null == dbRoot) { throw new Exception(); } // create the storage context storageContext = new StorageContext(); // read in the page table storageContext.PageTable.ReadPageTableData( this.dataFile, dbRoot.PageTable); // read in the resource index storageContext.ResourceIndex.ReadIndexData( this.dataFile, dbRoot.ResourceIndex); // read in the reservation index storageContext.ReservationIndex.ReadIndexData( this.dataFile, dbRoot.ReservationIndex); // insert the context into the map this.activeContextMap.Add(context, storageContext); return(storageContext); } }
private void InitializeDataFile() { // helpers List <int> oldPages = null; DBHdr dbRoot = new DBHdr(); WriteDBRoot(dbRoot); // create the page table StoragePageTable pageTable = new StoragePageTable(); dbRoot.PageTable = pageTable.WritePageTableData( this.dataFile, this.pageManager, out oldPages); // create resource index StorageIndex <RID> resourceIndx = new StorageIndex <RID>(); dbRoot.ResourceIndex = resourceIndx.WriteIndexData( this.dataFile, this.pageManager, out oldPages); // create reservation index StorageIndex <Customer> reservationIndex = new StorageIndex <Customer>(); dbRoot.ReservationIndex = reservationIndex.WriteIndexData( this.dataFile, this.pageManager, out oldPages); // create preped transactions index StorageTransactionTable preparedTransactions = new StorageTransactionTable(); dbRoot.PrepedTransactions = preparedTransactions.WriteTransactionTableData( this.dataFile, this.pageManager, out oldPages); // write the page manager dbRoot.PageManager = this.pageManager.WritePageManagerData(this.dataFile); // write the dbRoot one more time WriteDBRoot(dbRoot); }
// commits a transaction private void aCommit(Transaction context) { lock (ManagerLock) { TransItem contextData = this.preparedContextMap.Remove(context); if (null == contextData) { // transaction must already have been commited or aborted // nothing to do return; } List <int> oldStorageContextPages = contextData.StoragePageList; StorageContext storageContext = contextData.TransactionData; if (null == storageContext) { storageContext = ReadStorageContext(contextData, out oldStorageContextPages); } // read in the DB root DBHdr dbRoot = this.ReadDBRoot(); if (null == dbRoot) { throw new InvalidDataException(); } // merge page table storageContext.PageTable.ReadPageTableData( this.dataFile, dbRoot.PageTable); storageContext.PageTable.ClearDirtyFlags(); // merge resource index storageContext.ResourceIndex.ReadIndexData( this.dataFile, dbRoot.ResourceIndex); storageContext.ResourceIndex.ClearDirtyFlags(); // merge reservation index storageContext.ReservationIndex.ReadIndexData( this.dataFile, dbRoot.ReservationIndex); storageContext.ReservationIndex.ClearDirtyFlags(); // write the page table List <int> oldPageTablePages = null; dbRoot.PageTable = storageContext.PageTable.WritePageTableData( this.dataFile, this.pageManager, out oldPageTablePages); // write the resource index List <int> oldResourceIndexPages = null; dbRoot.ResourceIndex = storageContext.ResourceIndex.WriteIndexData( this.dataFile, this.pageManager, out oldResourceIndexPages); // write the reservation index List <int> oldReservationIndexPages = null; dbRoot.ReservationIndex = storageContext.ReservationIndex.WriteIndexData( this.dataFile, this.pageManager, out oldReservationIndexPages); // write the updated prepared transaction list List <int> oldPrepedContextMapPages = null; dbRoot.PrepedTransactions = this.preparedContextMap.WriteTransactionTableData( this.dataFile, this.pageManager, out oldPrepedContextMapPages); // update the page manager this.pageManager.SetFreePages(oldStorageContextPages); this.pageManager.SetFreePages(oldPageTablePages); this.pageManager.SetFreePages(oldResourceIndexPages); this.pageManager.SetFreePages(oldReservationIndexPages); this.pageManager.SetFreePages(oldPrepedContextMapPages); this.pageManager.SetFreePages(storageContext.FreedPageList); dbRoot.PageManager = this.pageManager.WritePageManagerData( this.dataFile); this.WriteDBRoot(dbRoot); this.dataFile.Flush(true); } }