예제 #1
0
        public static VersionEdit DecodeFrom(Stream stream)
        {
            var result = new VersionEdit();

            while (true)
            {
                Tag tag;
                try
                {
                    tag = (Tag)stream.Read7BitEncodedInt();
                }
                catch (EndOfStreamException)
                {
                    break;
                }

                int level;
                switch (tag)
                {
                    case Tag.Comparator:
                        var slice = stream.ReadLengthPrefixedSlice();
                        result.SetComparatorName(slice);
                        break;
                    case Tag.LogNumber:
                        result.SetLogNumber((ulong)stream.Read7BitEncodedLong());
                        break;
                    case Tag.PrevLogNumber:
                        result.SetPrevLogNumber((ulong)stream.Read7BitEncodedLong());
                        break;
                    case Tag.NextFileNumber:
                        result.SetNextFile((ulong)stream.Read7BitEncodedLong());
                        break;
                    case Tag.LastSequence:
                        result.SetLastSequence((ulong)stream.Read7BitEncodedLong());
                        break;
                    case Tag.CompactPointer:
                        level = stream.Read7BitEncodedInt();
                        var compactionPointer = stream.ReadLengthPrefixedInternalKey();

                        result.SetCompactionPointer(level, compactionPointer);
                        break;
                    case Tag.DeletedFile:
                        level = stream.Read7BitEncodedInt();
                        var fileNumber = (ulong)stream.Read7BitEncodedLong();

                        result.DeleteFile(level, fileNumber);
                        break;
                    case Tag.NewFile:
                        level = stream.Read7BitEncodedInt();
                        var fileMetadata = new FileMetadata
                                               {
                                                   FileNumber = (ulong)stream.Read7BitEncodedLong(),
                                                   FileSize = stream.Read7BitEncodedLong(),
                                                   SmallestKey = stream.ReadLengthPrefixedInternalKey(),
                                                   LargestKey = stream.ReadLengthPrefixedInternalKey()
                                               };

                        result.AddFile(level, fileMetadata);
                        break;
                }
            }

            return result;
        }
예제 #2
0
		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 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]);
		} 
예제 #4
0
		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;
			}
		}