예제 #1
0
        private void WriteDBRoot(DBHdr dbRoot)
        {
            StoragePage rootPage = new StoragePage();

            rootPage.AddRecord(dbRoot);
            rootPage.WritePageData(this.dataFile, RootPage);
        }
예제 #2
0
 // reads a page from persistent storage
 private void aReadPageData(StoragePage page, int pageIndex)
 {
     lock (ManagerLock)
     {
         page.ReadPageData(this.dataFile, pageIndex);
     }
 }
예제 #3
0
        // 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);
        }
예제 #4
0
        public object ReadRecord(int recordIdx)
        {
            if (recordIdx >= this.recordList.Count ||
                0 > recordIdx)
            {
                throw new InvalidRecordException();
            }

            object data = StoragePage.Deserialize(
                this.recordList[recordIdx]);

            return(data);
        }
예제 #5
0
        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);
        }
예제 #6
0
        public void WriteRecord(int recordIdx, object data)
        {
            if (recordIdx >= this.recordList.Count ||
                0 > recordIdx)
            {
                throw new InvalidRecordException();
            }

            // encode the data
            //byte[] record = RecordDataEncoder.GetBytes(data);
            byte[] record = StoragePage.Serialize(data);
            if (0 > this.GetAvailableSpace() + this.GetRecordSize(recordIdx) - this.GetRecordSize(record))
            {
                throw new InsuffcientSpaceException();
            }

            this.recordList[recordIdx] = record;
        }
예제 #7
0
        // writes a page to persistent storage and does book-keeping for allocated and freed pages
        private int aWritePageData(StoragePage page, StorageContext storageContext, int fileAddress)
        {
            lock (ManagerLock)
            {
                // store the index of the current page
                if (0 <= fileAddress)
                {
                    storageContext.FreedPageList.Add(fileAddress);
                }

                // write the page
                fileAddress = page.WritePageData(
                    this.dataFile, this.pageManager.GetFreePage());

                // store the index of the page we just wrote to
                storageContext.AllocatedPageList.Add(fileAddress);

                return(fileAddress);
            }
        }
예제 #8
0
        public int AddRecord(object data)
        {
            byte[] record = StoragePage.Serialize(data);
            if (0 > this.GetAvailableSpace() - this.GetRecordSize(record))
            {
                throw new InsuffcientSpaceException();
            }

            // lets find a space to insert this data
            int index = this.recordList.IndexOf(null);

            if (-1 == index)
            {
                index = this.recordList.Count;
            }

            // add the data
            this.recordList.Insert(index, record);

            // return to index
            return(this.recordList.IndexOf(record));
        }
예제 #9
0
        public void SP_TestAddRecord()
        {
            TestData[] testList =
            {
                new TestData{ data = "test data  1",   recordIdx = 0},
                new TestData{ data = "test data  2",   recordIdx = 1},
            };

            StoragePage page = new StoragePage();
            AddRecords(page, testList);

            // test adding a record when page is full
            string masterRecord = "1234567890";
            int maxCount =
                (StoragePage_Accessor.PageSize - sizeof(int))
                / (sizeof(int) + StoragePage_Accessor.Serialize(masterRecord).Length);

            List<TestData> noSpacetestList = new List<TestData>();
            for(int idx = 0; idx < maxCount; idx++)
            {
                TestData record = new TestData
                {
                    data = masterRecord,
                    recordIdx = idx,
                };
                noSpacetestList.Add(record);
            }
            noSpacetestList.Add(new TestData
            {
                data = masterRecord,
                exception = "InsuffcientSpaceException",
            });

            StoragePage page2 = new StoragePage();
            AddRecords(page2, noSpacetestList.ToArray());
        }
예제 #10
0
 private void WriteRecords(StoragePage page, TestData[] data)
 {
     foreach (TestData test in data)
     {
         try
         {
             page.WriteRecord(test.recordIdx, test.data);
         }
         catch (Exception e)
         {
             Assert.AreEqual(test.exception, e.GetType().Name,
                 "Unexpected exception. Test Data = [{0}]", test.ToString());
         }
     }
 }
