/// <summary> /// Writes a list of items to persistent storage using a "chain" format, where each /// page stores a "pointer" to the next page containing the following range of elements. /// </summary> /// <param name="stream">data file to write to</param> /// <param name="freeSpaceMgr">object that keeps track of available pages in the file</param> /// <param name="list">list of items to write</param> /// <param name="pages">list of pages we wrote to</param> public void WriteList(FileStreamWrapper stream, StoragePageManager freeSpaceMgr, List <T> list, out List <int> pages) { // create the pages this.CreateNewPage(list.Count, freeSpaceMgr); for (int idx = 0; idx < list.Count; idx++) { var item = list[idx]; try { this.pageList.Peek().AddRecord(item); this.pageHeaderList.Peek().PageEntriesCount++; } catch (StoragePage.InsuffcientSpaceException) { this.CreateNewPage(list.Count, freeSpaceMgr); idx--; } } // write the pages int lastPageIndex = ListHdr.EOLPageIndex; while (0 < this.pageList.Count) { lastPageIndex = this.WriteTopPage(stream, lastPageIndex); } // set the output parameter pages = this.pageIdxList; }
public void SPT_TestReadWriteTable() { int entryCount = 40; int physicalPageDistance = 5; string dataFile = "SPT_TestData1.tpdb"; if (File.Exists(dataFile)) { File.Delete(dataFile); } List <int> freedPages = null; StoragePageManager spaceMgr = new StoragePageManager(); StoragePageTable pageTable2 = new StoragePageTable(); StoragePageTable pageTable = new StoragePageTable(); for (int idx = 0; idx < entryCount; idx++) { pageTable.SetLogicalPage(idx + physicalPageDistance); } using (FileStreamWrapper dataFileStream = FileStreamWrapper.CreateObject(dataFile)) { int root = pageTable.WritePageTableData(dataFileStream, spaceMgr, out freedPages); dataFileStream.Seek(0, SeekOrigin.Begin); pageTable2.ReadPageTableData(dataFileStream, root); } for (int idx = 0; idx < entryCount; idx++) { int physicalAddress = pageTable2.GetPhysicalPage(idx); Assert.AreEqual(idx + physicalPageDistance, physicalAddress); } }
private void CreateNewPage(int count, StoragePageManager freeSpaceMgr) { // create a new header object ListHdr header = new ListHdr() { NextPageIndex = ListHdr.EOLPageIndex, TotalEntriesCount = count, PageEntriesCount = 0, PageWriteIndex = freeSpaceMgr.GetFreePage() }; this.pageHeaderList.Push(header); // create the page - and write a placeholder record for the header StoragePage page = new StoragePage(); page.AddRecord(header); this.pageList.Push(page); }