예제 #1
0
 /// <summary>
 /// This is used during the commit of a transaction. It takes all the new
 /// page versions that were constructed during the commit merge and adds them
 /// to a dictionary of pages
 /// </summary>
 /// <param name="pages">The dictionary of pages to add to</param>
 public void AddToPages(PageHeadCollection pages)
 {
     foreach (var pageVersionElement in _pageVersions)
     {
         var pageVersion = pageVersionElement.Data;
         var pageNumber  = pageVersion.Page.PageNumber;
         var pageHead    = pages.GetPageHead(pageNumber, CacheHints.ForUpdate);
         pageHead.AddVersion(pageVersion);
     }
 }
예제 #2
0
        public void AddUpdates(IEnumerable <PageUpdate> updates, PageHeadCollection pages)
        {
            EnsureUpdates();

            var start = Updates.Count;
            int end;

            lock (Updates)
            {
                Updates.AddRange(updates.OrderBy(u => u.SequenceNumber).Select(u => { u.SequenceNumber += (uint)start; return(u); }));
                end = Updates.Count;
            }

            for (var i = start; i < end; i++)
            {
                PageUpdate update;
                lock (Updates) update = Updates[i];

                IPage modifiedPage = null;
                try
                {
                    lock (Transaction)
                    {
                        modifiedPage = GetModifiedPage(update.PageNumber);
                        if (modifiedPage == null)
                        {
                            modifiedPage = _pagePool.Get(update.PageNumber);

                            var pageHead = pages.GetPageHead(update.PageNumber, CacheHints.ForUpdate);

                            using (var originalPage = pageHead.GetVersion(Root.Transaction.BeginVersionNumber))
                                originalPage.Data.CopyTo(modifiedPage.Data, 0);

                            SetModifiedPage(modifiedPage);
                        }
                        update.Data.CopyTo(modifiedPage.Data, update.Offset);
                    }
                }
                finally
                {
                    modifiedPage.Dispose();
                }
            }
        }
예제 #3
0
        public PageCache(
            IFileSet fileSet,
            IDatabase database,
            IPagePoolFactory pagePoolFactory,
            IStartupLog startupLog,
            IErrorLog errorLog)
        {
            _startupLog = startupLog;
            _errorLog   = errorLog;
            _fileSet    = fileSet;
            _database   = database;

            startupLog.WriteLine("Creating a new page cache for " + _fileSet);

            _pagePool = pagePoolFactory.Create(fileSet.PageSize);

            _pages        = new PageHeadCollection(fileSet, startupLog, errorLog, _pagePool);
            _versions     = new VersionHeadCollection(startupLog, errorLog, database);
            _transactions = new TransactionHeadCollection(startupLog, errorLog, _pagePool);
        }
        public void Update(ITransaction transaction, IEnumerable <PageUpdate> updates, PageHeadCollection pages)
        {
            if (transaction == null)
            {
                IPage page = null;

                foreach (var update in updates.OrderBy(u => u.PageNumber).ThenBy(u => u.SequenceNumber))
                {
                    if (page == null || page.PageNumber != update.PageNumber)
                    {
                        if (page != null)
                        {
                            page.Dispose();
                        }
                        page = pages.GetPageHead(update.PageNumber, CacheHints.ForUpdate).GetVersion(null);
                    }
                    update.Data.CopyTo(page.Data, update.Offset);
                }

                if (page != null)
                {
                    page.Dispose();
                }

                return;
            }

            TransactionHead transactionHead;

            lock (_transactions)
                if (!_transactions.TryGetValue(transaction.TransactionId, out transactionHead))
                {
                    throw new FileLayerException("You can not apply updates to a transaction context before the transaction has begun or after it has ended");
                }

            transactionHead.AddUpdates(updates, pages);
        }
        public IPage GetPage(ITransaction transaction, ulong pageNumber, CacheHints hints, PageHeadCollection pages)
        {
            PageHead pageHead;

            if (transaction == null)
            {
                pageHead = pages.GetPageHead(pageNumber, hints);
                return(pageHead == null ? null : pageHead.GetVersion(null));
            }

            TransactionHead transactionHead;

            lock (_transactions)
                if (!_transactions.TryGetValue(transaction.TransactionId, out transactionHead))
                {
                    throw new FileLayerException("You can not get pages for a transaction until you begin the transaction");
                }

            var modifiedPage = transactionHead.GetModifiedPage(pageNumber);

            if (modifiedPage != null)
            {
                return(modifiedPage);
            }

            pageHead = pages.GetPageHead(pageNumber, hints);
            return(pageHead == null ? null : pageHead.GetVersion(transactionHead.Root.Transaction.BeginVersionNumber));
        }