コード例 #1
0
        public DecompressedLeafPage(byte *basePtr, int pageSize, DecompressionUsage usage, TreePage original, TemporaryPage tempPage) : base(basePtr, pageSize)
        {
            Original  = original;
            Usage     = usage;
            _tempPage = tempPage;

            PageNumber = Original.PageNumber;
            TreeFlags  = Original.TreeFlags;
            Flags      = Original.Flags & ~PageFlags.Compressed;
        }
コード例 #2
0
            public DecompressionBuffer(AbstractPager pager, long position, int size, DecompressionBuffersPool pool, int index, LowLevelTransaction tx)
            {
                _pager    = pager;
                _position = position;
                _size     = size;
                _pool     = pool;
                _index    = index;
                _pager.EnsureMapped(tx, _position, _size / Constants.Storage.PageSize);
                var ptr = _pager.AcquirePagePointer(tx, position);

                TempPage = new TemporaryPage(ptr, size)
                {
                    ReturnTemporaryPageToPool = this
                };
            }
コード例 #3
0
        public unsafe StorageEnvironment(StorageEnvironmentOptions options)
        {
            try
            {
                TemporaryPage      = new TemporaryPage();
                _options           = options;
                _dataPager         = options.DataPager;
                _freeSpaceHandling = new FreeSpaceHandling(this);
                _sliceComparer     = NativeMethods.memcmp;
                _headerAccessor    = new HeaderAccessor(this);
                var isNew = _headerAccessor.Initialize();

                _scratchBufferPool = new ScratchBufferPool(this);

                _journal = new WriteAheadJournal(this);

                if (isNew)
                {
                    CreateNewDatabase();
                }
                else // existing db, let us load it
                {
                    LoadExistingDatabase();
                }

                State.FreeSpaceRoot.Name = Constants.FreeSpaceTreeName;
                State.Root.Name          = Constants.RootTreeName;

                Writer = new TransactionMergingWriter(this);

                if (_options.ManualFlushing == false)
                {
                    _flushingTask = FlushWritesToDataFileAsync();
                }
            }
            catch (Exception)
            {
                Dispose();
                throw;
            }
        }
コード例 #4
0
        public IDisposable GetTemporaryPage(Transaction tx, out TemporaryPage tmp)
        {
            if (tx.Flags != TransactionFlags.ReadWrite)
            {
                throw new ArgumentException("Temporary pages are only available for write transactions");
            }
            if (_tempPagesPool.Count > 0)
            {
                tmp = _tempPagesPool.Dequeue();
                return(tmp.ReturnTemporaryPageToPool);
            }

            tmp = new TemporaryPage();
            try
            {
                return(tmp.ReturnTemporaryPageToPool = new ReturnTemporaryPageToPool(this, tmp));
            }
            catch (Exception)
            {
                tmp.Dispose();
                throw;
            }
        }
コード例 #5
0
        public IDisposable GetTemporaryPage(LowLevelTransaction tx, int pageSize, out TemporaryPage tmp)
        {
            if (pageSize < Constants.Storage.PageSize)
            {
                ThrowInvalidPageSize(pageSize);
            }

            if (pageSize > Constants.Compression.MaxPageSize)
            {
                ThrowPageSizeTooBig(pageSize);
            }

            Debug.Assert(pageSize == Bits.NextPowerOf2(pageSize));

            EnsureInitialized();

            var index = GetTempPagesPoolIndex(pageSize);

            if (_pool.Length <= index)
            {
                lock (_expandPoolLock)
                {
                    if (_pool.Length <= index) // someone could get the lock and add it meanwhile
                    {
                        var oldSize = _pool.Length;

                        var newPool = new ConcurrentQueue <DecompressionBuffer> [index + 1];
                        Array.Copy(_pool, newPool, _pool.Length);
                        for (var i = oldSize; i < newPool.Length; i++)
                        {
                            newPool[i] = new ConcurrentQueue <DecompressionBuffer>();
                        }
                        _pool = newPool;
                    }
                }
            }

            DecompressionBuffer buffer;

            var queue = _pool[index];

            tmp = null;

            while (queue.TryDequeue(out buffer))
            {
                if (buffer.CanReuse == false)
                {
                    continue;
                }

                try
                {
                    buffer.EnsureValidPointer(tx);
                    tmp = buffer.TempPage;
                    break;
                }
                catch (ObjectDisposedException)
                {
                    // we could dispose the pager during the cleanup
                }
            }

            if (tmp == null)
            {
                var allocationInPages = pageSize / Constants.Storage.PageSize;

                lock (_decompressionPagerLock) // once we fill up the pool we won't be allocating additional pages frequently
                {
                    if (_lastUsedPage + allocationInPages > _maxNumberOfPagesInScratchBufferPool)
                    {
                        CreateNewBuffersPager(_options.MaxScratchBufferSize);
                    }

                    try
                    {
                        _compressionPager.EnsureContinuous(_lastUsedPage, allocationInPages);
                    }
                    catch (InsufficientMemoryException)
                    {
                        // RavenDB-10830: failed to lock memory of temp buffers in encrypted db, let's create new file with initial size

                        CreateNewBuffersPager(DecompressedPagesCache.Size * Constants.Compression.MaxPageSize);
                        throw;
                    }

                    buffer = new DecompressionBuffer(_compressionPager, _lastUsedPage, pageSize, this, index, tx);

                    _lastUsedPage += allocationInPages;

                    void CreateNewBuffersPager(long size)
                    {
                        _oldPagers        = _oldPagers.Append(_compressionPager);
                        _compressionPager = CreateDecompressionPager(size);
                        _lastUsedPage     = 0;
                    }
                }

                tmp = buffer.TempPage;
            }

            Interlocked.Add(ref _currentlyUsedBytes, pageSize);

            return(tmp.ReturnTemporaryPageToPool);
        }
コード例 #6
0
 public ReturnTemporaryPageToPool(StorageEnvironment env, TemporaryPage tmp)
 {
     _tmp = tmp;
     _env = env;
 }