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 }; } }