private IList <ValueTuple <Checksum, object> > ReadAssets( Stream stream, int sessionId, ISet <Checksum> checksums, CancellationToken cancellationToken) { var results = new List <ValueTuple <Checksum, object> >(); using (var reader = StreamObjectReader.TryGetReader(stream)) { Debug.Assert(reader != null, @"We only ge a reader for data transmitted between live processes. This data should always be correct as we're never persisting the data between sessions."); var responseSessionId = reader.ReadInt32(); Contract.ThrowIfFalse(sessionId == responseSessionId); var count = reader.ReadInt32(); Contract.ThrowIfFalse(count == checksums.Count); for (var i = 0; i < count; i++) { var responseChecksum = new Checksum(reader.ReadArray <byte>()); Contract.ThrowIfFalse(checksums.Contains(responseChecksum)); var kind = reader.ReadString(); // in service hub, cancellation means simply closed stream var @object = _owner.RoslynServices.AssetService.Deserialize <object>(kind, reader, cancellationToken); results.Add(ValueTuple.Create(responseChecksum, @object)); } return(results); } }
private static async Task <bool> PrecalculatedAsync(Document document, string persistenceName, string formatVersion, CancellationToken cancellationToken) { Contract.Requires(document.IsFromPrimaryBranch()); var persistentStorageService = document.Project.Solution.Workspace.Services.GetService <IPersistentStorageService>(); var syntaxVersion = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false); // check whether we already have info for this document try { using (var storage = persistentStorageService.GetStorage(document.Project.Solution)) using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false)) using (var reader = StreamObjectReader.TryGetReader(stream)) { if (reader != null) { return(TryReadVersion(reader, formatVersion, out var persistVersion) && document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistVersion)); } } } catch (Exception e) when(IOUtilities.IsNormalIOException(e)) { // Storage APIs can throw arbitrary exceptions. } return(false); }
private static async Task VerifyOptionSetsAsync(Workspace workspace, string language) { var assetBuilder = new CustomAssetBuilder(workspace.CurrentSolution); var serializer = new Serializer(workspace.Services); var asset = assetBuilder.Build(workspace.Options, language, CancellationToken.None); using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new StreamObjectWriter(stream)) { await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = new StreamObjectReader(stream)) { var recovered = serializer.Deserialize <OptionSet>(asset.Kind, reader, CancellationToken.None); var assetFromStorage = assetBuilder.Build(recovered, language, CancellationToken.None); Assert.Equal(asset.Checksum, assetFromStorage.Checksum); // option should be exactly same Assert.Equal(0, recovered.GetChangedOptions(workspace.Options).Count()); } } }
private IList<ValueTuple<Checksum, object>> ReadAssets( Stream stream, int sessionId, ISet<Checksum> checksums, CancellationToken cancellationToken) { var results = new List<ValueTuple<Checksum, object>>(); using (var reader = new StreamObjectReader(stream)) { var responseSessionId = reader.ReadInt32(); Contract.ThrowIfFalse(sessionId == responseSessionId); var count = reader.ReadInt32(); Contract.ThrowIfFalse(count == checksums.Count); for (var i = 0; i < count; i++) { var responseChecksum = new Checksum(reader.ReadArray<byte>()); Contract.ThrowIfFalse(checksums.Contains(responseChecksum)); var kind = reader.ReadString(); // in service hub, cancellation means simply closed stream var @object = _owner.RoslynServices.AssetService.Deserialize<object>(kind, reader, cancellationToken); results.Add(ValueTuple.Create(responseChecksum, @object)); } return results; } }
public async Task TestSymbolTreeInfoSerialization() { var solution = GetSolution(WorkspaceKind.SingleClass); var compilation = await solution.Projects.First().GetCompilationAsync(); var assembly = compilation.GetSpecialType(SpecialType.System_Byte).ContainingAssembly; ////var assembly = compilation.Assembly; // create symbol tree info from assembly var version = VersionStamp.Create(); var info = SymbolTreeInfo.CreateSourceSymbolTreeInfo( solution, version, assembly, "", cancellationToken: CancellationToken.None); using (var writerStream = new MemoryStream()) { using (var writer = new StreamObjectWriter(writerStream)) { info.WriteTo(writer); } using (var readerStream = new MemoryStream(writerStream.ToArray())) using (var reader = new StreamObjectReader(readerStream)) { var readInfo = SymbolTreeInfo.ReadSymbolTreeInfo_ForTestingPurposesOnly(reader); info.AssertEquivalentTo(readInfo); } } }
protected override Data TryGetExistingData(Stream stream, Document value, CancellationToken cancellationToken) { var list = SharedPools.Default <List <TodoItem> >().AllocateAndClear(); try { using (var reader = new StreamObjectReader(stream)) { var format = reader.ReadString(); if (!string.Equals(format, FormatVersion)) { return(null); } var textVersion = VersionStamp.ReadFrom(reader); var dataVersion = VersionStamp.ReadFrom(reader); AppendItems(reader, value, list, cancellationToken); return(new Data(textVersion, dataVersion, list.ToImmutableArray <TodoItem>())); } } catch (Exception) { return(null); } finally { SharedPools.Default <List <TodoItem> >().ClearAndFree(list); } }
protected static async Task <T> LoadAsync <T>( Document document, string persistenceName, string formatVersion, Func <ObjectReader, VersionStamp, T> readFrom, CancellationToken cancellationToken) where T : AbstractPersistableState { var persistentStorageService = document.Project.Solution.Workspace.Services.GetService <IPersistentStorageService>(); var syntaxVersion = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false); // attempt to load from persisted state using (var storage = persistentStorageService.GetStorage(document.Project.Solution)) using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false)) { if (stream == null) { return(null); } using (var reader = new StreamObjectReader(stream)) { VersionStamp persistVersion; if (TryReadVersion(reader, formatVersion, out persistVersion) && document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistVersion)) { return(readFrom(reader, syntaxVersion)); } } } return(null); }
private static async Task <SyntaxTreeIndex> LoadAsync( Document document, string persistenceName, string formatVersion, Func <ObjectReader, VersionStamp, SyntaxTreeIndex> readFrom, CancellationToken cancellationToken) { var persistentStorageService = document.Project.Solution.Workspace.Services.GetService <IPersistentStorageService>(); var syntaxVersion = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false); try { // attempt to load from persisted state using (var storage = persistentStorageService.GetStorage(document.Project.Solution)) using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false)) using (var reader = StreamObjectReader.TryGetReader(stream)) { if (reader != null) { if (TryReadVersion(reader, formatVersion, out var persistVersion) && document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistVersion)) { return(readFrom(reader, syntaxVersion)); } } } } catch (Exception e) when(IOUtilities.IsNormalIOException(e)) { // Storage APIs can throw arbitrary exceptions. } return(null); }
private IList <ValueTuple <Checksum, object> > ReadAssets( Stream stream, int sessionId, ISet <Checksum> checksums, CancellationToken cancellationToken) { var results = new List <ValueTuple <Checksum, object> >(); using (var reader = new StreamObjectReader(stream)) { var responseSessionId = reader.ReadInt32(); Contract.ThrowIfFalse(sessionId == responseSessionId); var count = reader.ReadInt32(); Contract.ThrowIfFalse(count == checksums.Count); for (var i = 0; i < count; i++) { var responseChecksum = new Checksum(reader.ReadArray <byte>()); Contract.ThrowIfFalse(checksums.Contains(responseChecksum)); var kind = reader.ReadString(); // in service hub, cancellation means simply closed stream var @object = _owner.RoslynServices.AssetService.Deserialize <object>(kind, reader, cancellationToken); results.Add(ValueTuple.Create(responseChecksum, @object)); } return(results); } }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > GetCompilerAnalysisResultAsync(Stream stream, Dictionary <string, DiagnosticAnalyzer> analyzerMap, Project project, CancellationToken cancellationToken) { // handling of cancellation and exception var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); using (var reader = new StreamObjectReader(stream)) { return(DiagnosticResultSerializer.Deserialize(reader, analyzerMap, project, version, cancellationToken)); } }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > GetCompilerAnalysisResultAsync(Stream stream, Dictionary <string, DiagnosticAnalyzer> analyzerMap, Project project, CancellationToken cancellationToken) { // handling of cancellation and exception var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); using (var reader = StreamObjectReader.TryGetReader(stream)) { Debug.Assert(reader != null, @"We only ge a reader for data transmitted between live processes. This data should always be correct as we're never persisting the data between sessions."); return(DiagnosticResultSerializer.Deserialize(reader, analyzerMap, project, version, cancellationToken)); } }
private void TestInvalidStreamVersion() { var stream = new MemoryStream(); stream.WriteByte(0); stream.WriteByte(0); stream.Position = 0; var reader = StreamObjectReader.TryGetReader(stream); Assert.Null(reader); }
private T RoundTrip <T>(T value, Action <ObjectWriter, T> writeAction, Func <ObjectReader, T> readAction) { var stream = new MemoryStream(); var binder = new RecordingObjectBinder(); var writer = new StreamObjectWriter(stream, binder: binder); writeAction(writer, value); writer.Dispose(); stream.Position = 0; using (var reader = new StreamObjectReader(stream, binder: binder)) { return((T)readAction(reader)); } }
private void TestRoundTrip(Action <ObjectWriter> writeAction, Action <ObjectReader> readAction) { var stream = new MemoryStream(); var binder = new RecordingObjectBinder(); var writer = new StreamObjectWriter(stream, binder: binder); writeAction(writer); writer.Dispose(); stream.Position = 0; using (var reader = new StreamObjectReader(stream, binder: binder)) { readAction(reader); } }
private VersionStamp GetIdentifierSetVersion(EsentStorage.Key key, int identifierId, object unused1, object unused2, CancellationToken cancellationToken) { using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor()) using (var stream = accessor.GetReadStream(key, identifierId)) { if (stream == null) { return(VersionStamp.Default); } using (var reader = new StreamObjectReader(stream)) { return(VersionStamp.ReadFrom(reader)); } } }
public void VersionStamp_RoundTripText() { using (var writerStream = new MemoryStream()) using (var writer = new StreamObjectWriter(writerStream)) { var versionStamp = VersionStamp.Create(); versionStamp.WriteTo(writer); using (var readerStream = new MemoryStream(writerStream.ToArray())) using (var reader = new StreamObjectReader(readerStream)) { var deserializedVersionStamp = VersionStamp.ReadFrom(reader); Assert.Equal(versionStamp, deserializedVersionStamp); } } }
/// <summary> /// Deserialize a syntax node from the byte stream. /// </summary> public static SyntaxNode DeserializeFrom(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (!stream.CanRead) { throw new InvalidOperationException(CSharpResources.TheStreamCannotBeReadFrom); } using (var reader = new StreamObjectReader(stream, knownObjects: GetDeserializationObjectData(), binder: s_defaultBinder, cancellationToken: cancellationToken)) { var root = (Syntax.InternalSyntax.CSharpSyntaxNode)reader.ReadValue(); return(root.CreateRed()); } }
private static async Task <RemotableData> CloneAssetAsync(Serializer serializer, RemotableData asset) { using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new StreamObjectWriter(stream)) { await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = new StreamObjectReader(stream)) { var recovered = serializer.Deserialize <object>(asset.Kind, reader, CancellationToken.None); var assetFromStorage = SolutionAsset.Create(serializer.CreateChecksum(recovered, CancellationToken.None), recovered, serializer); Assert.Equal(asset.Checksum, assetFromStorage.Checksum); return(assetFromStorage); } } }
public void TestSerialization() { var stream = new MemoryStream(); var bloomFilter = new BloomFilter(0.001, false, new[] { "Hello, World" }); using (var writer = new StreamObjectWriter(stream)) { bloomFilter.WriteTo(writer); } stream.Position = 0; using (var reader = new StreamObjectReader(stream)) { var rehydratedFilter = BloomFilter.ReadFrom(reader); Assert.True(bloomFilter.IsEquivalent(rehydratedFilter)); } }
private T RoundTrip <T>(T value, Action <ObjectWriter, T> writeAction, Func <ObjectReader, T> readAction, bool recursive) { var stream = new MemoryStream(); var binder = new RecordingObjectBinder(); var writer = new StreamObjectWriter(stream, binder: binder, recursive: recursive); writeAction(writer, value); writer.Dispose(); stream.Position = 2; Assert.Equal(recursive, StreamObjectReader.IsRecursive(stream)); stream.Position = 0; using (var reader = StreamObjectReader.TryGetReader(stream, binder: binder)) { return((T)readAction(reader)); } }
private void RoundTrip(Action <ObjectWriter> writeAction, Action <ObjectReader> readAction, bool recursive) { var stream = new MemoryStream(); var binder = new RecordingObjectBinder(); var writer = new StreamObjectWriter(stream, binder: binder, recursive: recursive); writeAction(writer); writer.Dispose(); stream.Position = 0; Assert.Equal(recursive, StreamObjectReader.IsRecursive(stream)); stream.Position = 0; using (var reader = new StreamObjectReader(stream, binder: binder)) { readAction(reader); } }
private static bool TryReadFrom(Project project, string keyName, out Versions versions) { versions = default(Versions); var service = project.Solution.Workspace.Services.GetService <IPersistentStorageService>(); if (service == null) { return(false); } using (var storage = service.GetStorage(project.Solution)) using (var stream = storage.ReadStreamAsync(keyName, CancellationToken.None).WaitAndGetResult(CancellationToken.None)) { if (stream == null) { return(false); } try { using (var reader = new StreamObjectReader(stream)) { var formatVersion = reader.ReadInt32(); if (formatVersion != SerializationFormat) { return(false); } var persistedProjectVersion = VersionStamp.ReadFrom(reader); var persistedSemanticVersion = VersionStamp.ReadFrom(reader); versions = new Versions(persistedProjectVersion, persistedSemanticVersion); return(true); } } catch (Exception) { return(false); } } }
protected override Data TryGetExistingData(Stream stream, Document value, CancellationToken cancellationToken) { using (var reader = StreamObjectReader.TryGetReader(stream)) { if (reader != null) { var format = reader.ReadString(); if (string.Equals(format, FormatVersion, StringComparison.InvariantCulture)) { var textVersion = VersionStamp.ReadFrom(reader); var dataVersion = VersionStamp.ReadFrom(reader); var designerAttributeArgument = reader.ReadString(); return(new Data(textVersion, dataVersion, designerAttributeArgument)); } } } return(null); }
public async Task <StrongBox <ImmutableArray <DiagnosticData> > > DeserializeAsync(object documentOrProject, string key, CancellationToken cancellationToken) { // we have persisted data var solution = GetSolution(documentOrProject); var persistService = solution.Workspace.Services.GetService <IPersistentStorageService>(); using (var storage = persistService.GetStorage(solution)) using (var stream = await ReadStreamAsync(storage, key, documentOrProject, cancellationToken).ConfigureAwait(false)) using (var reader = StreamObjectReader.TryGetReader(stream)) { if (reader == null) { return(null); } // we return StrongBox rather than ImmutableArray due to task lib's issue with allocations // when returning default(value type) return(ReadFrom(reader, documentOrProject, cancellationToken)); } }
public static async Task <T> GetValueAsync <T>(this ISolutionSynchronizationService service, Checksum checksum) { var syncService = (SolutionSynchronizationServiceFactory.Service)service; var syncObject = service.GetRemotableData(checksum, CancellationToken.None); using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new StreamObjectWriter(stream)) { // serialize asset to bits await syncObject.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = new StreamObjectReader(stream)) { // deserialize bits to object var serializer = syncService.Serializer_TestOnly; return(serializer.Deserialize <T>(syncObject.Kind, reader, CancellationToken.None)); } } }
public void TestObjectMapLimits() { using (var stream = new MemoryStream()) { var instances = new List <TypeWithTwoMembers <int, string> >(); // We need enough items to exercise all sizes of ObjectRef for (int i = 0; i < ushort.MaxValue + 1; i++) { instances.Add(new TypeWithTwoMembers <int, string>(i, i.ToString())); } var binder = new RecordingObjectBinder(); var writer = new StreamObjectWriter(stream, binder: binder); // Write each instance twice. The second time around, they'll become ObjectRefs for (int pass = 0; pass < 2; pass++) { foreach (var instance in instances) { writer.WriteValue(instance); } } writer.Dispose(); stream.Position = 0; using (var reader = new StreamObjectReader(stream, binder: binder)) { for (int pass = 0; pass < 2; pass++) { foreach (var instance in instances) { var obj = reader.ReadValue(); Assert.NotNull(obj); Assert.True(Equalish(obj, instance)); } } } } }
public async Task<StrongBox<ImmutableArray<DiagnosticData>>> DeserializeAsync(object documentOrProject, string key, CancellationToken cancellationToken) { // we have persisted data var solution = GetSolution(documentOrProject); var persistService = solution.Workspace.Services.GetService<IPersistentStorageService>(); using (var storage = persistService.GetStorage(solution)) using (var stream = await ReadStreamAsync(storage, key, documentOrProject, cancellationToken).ConfigureAwait(false)) { if (stream == null) { return null; } using (var reader = new StreamObjectReader(stream)) { // we return StrongBox rather than ImmutableArray due to task lib's issue with allocations // when returning default(value type) return ReadFrom(reader, documentOrProject, cancellationToken); } } }
private TimeSpan TestReaderPerf(int iterations, bool recursive) { int id = 0; var graph = ConstructGraph(ref id, 5, 3); var stream = new MemoryStream(); var binder = new RecordingObjectBinder(); var writer = new StreamObjectWriter(stream, binder: binder, recursive: recursive); writer.WriteValue(graph); writer.Dispose(); var start = DateTime.Now; for (int i = 0; i < iterations; i++) { stream.Position = 0; var reader = new StreamObjectReader(stream, binder: binder); var item = reader.ReadValue(); } return(DateTime.Now - start); }
protected override Data TryGetExistingData(Stream stream, Document value, CancellationToken cancellationToken) { using (var reader = StreamObjectReader.TryGetReader(stream)) { if (reader != null) { var format = reader.ReadString(); if (string.Equals(format, FormatVersion)) { var textVersion = VersionStamp.ReadFrom(reader); var dataVersion = VersionStamp.ReadFrom(reader); var list = ArrayBuilder <TodoItem> .GetInstance(); AppendItems(reader, value, list, cancellationToken); return(new Data(textVersion, dataVersion, list.ToImmutableAndFree())); } } } return(null); }
private bool ReadIdentifierPositions(EsentStorage.Key key, int identifierId, List <int> positions, object unused, CancellationToken cancellationToken) { using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor()) using (var stream = accessor.GetReadStream(key, identifierId)) { if (stream == null) { // no such identifier exist. return(true); } using (var reader = new StreamObjectReader(stream)) { var formatVersion = reader.ReadString(); if (formatVersion != IdentifierSetSerializationVersion) { return(false); } return(ReadFrom(reader, positions, cancellationToken)); } } }
protected static async Task <bool> PrecalculatedAsync(Document document, string persistenceName, string formatVersion, CancellationToken cancellationToken) { Contract.Requires(document.IsFromPrimaryBranch()); var persistentStorageService = document.Project.Solution.Workspace.Services.GetService <IPersistentStorageService>(); var syntaxVersion = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false); // check whether we already have info for this document using (var storage = persistentStorageService.GetStorage(document.Project.Solution)) using (var stream = await storage.ReadStreamAsync(document, persistenceName, cancellationToken).ConfigureAwait(false)) { if (stream != null) { using (var reader = new StreamObjectReader(stream)) { return(TryReadVersion(reader, formatVersion, out var persistVersion) && document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistVersion)); } } } return(false); }
private async Task<DiagnosticAnalysisResultMap<DiagnosticAnalyzer, DiagnosticAnalysisResult>> GetCompilerAnalysisResultAsync(Stream stream, Dictionary<string, DiagnosticAnalyzer> analyzerMap, Project project, CancellationToken cancellationToken) { // handling of cancellation and exception var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); using (var reader = new StreamObjectReader(stream)) { return DiagnosticResultSerializer.Deserialize(reader, analyzerMap, project, version, cancellationToken); } }
private static bool TryReadFrom(Project project, string keyName, out Versions versions) { versions = default(Versions); var service = project.Solution.Workspace.Services.GetService<IPersistentStorageService>(); if (service == null) { return false; } using (var storage = service.GetStorage(project.Solution)) using (var stream = storage.ReadStreamAsync(keyName, CancellationToken.None).WaitAndGetResult(CancellationToken.None)) { if (stream == null) { return false; } try { using (var reader = new StreamObjectReader(stream)) { var formatVersion = reader.ReadInt32(); if (formatVersion != SerializationFormat) { return false; } var persistedProjectVersion = VersionStamp.ReadFrom(reader); var persistedSemanticVersion = VersionStamp.ReadFrom(reader); versions = new Versions(persistedProjectVersion, persistedSemanticVersion); return true; } } catch (Exception) { return false; } } }
private static async Task VerifyOptionSetsAsync(Workspace workspace, string language) { var assetBuilder = new CustomAssetBuilder(workspace.CurrentSolution); var serializer = new Serializer(workspace.Services); var asset = assetBuilder.Build(workspace.Options, language, CancellationToken.None); using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new StreamObjectWriter(stream)) { await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = new StreamObjectReader(stream)) { var recovered = serializer.Deserialize<OptionSet>(asset.Kind, reader, CancellationToken.None); var assetFromStorage = assetBuilder.Build(recovered, language, CancellationToken.None); Assert.Equal(asset.Checksum, assetFromStorage.Checksum); // option should be exactly same Assert.Equal(0, recovered.GetChangedOptions(workspace.Options).Count()); } } }
private static async Task<RemotableData> CloneAssetAsync(Serializer serializer, RemotableData asset) { using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new StreamObjectWriter(stream)) { await asset.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false); stream.Position = 0; using (var reader = new StreamObjectReader(stream)) { var recovered = serializer.Deserialize<object>(asset.Kind, reader, CancellationToken.None); var assetFromStorage = SolutionAsset.Create(serializer.CreateChecksum(recovered, CancellationToken.None), recovered, serializer); Assert.Equal(asset.Checksum, assetFromStorage.Checksum); return assetFromStorage; } } }
private VersionStamp GetIdentifierSetVersion(EsentStorage.Key key, int identifierId, object unused1, object unused2, CancellationToken cancellationToken) { using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor()) using (var stream = accessor.GetReadStream(key, identifierId)) { if (stream == null) { return VersionStamp.Default; } using (var reader = new StreamObjectReader(stream)) { return VersionStamp.ReadFrom(reader); } } }
/// <summary> /// Generalized function for loading/creating/persisting data. Used as the common core /// code for serialization of SymbolTreeInfos and SpellCheckers. /// </summary> private static async Task <T> LoadOrCreateAsync <T>( Solution solution, string filePath, bool loadOnly, Func <VersionStamp, T> create, string keySuffix, Func <T, VersionStamp> getVersion, Func <ObjectReader, T> readObject, Action <ObjectWriter, T> writeObject, CancellationToken cancellationToken) where T : class { // See if we can even use serialization. If not, we'll just have to make the value // from scratch. if (ShouldCreateFromScratch(solution, filePath, out var prefix, out var version, cancellationToken)) { return(loadOnly ? null : create(VersionStamp.Default)); } // Ok, we can use persistence. First try to load from the persistence service. var persistentStorageService = solution.Workspace.Services.GetService <IPersistentStorageService>(); T result; using (var storage = persistentStorageService.GetStorage(solution)) { // Get the unique key to identify our data. var key = PrefixMetadataSymbolTreeInfo + prefix + keySuffix; using (var stream = await storage.ReadStreamAsync(key, cancellationToken).ConfigureAwait(false)) { if (stream != null) { using (var reader = new StreamObjectReader(stream)) { // We have some previously persisted data. Attempt to read it back. // If we're able to, and the version of the persisted data matches // our version, then we can reuse this instance. result = readObject(reader); if (result != null && VersionStamp.CanReusePersistedVersion(version, getVersion(result))) { return(result); } } } } cancellationToken.ThrowIfCancellationRequested(); // Couldn't read from the persistence service. If we've been asked to only load // data and not create new instances in their absense, then there's nothing left // to do at this point. if (loadOnly) { return(null); } // Now, try to create a new instance and write it to the persistence service. result = create(version); if (result != null) { using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new StreamObjectWriter(stream, cancellationToken: cancellationToken)) { writeObject(writer, result); stream.Position = 0; await storage.WriteStreamAsync(key, stream, cancellationToken).ConfigureAwait(false); } } } return(result); }
private bool ReadIdentifierPositions(EsentStorage.Key key, int identifierId, List<int> positions, object unused, CancellationToken cancellationToken) { using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor()) using (var stream = accessor.GetReadStream(key, identifierId)) { if (stream == null) { // no such identifier exist. return true; } using (var reader = new StreamObjectReader(stream)) { var formatVersion = reader.ReadString(); if (formatVersion != IdentifierSetSerializationVersion) { return false; } return ReadFrom(reader, positions, cancellationToken); } } }