private static async Task<SyntaxTreeIndex> GetIndexAsync( Document document, ConditionalWeakTable<Document, SyntaxTreeIndex> cache, Func<Document, CancellationToken, Task<SyntaxTreeIndex>> generator, CancellationToken cancellationToken) { if (cache.TryGetValue(document, out var info)) { return info; } info = await generator(document, cancellationToken).ConfigureAwait(false); if (info != null) { return cache.GetValue(document, _ => info); } // alright, we don't have cached information, re-calculate them here. var data = await CreateInfoAsync(document, cancellationToken).ConfigureAwait(false); // okay, persist this info await data.SaveAsync(document, cancellationToken).ConfigureAwait(false); return cache.GetValue(document, _ => data); }
public void GetValue() { var cwt = new ConditionalWeakTable<object, object>(); try { cwt.GetValue(null, k => null); Assert.Fail("#0"); } catch (ArgumentNullException) { } try { cwt.GetValue(20, null); Assert.Fail("#1"); } catch (ArgumentNullException) { } object key = "foo"; object val = cwt.GetValue(key, k => new Link(k)); Assert.IsTrue(val != null, "#2"); Assert.AreEqual(typeof(Link), val.GetType(), "#3"); Assert.AreEqual(val, cwt.GetValue(key, k => new object()), "#4"); }
public static void AddMany_ThenRemoveAll(int numObjects) { object[] keys = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); object[] values = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); var cwt = new ConditionalWeakTable<object, object>(); for (int i = 0; i < numObjects; i++) { cwt.Add(keys[i], values[i]); } for (int i = 0; i < numObjects; i++) { Assert.Same(values[i], cwt.GetValue(keys[i], _ => new object())); } for (int i = 0; i < numObjects; i++) { Assert.True(cwt.Remove(keys[i])); Assert.False(cwt.Remove(keys[i])); } for (int i = 0; i < numObjects; i++) { object ignored; Assert.False(cwt.TryGetValue(keys[i], out ignored)); } }
protected static async Task<AbstractSyntaxTreeInfo> LoadAsync( Document document, Func<ObjectReader, VersionStamp, AbstractSyntaxTreeInfo> reader, ConditionalWeakTable<BranchId, ConditionalWeakTable<DocumentId, AbstractSyntaxTreeInfo>> cache, string persistenceName, string serializationFormat, CancellationToken cancellationToken) { var infoTable = cache.GetValue(document.Project.Solution.BranchId, _ => new ConditionalWeakTable<DocumentId, AbstractSyntaxTreeInfo>()); var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false); // first look to see if we already have the info in the cache AbstractSyntaxTreeInfo info; if (infoTable.TryGetValue(document.Id, out info) && info.Version == version) { return info; } // cache is invalid. remove it infoTable.Remove(document.Id); // check primary cache to see whether we have valid info there var primaryInfoTable = cache.GetValue(document.Project.Solution.Workspace.PrimaryBranchId, _ => new ConditionalWeakTable<DocumentId, AbstractSyntaxTreeInfo>()); if (primaryInfoTable.TryGetValue(document.Id, out info) && info.Version == version) { return info; } // check whether we can get it from persistence service info = await LoadAsync(document, persistenceName, serializationFormat, reader, cancellationToken).ConfigureAwait(false); if (info != null) { // save it in the cache. persisted info is always from primary branch. no reason to save it to the branched document cache. primaryInfoTable.Remove(document.Id); primaryInfoTable.GetValue(document.Id, _ => info); return info; } // well, we don't have this information. return null; }
public static void InvalidArgs_Throws() { var cwt = new ConditionalWeakTable<object, object>(); object ignored; Assert.Throws<ArgumentNullException>("key", () => cwt.Add(null, new object())); // null key Assert.Throws<ArgumentNullException>("key", () => cwt.TryGetValue(null, out ignored)); // null key Assert.Throws<ArgumentNullException>("key", () => cwt.Remove(null)); // null key Assert.Throws<ArgumentNullException>("createValueCallback", () => cwt.GetValue(new object(), null)); // null delegate object key = new object(); cwt.Add(key, key); Assert.Throws<ArgumentException>(null, () => cwt.Add(key, key)); // duplicate key }
public static void GetValueTest() { ConditionalWeakTable<object, object> cwt = new ConditionalWeakTable<object, object>(); object key = new object(); object obj = null; object value = cwt.GetValue(key, k => new object()); Assert.True(cwt.TryGetValue(key, out value)); Assert.Equal(value, cwt.GetOrCreateValue(key)); WeakReference<object> wrValue = new WeakReference<object>(value, false); WeakReference<object> wrkey = new WeakReference<object>(key, false); key = null; value = null; GC.Collect(); // key and value must be collected Assert.False(wrValue.TryGetTarget(out obj)); Assert.False(wrkey.TryGetTarget(out obj)); }
public static void Add(int numObjects) { // Isolated to ensure we drop all references even in debug builds where lifetime is extended by the JIT to the end of the method Func<int, Tuple<ConditionalWeakTable<object, object>, WeakReference[], WeakReference[]>> body = count => { object[] keys = Enumerable.Range(0, count).Select(_ => new object()).ToArray(); object[] values = Enumerable.Range(0, count).Select(_ => new object()).ToArray(); var cwt = new ConditionalWeakTable<object, object>(); for (int i = 0; i < count; i++) { cwt.Add(keys[i], values[i]); } for (int i = 0; i < count; i++) { object value; Assert.True(cwt.TryGetValue(keys[i], out value)); Assert.Same(values[i], value); Assert.Same(value, cwt.GetOrCreateValue(keys[i])); Assert.Same(value, cwt.GetValue(keys[i], _ => new object())); } return Tuple.Create(cwt, keys.Select(k => new WeakReference(k)).ToArray(), values.Select(v => new WeakReference(v)).ToArray()); }; Tuple<ConditionalWeakTable<object, object>, WeakReference[], WeakReference[]> result = body(numObjects); GC.Collect(); Assert.NotNull(result.Item1); for (int i = 0; i < numObjects; i++) { Assert.False(result.Item2[i].IsAlive, $"Expected not to find key #{i}"); Assert.False(result.Item3[i].IsAlive, $"Expected not to find value #{i}"); } }
private static List<SymbolKey> GetOrAddDependentTypes(ConditionalWeakTable<Compilation, ConcurrentDictionary<SymbolKey, List<SymbolKey>>> cache, Compilation compilation, SymbolKey typeId, List<SymbolKey> dependentTypeIds) { List<SymbolKey> result; if (TryGetDependentTypes(cache, compilation, typeId, out result)) { return result; } else { return cache.GetValue(compilation, s_createSymbolDictionary) .GetOrAdd(typeId, dependentTypeIds); } }
private bool TryLoadInitialVersions(ConditionalWeakTable<ProjectId, Versions> initialVersionMap, Project project, string keyName, out Versions versions) { var result = TryReadFrom(project, keyName, out versions); if (result) { Versions save = versions; initialVersionMap.GetValue(project.Id, _ => save); return true; } initialVersionMap.GetValue(project.Id, _ => Versions.Default); return false; }
private static MouseTracker GetMouseTracker(BasePresenter presenter) { return(s_mouseTrackers.GetValue(presenter, CreateMouseTracker)); }
private ImmutableDictionary <DiagnosticId, List <CodeFixProvider> > GetProjectFixers(Project project) { return(_projectFixersMap.GetValue(project.AnalyzerReferences, pId => ComputeProjectFixers(project))); }
/// <inheritdoc/> protected override string AssignTempTableName(Model model) { return(_tempTableNamesByModel.GetValue(model, GetUniqueTempTableName)); }
public static TValue GetOrAdd <TKey, TValue>(this ConditionalWeakTable <TKey, TValue> table, TKey key, Func <TKey, TValue> valueFactory) where TKey : class where TValue : class { return(table.GetValue(key, k => valueFactory(k))); }
public static Serializer GetOrCreateSerializer(HostWorkspaceServices services) { return(s_serializerCache.GetValue(services, s_serializerCallback)); }
private static ToAbiHelper FindAdapter(IntPtr thisPtr) { var __this = global::WinRT.ComWrappersSupport.FindObject <global::System.Collections.Generic.IReadOnlyList <T> >(thisPtr); return(_adapterTable.GetValue(__this, (list) => new ToAbiHelper(list))); }
private static ConditionalWeakTable<DocumentId, SyntaxTreeIndex> GetInfoTable( BranchId branchId, Workspace workspace, ConditionalWeakTable<BranchId, ConditionalWeakTable<DocumentId, SyntaxTreeIndex>> cache) { return cache.GetValue(branchId, id => { if (id == workspace.PrimaryBranchId) { workspace.DocumentClosed += (sender, e) => { if (!e.Document.IsFromPrimaryBranch()) { return; } if (cache.TryGetValue(e.Document.Project.Solution.BranchId, out var infoTable)) { // remove closed document from primary branch from live cache. infoTable.Remove(e.Document.Id); } }; } return new ConditionalWeakTable<DocumentId, SyntaxTreeIndex>(); }); }
public static void Concurrent_GetValue_Read_Remove_SameObject() { object key = new object(); object value = new object(); var cwt = new ConditionalWeakTable<object, object>(); DateTime end = DateTime.UtcNow + TimeSpan.FromSeconds(0.25); Parallel.For(0, Environment.ProcessorCount, i => { while (DateTime.UtcNow < end) { Assert.Same(value, cwt.GetValue(key, _ => value)); cwt.Remove(key); } }); }
/// <summary> /// returns the core's SoundProvider, or a suitable dummy provider /// </summary> public static ISoundProvider AsSoundProviderOrDefault(this IEmulator core) { return(core.ServiceProvider.GetService <ISoundProvider>() ?? CachedNullSoundProviders.GetValue(core, e => new NullSound(core.VsyncNumerator(), core.VsyncDenominator()))); }
/// <summary> /// Sets the URL of a given object. /// </summary> /// <param name="obj">The object.</param> /// <param name="url">The URL.</param> public static void SetUrl(object obj, string url) { var attachedReference = AttachedReferences.GetValue(obj, x => new AttachedReference()); attachedReference.Url = url; }
public static void Clear_AllValuesRemoved(int numObjects) { var cwt = new ConditionalWeakTable<object, object>(); MethodInfo clear = cwt.GetType().GetMethod("Clear", BindingFlags.NonPublic | BindingFlags.Instance); if (clear == null) { // Couldn't access the Clear method; skip the test. return; } object[] keys = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); object[] values = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); for (int iter = 0; iter < 2; iter++) { // Add the objects for (int i = 0; i < numObjects; i++) { cwt.Add(keys[i], values[i]); Assert.Same(values[i], cwt.GetValue(keys[i], _ => new object())); } // Clear the table clear.Invoke(cwt, null); // Verify the objects are removed for (int i = 0; i < numObjects; i++) { object ignored; Assert.False(cwt.TryGetValue(keys[i], out ignored)); } // Do it a couple of times, to make sure the table is still usable after a clear. } }