public async Task Big() { var random = new Random(); var buffers = new List<byte[]>(); for (int i = 0; i < 15; i++) { var buffer = new byte[1044*33]; random.NextBytes(buffer); buffers.Add(buffer); } var memoryStream = new MemoryStream(); var logWriterStream = new LogWriter(new InMemoryFileSystem("test"),memoryStream, new BufferPool()); foreach (var buffer in buffers) { await CanReadAndWriteOkaySingleRecord.WriteRecordAsync(logWriterStream, buffer); } memoryStream.Position = 0; var logReader = new LogReader(memoryStream, true, 0, new BufferPool()); for (int i = 0; i < 15; i++) { Stream stream; Assert.True(logReader.TryReadRecord(out stream)); var actual = new MemoryStream(); stream.CopyTo(actual); Assert.Equal(buffers[i], actual.ToArray()); } }
public void WriteSnapshot(LogWriter logWriter, VersionSet versionSet) { var edit = new VersionEdit(); AddMetadata(edit, storageContext.Options); AddCompactionPointers(edit, versionSet); AddFiles(edit, versionSet); edit.EncodeTo(logWriter); }
public async Task Small() { var buffer = new byte[1044]; new Random().NextBytes(buffer); var memoryStream = new MemoryStream(); var logWriterStream = new LogWriter(new InMemoryFileSystem("test"), memoryStream, new BufferPool()); await WriteRecordAsync(logWriterStream, buffer); memoryStream.Position = 0; var logReader = new LogReader(memoryStream, true, 0, new BufferPool()); Stream stream; Assert.True(logReader.TryReadRecord(out stream)); var actual = new MemoryStream(); stream.CopyTo(actual); Assert.Equal(buffer, actual.ToArray()); }
public void EncodeTo(LogWriter writer) { writer.RecordStarted(); if (HasComparator) { writer.Write7BitEncodedInt((int)Tag.Comparator); writer.WriteLengthPrefixedSlice(Comparator); } if (LogNumber.HasValue) { writer.Write7BitEncodedInt((int)Tag.LogNumber); writer.Write7BitEncodedLong((long)LogNumber.Value); } if (PrevLogNumber.HasValue) { writer.Write7BitEncodedInt((int)Tag.PrevLogNumber); writer.Write7BitEncodedLong((long)PrevLogNumber.Value); } if (NextFileNumber.HasValue) { writer.Write7BitEncodedInt((int)Tag.NextFileNumber); writer.Write7BitEncodedLong((long)NextFileNumber.Value); } if (LastSequence.HasValue) { writer.Write7BitEncodedInt((int)Tag.LastSequence); writer.Write7BitEncodedLong((long)LastSequence.Value); } for (int level = 0; level < Config.NumberOfLevels; level++) { foreach (var compactionPointer in CompactionPointers[level]) { writer.Write7BitEncodedInt((int)Tag.CompactPointer); writer.Write7BitEncodedInt(level); writer.WriteLengthPrefixedInternalKey(compactionPointer); } foreach (var fileNumber in DeletedFiles[level]) { writer.Write7BitEncodedInt((int)Tag.DeletedFile); writer.Write7BitEncodedInt(level); writer.Write7BitEncodedLong((long)fileNumber); } foreach (var fileMetadata in NewFiles[level]) { writer.Write7BitEncodedInt((int)Tag.NewFile); writer.Write7BitEncodedInt(level); writer.Write7BitEncodedLong((long)fileMetadata.FileNumber); writer.Write7BitEncodedLong(fileMetadata.FileSize); writer.WriteLengthPrefixedInternalKey(fileMetadata.SmallestKey); writer.WriteLengthPrefixedInternalKey(fileMetadata.LargestKey); } } writer.RecordCompleted(true); }
public void ShouldEncodeAndDecode() { var versionEdit = new VersionEdit(); versionEdit.SetComparatorName("testComparator"); versionEdit.SetLastSequence(10); versionEdit.SetLogNumber(2); versionEdit.SetNextFile(3); versionEdit.SetPrevLogNumber(1); versionEdit.SetLastSequence(1); versionEdit.AddFile(0, new FileMetadata() { FileNumber = 0, FileSize = 128, LargestKey = new InternalKey("begin", Format.MaxSequenceNumber, ItemType.Value), SmallestKey = new InternalKey("end", Format.MaxSequenceNumber, ItemType.Value), }); versionEdit.AddFile(1, new FileMetadata() { FileNumber = 1, FileSize = 128, LargestKey = new InternalKey("begin", Format.MaxSequenceNumber, ItemType.Value), SmallestKey = new InternalKey("end", Format.MaxSequenceNumber, ItemType.Value), }); versionEdit.DeleteFile(0, 3); versionEdit.DeleteFile(1, 4); versionEdit.SetCompactionPointer(0, new InternalKey("begin", Format.MaxSequenceNumber, ItemType.Value)); versionEdit.SetCompactionPointer(1, new InternalKey("end", Format.MaxSequenceNumber, ItemType.Value)); var memoryStream = new MemoryStream(); var logWriter = new LogWriter(new InMemoryFileSystem("test"),memoryStream, new BufferPool()); versionEdit.EncodeTo(logWriter); memoryStream.Position = 0; var afterDecode = VersionEdit.DecodeFrom(new LogRecordStream(memoryStream, true, new BufferPool())); Assert.Equal(versionEdit.Comparator, afterDecode.Comparator); Assert.Equal(versionEdit.LogNumber, afterDecode.LogNumber); Assert.Equal(versionEdit.NextFileNumber, afterDecode.NextFileNumber); Assert.Equal(versionEdit.PrevLogNumber, afterDecode.PrevLogNumber); Assert.Equal(versionEdit.LogNumber, afterDecode.LogNumber); Assert.Equal(versionEdit.PrevLogNumber, afterDecode.PrevLogNumber); Assert.Equal(versionEdit.LastSequence, afterDecode.LastSequence); Assert.Equal(versionEdit.NewFiles[0][0].FileNumber, afterDecode.NewFiles[0][0].FileNumber); Assert.Equal(versionEdit.NewFiles[0][0].FileSize, afterDecode.NewFiles[0][0].FileSize); Assert.Equal(versionEdit.NewFiles[0][0].LargestKey, afterDecode.NewFiles[0][0].LargestKey); Assert.Equal(versionEdit.NewFiles[0][0].SmallestKey, afterDecode.NewFiles[0][0].SmallestKey); Assert.Equal(versionEdit.NewFiles[1][0].FileNumber, afterDecode.NewFiles[1][0].FileNumber); Assert.Equal(versionEdit.NewFiles[1][0].FileSize, afterDecode.NewFiles[1][0].FileSize); Assert.Equal(versionEdit.NewFiles[1][0].LargestKey, afterDecode.NewFiles[1][0].LargestKey); Assert.Equal(versionEdit.NewFiles[1][0].SmallestKey, afterDecode.NewFiles[1][0].SmallestKey); Assert.Equal(versionEdit.DeletedFiles[0][0], afterDecode.DeletedFiles[0][0]); Assert.Equal(versionEdit.DeletedFiles[1][0], afterDecode.DeletedFiles[1][0]); Assert.Equal(versionEdit.CompactionPointers[0][0], afterDecode.CompactionPointers[0][0]); Assert.Equal(versionEdit.CompactionPointers[1][0], afterDecode.CompactionPointers[1][0]); }
public static async Task WriteRecordAsync(LogWriter logWriterStream, byte[] buffer) { logWriterStream.RecordStarted(); await logWriterStream.WriteAsync(buffer, 0, buffer.Length); logWriterStream.RecordCompleted(true); }
public async Task LogAndApplyAsync(VersionEdit edit, AsyncLock.LockScope locker) { string newManifestFile = null; try { Version version; using (await locker.LockAsync()) { if (!edit.LogNumber.HasValue) edit.SetLogNumber(VersionSet.LogNumber); else if (edit.LogNumber < VersionSet.LogNumber || edit.LogNumber >= VersionSet.NextFileNumber) throw new InvalidOperationException("LogNumber"); if (!edit.PrevLogNumber.HasValue) edit.SetPrevLogNumber(VersionSet.PrevLogNumber); edit.SetNextFile(VersionSet.NextFileNumber); edit.SetLastSequence(VersionSet.LastSequence); version = new Version(this, VersionSet); var builder = new Builder(this, VersionSet, VersionSet.Current); builder.Apply(edit); builder.SaveTo(version); Version.Finalize(version); // Initialize new descriptor log file if necessary by creating // a temporary file that contains a snapshot of the current version. if (DescriptorLogWriter == null) { // No reason to unlock *mu here since we only hit this path in the // first call to LogAndApply (when opening the database). newManifestFile = FileSystem.DescriptorFileName(VersionSet.ManifestFileNumber); edit.SetNextFile(VersionSet.NextFileNumber); var descriptorFile = FileSystem.NewWritable(newManifestFile); DescriptorLogWriter = new LogWriter(FileSystem, descriptorFile, Options.BufferPool); Snapshooter.WriteSnapshot(DescriptorLogWriter, VersionSet); } } // Write new record to MANIFEST log edit.EncodeTo(DescriptorLogWriter); // If we just created a new descriptor file, install it by writing a // new CURRENT file that points to it. if (!string.IsNullOrEmpty(newManifestFile)) { SetCurrentFile(VersionSet.ManifestFileNumber); // No need to double-check MANIFEST in case of error since it // will be discarded below. } using (await locker.LockAsync()) { // Install the new version VersionSet.AppendVersion(version); VersionSet.SetLogNumber(edit.LogNumber.Value); VersionSet.SetPrevLogNumber(edit.PrevLogNumber.Value); } } catch (Exception) { if (!string.IsNullOrEmpty(newManifestFile)) { if (DescriptorLogWriter != null) { DescriptorLogWriter.Dispose(); DescriptorLogWriter = null; } FileSystem.DeleteFile(newManifestFile); } throw; } }
public void CreateNewLog() { var newFileNumber = VersionSet.NewFileNumber(); try { var name = FileSystem.GetLogFileName(newFileNumber); var file = FileSystem.NewWritable(name); LogWriter = new LogWriter(FileSystem, file, Options.BufferPool); LogFileNumber = newFileNumber; } catch (Exception) { // Avoid chewing through file number space in a tight loop. VersionSet.ReuseFileNumber(newFileNumber); throw; } }
public void CreateNewDatabase() { var newDb = new VersionEdit(); newDb.SetComparatorName(Options.Comparator.Name); newDb.SetLogNumber(0); newDb.SetNextFile(2); newDb.SetLastSequence(0); var manifest = FileSystem.DescriptorFileName(1); try { using (var file = FileSystem.NewWritable(manifest)) { using (var logWriter = new LogWriter(FileSystem, file, Options.BufferPool)) { newDb.EncodeTo(logWriter); } } SetCurrentFile(1); } catch (Exception) { FileSystem.DeleteFile(manifest); throw; } }