Пример #1
0
 /// <summary>
 /// Creates a new page in storage. A page with this number must not already exist
 /// </summary>
 public IPage NewPage(ulong pageNumber)
 {
     using (var page = _pagePool.Get(pageNumber, true))
     {
         lock (_pages) _pages.Add(pageNumber, new PageHead(pageNumber, page));
         return(page.Reference());
     }
 }
Пример #2
0
        public void should_write_directly_to_data()
        {
            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _pageSize, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, true, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            _fileSet.Write(
                null,
                Enumerable.Repeat(
                    new PageUpdate
            {
                SequenceNumber = 0,
                PageNumber     = 1,
                Offset         = 20,
                Data           = new byte[] { 5, 6, 7 }
            },
                    1));

            using (var page = _pagePool.Get(1))
            {
                _fileSet.Read(page);

                Assert.AreEqual(5, page.Data[20]);
                Assert.AreEqual(6, page.Data[21]);
                Assert.AreEqual(7, page.Data[22]);
            }
        }
Пример #3
0
        public ulong Allocate(ushort pageCount)
        {
            var pageNumber = _nextPage;

            _nextPage += pageCount;

            for (ushort i = 0; i < pageCount; i++)
            {
                _pages.Add(pageNumber + i, _pagePool.Get(pageNumber + i, true));
            }

            return(pageNumber);
        }
Пример #4
0
        Task IPageCache.CommitTransaction(ITransaction transaction)
        {
            using (var transactionHead = CleanupTransaction(transaction))
            {
                if (transactionHead == null || transactionHead.Updates == null || transactionHead.Updates.Count == 0)
                {
                    return(null);
                }

                var versionHead = _versions.Add(transaction.CommitVersionNumber);

                IPage newPage = null;
                foreach (var update in transactionHead.Updates.OrderBy(u => u.PageNumber).ThenBy(u => u.SequenceNumber))
                {
                    if (newPage == null || update.PageNumber != newPage.PageNumber)
                    {
                        var pageHead      = _pages.GetPageHead(update.PageNumber, CacheHints.ForUpdate);
                        var newestVersion = pageHead.GetVersion(null);

                        newPage = _pagePool.Get(update.PageNumber);
                        newestVersion.Data.CopyTo(newPage.Data, 0);

                        versionHead.AddPage(new PageVersion(versionHead.VersionNumber, newPage));
                    }

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

                versionHead.AddToPages(_pages);

                return(_fileSet.WriteAndCommit(transaction, transactionHead.Updates));
            }
        }
Пример #5
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();
                }
            }
        }