Exemplo n.º 1
0
        // 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);
            }
        }
Exemplo n.º 2
0
        private StorageContext ReadStorageContext(TransItem contextData, out List <int> oldStorageContextPages)
        {
            // allocate the storage page list
            oldStorageContextPages = new List <int>();

            // look for the context in the map
            StorageContext storageContext = new StorageContext();

            // read in the page table
            if (TransItem.NotStored != contextData.PageTableStartPage)
            {
                storageContext.PageTable.ReadPageTableData(
                    this.dataFile, contextData.PageTableStartPage);
                oldStorageContextPages.AddRange(
                    storageContext.PageTable.GetStoragePages());
            }

            // read in the resource index
            if (TransItem.NotStored != contextData.ResourceIndexStartPage)
            {
                storageContext.ResourceIndex.ReadIndexData(
                    this.dataFile, contextData.ResourceIndexStartPage);
                oldStorageContextPages.AddRange(
                    storageContext.ResourceIndex.GetStoragePages());
            }

            // read in the reservation index
            if (TransItem.NotStored != contextData.ReservationIndexStartPage)
            {
                storageContext.ReservationIndex.ReadIndexData(
                    this.dataFile, contextData.ReservationIndexStartPage);
                oldStorageContextPages.AddRange(
                    storageContext.ReservationIndex.GetStoragePages());
            }

            // read in the allocated page list
            if (TransItem.NotStored != contextData.AllocatedPageListStartPage)
            {
                List <int> usedPages = null;
                List <int> data      = null;

                ListReader <int> reader = new ListReader <int>();
                reader.ReadList(this.dataFile, contextData.AllocatedPageListStartPage, out data, out usedPages);

                storageContext.AllocatedPageList = data;
                oldStorageContextPages.AddRange(usedPages);
            }

            // read in the freed page list
            if (TransItem.NotStored != contextData.FreedPageListStartPage)
            {
                List <int> usedPages = null;
                List <int> data      = null;

                ListReader <int> reader = new ListReader <int>();
                reader.ReadList(this.dataFile, contextData.FreedPageListStartPage, out data, out usedPages);

                storageContext.FreedPageList = data;
                oldStorageContextPages.AddRange(usedPages);
            }

            return(storageContext);
        }
Exemplo n.º 3
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);
        }