Example #1
0
        Task IFileSet.FinalizeTransaction(ITransaction transaction)
        {
            TransactionDetail transactionDetail;

            lock (_transactions)
            {
                if (!_transactions.TryGetValue(transaction, out transactionDetail))
                {
                    return(Task.CompletedTask);
                }
                _transactions.Remove(transaction);
            }

            // TODO: needs to be a single thread with a queue to ensure transactions are committed in order
            // TODO: maybe group updates by page across multiple transactions

            var task = Task.Run(() =>
            {
                var updatesByPage = transactionDetail.PendingUpdates
                                    .OrderBy(u => u.PageNumber)
                                    .ThenBy(u => u.SequenceNumber);

                IPage page = null;
                ulong filePageNumber;
                int fileIndex;

                foreach (var update in updatesByPage)
                {
                    if (page == null || page.PageNumber != update.PageNumber)
                    {
                        if (page != null)
                        {
                            GetPageLocation(page.PageNumber, out filePageNumber, out fileIndex);
                            _dataFiles[fileIndex].Write(filePageNumber, page.Data);
                            page.Dispose();
                        }

                        page = _pagePool.Get(update.PageNumber);
                        GetPageLocation(update.PageNumber, out filePageNumber, out fileIndex);
                        _dataFiles[fileIndex].Read(filePageNumber, page.Data);
                    }

                    update.Data.CopyTo(page.Data, update.Offset);
                }

                if (page != null)
                {
                    GetPageLocation(page.PageNumber, out filePageNumber, out fileIndex);
                    _dataFiles[fileIndex].Write(filePageNumber, page.Data);
                    page.Dispose();
                }

                _logFiles[transactionDetail.LogFileIndex].CommitComplete(transactionDetail.LogFileOffset);
            });

            return(task);
        }
    /// <inheritdoc/>
    public void NavTo(Type pageType)
    {
        if (disposedValue)
        {
            throw new ObjectDisposedException(nameof(PageNavigator));
        }

        if (pageType is null)
        {
            throw new ArgumentNullException(nameof(pageType));
        }

        IPage page = Dispatcher.Invoke(() =>
                                       (IPage)ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, pageType));

        if (page is not Page pg)
        {
            throw new ArgumentException("invalid type", nameof(pageType));
        }

        if (!TryNavTo(pg))
        {
            page.Dispose();
        }
    }
Example #3
0
 public void Dispose()
 {
     lock (lockToken)
     {
         page.Dispose();
     }
 }
Example #4
0
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         p.Dispose();
     }
     base.Dispose(disposing);
 }
Example #5
0
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         pageRepository.Dispose();
         pageGroupRepository.Dispose();
     }
     base.Dispose(disposing);
 }
        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);
        }
Example #7
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();
                }
            }
        }