예제 #11
0
 private void ReadRecords(StoragePage page, TestData[] data)
 {
     foreach (TestData test in data)
     {
         try
         {
             string result = (string)page.ReadRecord(test.recordIdx);
             Assert.AreEqual(test.data, result,
                 "Read record did not match. Test Data = [{0}]", test.ToString());
         }
         catch (Exception e)
         {
             Assert.AreEqual(test.exception, e.GetType().Name,
                 "Unexpected exception. Test Data = [{0}]", test.ToString());
         }
     }
 }
예제 #12
0
 private void AddRecords(StoragePage page, TestData[] data)
 {
     foreach (TestData test in data)
     {
         try
         {
             int result = page.AddRecord(test.data);
             Assert.AreEqual(test.recordIdx, result,
                 string.Format("Return value did not match. Test Data=[{0}]", test.ToString()));
         }
         catch (Exception e)
         {
             Assert.AreEqual(test.exception, e.GetType().Name,
                 "Unexpected exception. Test Data = [{0}]", test.ToString());
         }
     }
 }
예제 #13
0
        public void SP_TestReadWriteRecord()
        {
            TestData[] addList =
            {
                new TestData{data = "Record0", recordIdx = 0},
                new TestData{data = "Record1", recordIdx = 1},
            };
            TestData[] readAddList = addList;

            TestData[] readWriteTestList =
            {
                new TestData{data = "Record-1",  recordIdx = -1,                exception = "InvalidRecordException"},
                new TestData{data = "RecordMax", recordIdx = int.MaxValue,      exception = "InvalidRecordException"},
                new TestData{data = "RecordLen", recordIdx = addList.Length,    exception = "InvalidRecordException"},
                new TestData{data = "Record0_2", recordIdx = addList[0].recordIdx},
                new TestData{data = "Record1_2", recordIdx = addList[1].recordIdx},

            };

            TestData[] readWriteList = readWriteTestList;

            StoragePage page = new StoragePage();

            // setup the page by adding some records and
            // verify by reading the records back
            AddRecords(page, addList);
            ReadRecords(page, readAddList);

            // execute writes
            WriteRecords(page, readWriteTestList);
            ReadRecords(page, readWriteList);
        }
예제 #14
0
        public void SP_TestReadWritePage()
        {
            string dataFile = "SP_TestData1.tpdb";
            if (File.Exists(dataFile))
            {
                File.Delete(dataFile);
            }

            TestData[] pageData =
            {
                new TestData{data = "Record_0", recordIdx = 0},
                new TestData{data = "Record_1", recordIdx = 1},
                new TestData{data = "Record_2", recordIdx = 2}
            };

            int pageIndex = int.MinValue;

            // write the page
            using (FileStreamWrapper dataFileStream = FileStreamWrapper.CreateObject(dataFile))
            {
                // populate the page with some data
                StoragePage page = new StoragePage();
                AddRecords(page, pageData);

                // write the file to disk
                pageIndex = page.WritePageData(dataFileStream, -1);
            }

            // read the page
            using (FileStreamWrapper dataFileStream = FileStreamWrapper.CreateObject(dataFile))
            {
                // read page from file
                StoragePage page = new StoragePage();
                page.ReadPageData(dataFileStream, pageIndex);

                // validate the page data
                ReadRecords(page, pageData);
            }
        }
예제 #15
0
        public void SP_TestDeleteRecord()
        {
            TestData[] addList =
            {
                new TestData{ data = "Record0", recordIdx = 0 }
            };

            TestData[] deleteTestList =
            {
                new TestData{ recordIdx = -1,   exception = "InvalidRecordException"},
                new TestData{ recordIdx = 2,    exception = "InvalidRecordException"},
                new TestData{ recordIdx = 0,    exception = ""},
                new TestData{ recordIdx = 0,    exception = "InvalidRecordException"},
            };

            StoragePage page = new StoragePage();
            AddRecords(page, addList);
            DeleteRecords(page, deleteTestList);
        }
예제 #16
0
        // 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);
        }