public EventStream(StreamOptions options)
		{
			_options = options;
			_options.Initialize();
			_currentBufferSize = _options.InitialInMemoryBuffer;
			long log;
			_memTable = new MemRange
				{
					MemTable = new MemTable(_currentBufferSize, new InternalKeyComparator(options.Comparator), _options.BufferPool),
					Start = EtagToSlice(Etag.Empty),
					Log = new LogWriter(_options.CreateNewLogFile(out log), _options.BufferPool),
					LogNumber = log
				};
		}
		private void WriteMemTableToDisk(MemRange range)
		{
			string fileName;
			Slice first = new Slice(), last = new Slice();
			using (var stream = _options.CreateNewTableFile(out fileName))
			using (var builder = new TableBuilder(_options, stream, _options.Storage.CreateTemp))
			using (var it = range.MemTable.NewIterator())
			{
				it.SeekToFirst();
				while (it.IsValid)
				{
					if (first.Array == null)
						first = it.Key;
					last = it.Key;
					using (var valueStream = it.CreateValueStream())
						builder.Add(it.Key, valueStream);
					it.Next();
				}
				builder.Finish();
				_options.Storage.Flush(stream);
			}
			lock (_metadataLocker)
			{
				_options.Status.Ranges = new List<CurrentStatus.SstRange>(_options.Status.Ranges)
					{
						new CurrentStatus.SstRange
							{
								End = last,
								Name = fileName,
								Start = first,
								Count = range.MemTable.Count
							}
					};
				_options.Status.LastCompletedLog = range.LogNumber;
				_options.FlushStatus();
			}
		}
		// REQUIRE: no other concurrent access to the event stream
		public async Task FlushMemTableToFiskAsync(Etag newEtag)
		{
			if (_flushingMemTable != null)
			{
				// we are currently writing this to disk, let us wait for that
				try
				{
					await _flushingMemTable;
				}
				finally
				{
					_flushingMemTable = null;
					_immutableMemTable = null;
				}
			}

			if (_memTable.MemTable.Count == 0)
			{
				return;
			}

			var imm = _memTable;

			_flushingMemTable = Task.Factory.StartNew(() => WriteMemTableToDisk(imm));

			lock (_metadataLocker)
			{
				_immutableMemTable = _memTable;
				_flushingMemTable = _flushingMemTable.ContinueWith(task =>
					{
						using (imm)
						{
							_immutableMemTable = null;
						}
					});
				long log;
				_memTable = new MemRange
					{
						MemTable = new MemTable(_currentBufferSize, new InternalKeyComparator(_options.Comparator), _options.BufferPool),
						Start = EtagToSlice(newEtag),
						Log = new LogWriter(_options.CreateNewLogFile(out log), _options.BufferPool),
						LogNumber = log
					};
			}
		}