// reads a resource or a reservation data item protected virtual bool Read <I, R>(Transaction context, StorageContext storageContext, StorageIndex <I> index, I rID, bool lockPage, out R data) { // look for the resource in the index IndexItem <I> address = index.GetResourceAddress(rID); if (null == address) { data = default(R); return(false); } if (lockPage) { // Aquire a lock on the logical page address to ensure that the page is not // being written while we read the data this.LockPage(context, MyLM.LockMode.Read, address.Page); } // find the physical page int fileAddress = storageContext.PageTable.GetPhysicalPage(address.Page); // get the page StoragePage page = new StoragePage(); this.aReadPageData(page, fileAddress); // read the data data = (R)page.ReadRecord(address.Record); return(true); }
// writes a resource or reservation data item protected virtual bool Write <I, R>(Transaction context, StorageContext storageContext, StorageIndex <I> index, I rID, R data) { // look for the resource in the index IndexItem <I> address = index.GetResourceAddress(rID); if (null == address && null == data) { // nothing to do: // user probably wanted to delete an non-existing item return(true); } else if (null == address && null != data) { address = new IndexItem <I> { Page = storageContext.PageTable.GetLastLogicalPage(), Record = -1 }; } // Aquire a lock on the logical page address to ensure that we have access to the page this.LockPage(context, MyLM.LockMode.Write, address.Page); // find the physical page int fileAddress = storageContext.PageTable.GetPhysicalPage(address.Page); // get the page StoragePage page = new StoragePage(); if (0 <= fileAddress) { this.aReadPageData(page, fileAddress); } // write the record while (true) { try { if (0 > address.Record) { address.Record = page.AddRecord(data); } else { page.WriteRecord(address.Record, data); } } catch (StoragePage.InsuffcientSpaceException) { // did not fit on last page so allocate a new page page = new StoragePage(); address.Page = -1; fileAddress = -1; continue; } break; } // write the page fileAddress = this.aWritePageData(page, storageContext, fileAddress); // update the page table if (0 > address.Page) { address.Page = storageContext.PageTable.SetLogicalPage(fileAddress); } else { storageContext.PageTable.UpdatePage(address.Page, fileAddress); } // update the index if (null == data) { // handle deletes address = null; } index.SetResourceAddress(rID, address); return(true); }