public override void AllocateMorePages(Transaction tx, long newLength)
        {
            ThrowObjectDisposedIfNeeded();
            var newLengthAfterAdjustment = NearestSizeToAllocationGranularity(newLength);

            if (newLengthAfterAdjustment <= _totalAllocationSize)
                return;

            var allocationSize = newLengthAfterAdjustment - _totalAllocationSize;

            if (TryAllocateMoreContinuousPages(allocationSize) == false)
            {
                var newPagerState = AllocateMorePagesAndRemapContinuously(allocationSize);
                if (newPagerState == null)
                {
                    var errorMessage = string.Format(
                        "Unable to allocate more pages - unsuccessfully tried to allocate continuous block of virtual memory with size = {0:##,###;;0} bytes",
                        (_totalAllocationSize + allocationSize));

                    throw new OutOfMemoryException(errorMessage);
                }
                newPagerState.DebugVerify(newLengthAfterAdjustment);

                newPagerState.AddRef();
                if (tx != null)
                {
                    tx.EnsurePagerStateReference(newPagerState);
                }
                // we always share the same memory mapped files references between all pages, since to close them
                // would be to lose all the memory associated with them
                PagerState.DisposeFilesOnDispose = false;
                var tmp = PagerState;
                PagerState = newPagerState;
                tmp.Release(); //replacing the pager state --> so one less reference for it
            }

            _totalAllocationSize += allocationSize;
            NumberOfAllocatedPages = _totalAllocationSize / PageSize;
        }
        public void RefreshMappedView(Transaction tx)
        {
            PagerState newPagerState = CreatePagerState();

            if (tx != null)
            {
                tx.EnsurePagerStateReference(newPagerState);
            }

            var tmp = PagerState;
            PagerState = newPagerState;
            tmp.Release(); //replacing the pager state --> so one less reference for it
        }
        public Transaction NewTransaction(TransactionFlags flags, TimeSpan? timeout = null)
        {
            bool txLockTaken = false;
            try
            {
                if (flags == (TransactionFlags.ReadWrite))
                {
                    var wait = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(30));
                    Monitor.TryEnter(_txWriter, wait, ref txLockTaken);
                    if (txLockTaken == false)
                    {
                        throw new TimeoutException("Waited for " + wait +
                                                    " for transaction write lock, but could not get it");
                    }
                    
                    if (_endOfDiskSpace != null)
                    {
                        if (_endOfDiskSpace.CanContinueWriting)
                        {
                            var flushingTask = _flushingTask;
                            Debug.Assert(flushingTask != null && (flushingTask.Status == TaskStatus.Canceled || flushingTask.Status == TaskStatus.RanToCompletion));
                            _cancellationTokenSource = new CancellationTokenSource();
                            _flushingTask = FlushWritesToDataFileAsync();
                            _endOfDiskSpace = null;
                        }
                    }
                }

                Transaction tx;

                _txCommit.EnterReadLock();
                try
                {
                    long txId = flags == TransactionFlags.ReadWrite ? _transactionsCounter + 1 : _transactionsCounter;
                    tx = new Transaction(this, txId, flags, _freeSpaceHandling);

                    if (IsDebugRecording)
                    {
                        RecordTransactionState(tx, DebugActionType.TransactionStart);
                        tx.RecordTransactionState = RecordTransactionState;
                    }
                }
                finally
                {
                    _txCommit.ExitReadLock();
                }

                _activeTransactions.Add(tx);
                tx.EnsurePagerStateReference(_dataPager.PagerState);

                if (flags == TransactionFlags.ReadWrite)
                {
                    tx.AfterCommit = TransactionAfterCommit;
                }

                return tx;
            }
            catch (Exception)
            {
                if (txLockTaken)
                    Monitor.Exit(_txWriter);
                throw;
            }
        }
示例#4
0
        public override void AllocateMorePages(Transaction tx, long newLength)
        {
            ThrowObjectDisposedIfNeeded();
            var newLengthAfterAdjustment = NearestSizeToPageSize(newLength);

            if (newLengthAfterAdjustment <= _totalAllocationSize)
                return;

            var allocationSize = newLengthAfterAdjustment - _totalAllocationSize;

            PosixHelper.AllocateFileSpace(_fd, (ulong) (_totalAllocationSize + allocationSize));
            PagerState newPagerState = CreatePagerState();
            if (newPagerState == null)
            {
                var errorMessage = string.Format(
                    "Unable to allocate more pages - unsuccessfully tried to allocate continuous block of virtual memory with size = {0:##,###;;0} bytes",
                    (_totalAllocationSize + allocationSize));

                throw new OutOfMemoryException(errorMessage);
            }

            newPagerState.DebugVerify(newLengthAfterAdjustment);

            if (tx != null)
            {
                tx.EnsurePagerStateReference(newPagerState);
            }

            var tmp = PagerState;
            PagerState = newPagerState;
            tmp.Release(); //replacing the pager state --> so one less reference for it

            _totalAllocationSize += allocationSize;
            NumberOfAllocatedPages = _totalAllocationSize/PageSize;
        }