コード例 #1
0
		public void WriteSnapshot(LogWriter logWriter, VersionSet versionSet)
		{
			var edit = new VersionEdit();
			AddMetadata(edit, storageContext.Options);
			AddCompactionPointers(edit, versionSet);
			AddFiles(edit, versionSet);

			edit.EncodeTo(logWriter);
		}
コード例 #2
0
		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]);
		} 
コード例 #3
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;
			}
		}
コード例 #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;
			}
		}