private ScratchBufferItem NextFile(long minSize, long?requestedSize) { var current = _recycleArea.Last; var oldestTx = _env.PossibleOldestReadTransaction(null); while (current != null) { var recycled = current.Value; if (recycled.File.Size >= Math.Max(minSize, requestedSize ?? 0) && // even though this is in the recyle bin, there might still be some transactions looking at it // so we have to make sure that this is really unused before actually reusing it recycled.File.HasActivelyUsedBytes(oldestTx) == false) { recycled.File.Reset(); recycled.RecycledAt = default(DateTime); _recycleArea.Remove(current); AddScratchBufferFile(recycled); _scratchSpaceMonitor.Increase(recycled.File.NumberOfAllocatedPages * Constants.Storage.PageSize); return(recycled); } current = current.Previous; } _currentScratchNumber++; AbstractPager scratchPager; if (requestedSize != null) { try { scratchPager = _options.CreateScratchPager(StorageEnvironmentOptions.ScratchBufferName(_currentScratchNumber), requestedSize.Value); } catch (Exception) { // this can fail because of disk space issue, let us just ignore it // we'll allocate the minimum amount in a bit anyway return(NextFile(minSize, null)); } } else { scratchPager = _options.CreateScratchPager(StorageEnvironmentOptions.ScratchBufferName(_currentScratchNumber), Math.Max(_options.InitialLogFileSize, minSize)); } var scratchFile = new ScratchBufferFile(scratchPager, _currentScratchNumber); var item = new ScratchBufferItem(scratchFile.Number, scratchFile); AddScratchBufferFile(item); _scratchSpaceMonitor.Increase(item.File.NumberOfAllocatedPages * Constants.Storage.PageSize); return(item); }