From a505bc570c837d350f2fe3e9d7e3654e6e1afbe6 Mon Sep 17 00:00:00 2001 From: JakenVeina Date: Tue, 13 Feb 2024 18:42:55 -0600 Subject: [PATCH 1/2] Fixed ambiguous overloads for `ObservableCacheEx.ExpireAfter()`. Also moved `EnsureUniqueKeys()` into proper order. --- .../Cache/ExpireAfter_Cache_ForSource.cs | 4 +- ...ts.DynamicDataTests.DotNet8_0.verified.txt | 8 +- .../Cache/ExpireAfterFixture.ForSource.cs | 4 +- src/DynamicData/Cache/ObservableCacheEx.cs | 86 ++++--------------- 4 files changed, 23 insertions(+), 79 deletions(-) diff --git a/src/DynamicData.Benchmarks/Cache/ExpireAfter_Cache_ForSource.cs b/src/DynamicData.Benchmarks/Cache/ExpireAfter_Cache_ForSource.cs index 7b424058f..3c437f89f 100644 --- a/src/DynamicData.Benchmarks/Cache/ExpireAfter_Cache_ForSource.cs +++ b/src/DynamicData.Benchmarks/Cache/ExpireAfter_Cache_ForSource.cs @@ -67,8 +67,8 @@ public void RandomizedEditsAndExpirations() using var subscription = source .ExpireAfter( - timeSelector: static item => item.Lifetime, - interval: null) + timeSelector: static item => item.Lifetime, + pollingInterval: null) .Subscribe(); PerformRandomizedEdits(source); diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt index 305ec585b..421b73223 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt @@ -1301,19 +1301,13 @@ namespace DynamicData public static System.IObservable> ExpireAfter(this System.IObservable> source, System.Func timeSelector) where TObject : notnull where TKey : notnull { } - public static System.IObservable>> ExpireAfter(this DynamicData.ISourceCache source, System.Func timeSelector, System.Reactive.Concurrency.IScheduler? scheduler = null) - where TObject : notnull - where TKey : notnull { } - public static System.IObservable>> ExpireAfter(this DynamicData.ISourceCache source, System.Func timeSelector, System.TimeSpan? interval = default) - where TObject : notnull - where TKey : notnull { } public static System.IObservable> ExpireAfter(this System.IObservable> source, System.Func timeSelector, System.Reactive.Concurrency.IScheduler scheduler) where TObject : notnull where TKey : notnull { } public static System.IObservable> ExpireAfter(this System.IObservable> source, System.Func timeSelector, System.TimeSpan? pollingInterval) where TObject : notnull where TKey : notnull { } - public static System.IObservable>> ExpireAfter(this DynamicData.ISourceCache source, System.Func timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler? scheduler) + public static System.IObservable>> ExpireAfter(this DynamicData.ISourceCache source, System.Func timeSelector, System.TimeSpan? pollingInterval = default, System.Reactive.Concurrency.IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { } public static System.IObservable> ExpireAfter(this System.IObservable> source, System.Func timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler scheduler) diff --git a/src/DynamicData.Tests/Cache/ExpireAfterFixture.ForSource.cs b/src/DynamicData.Tests/Cache/ExpireAfterFixture.ForSource.cs index d4f5148ef..59cb1c204 100644 --- a/src/DynamicData.Tests/Cache/ExpireAfterFixture.ForSource.cs +++ b/src/DynamicData.Tests/Cache/ExpireAfterFixture.ForSource.cs @@ -550,7 +550,7 @@ public void SourceIsNull_ThrowsException() => FluentActions.Invoking(() => ObservableCacheEx.ExpireAfter( source: (null as ISourceCache)!, timeSelector: static _ => default, - interval: null)) + pollingInterval: null)) .Should().Throw(); [Fact] @@ -620,7 +620,7 @@ public async Task ThreadPoolSchedulerIsUsedWithPolling_ExpirationIsThreadSafe() public void TimeSelectorIsNull_ThrowsException() => FluentActions.Invoking(() => CreateTestSource().ExpireAfter( timeSelector: null!, - interval: null)) + pollingInterval: null)) .Should().Throw(); [Fact] diff --git a/src/DynamicData/Cache/ObservableCacheEx.cs b/src/DynamicData/Cache/ObservableCacheEx.cs index fc950e3f5..284ecd275 100644 --- a/src/DynamicData/Cache/ObservableCacheEx.cs +++ b/src/DynamicData/Cache/ObservableCacheEx.cs @@ -1189,6 +1189,22 @@ public static IObservable> EditDiff(thi return new EditDiffChangeSetOptional(source, keySelector, equalityComparer).Run(); } + /// + /// Ensures there are no duplicated keys in the observable changeset. + /// + /// The source change set. + /// The type of the object. + /// The type of the key. + /// A changeset which guarantees a key is only present at most once in the changeset. + public static IObservable> EnsureUniqueKeys(this IObservable> source) + where TObject : notnull + where TKey : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + + return new UniquenessEnforcer(source).Run(); + } + /// /// Signal observers to re-evaluate the specified item. /// @@ -1447,72 +1463,6 @@ public static IObservable> ExpireAfter( pollingInterval: pollingInterval, scheduler: scheduler); - /// - /// Automatically removes items from the cache after the time specified by - /// the time selector elapses. - /// - /// The type of the object. - /// The type of the key. - /// The cache. - /// The time selector. Return null if the item should never be removed. - /// The scheduler to perform the work on. - /// An observable of enumerable of the key values which has been removed. - /// source - /// or - /// timeSelector. - public static IObservable>> ExpireAfter( - this ISourceCache source, - Func timeSelector, - IScheduler? scheduler = null) - where TObject : notnull - where TKey : notnull - => Cache.Internal.ExpireAfter.ForSource.Create( - source: source, - timeSelector: timeSelector, - scheduler: scheduler); - - /// - /// Automatically removes items from the cache after the time specified by - /// the time selector elapses. - /// - /// The type of the object. - /// The type of the key. - /// The cache. - /// The time selector. Return null if the item should never be removed. - /// A polling interval. Since multiple timer subscriptions can be expensive, - /// it may be worth setting the interval . - /// - /// An observable of enumerable of the key values which has been removed. - /// source - /// or - /// timeSelector. - public static IObservable>> ExpireAfter( - this ISourceCache source, - Func timeSelector, - TimeSpan? interval = null) - where TObject : notnull - where TKey : notnull - => Cache.Internal.ExpireAfter.ForSource.Create( - source: source, - timeSelector: timeSelector, - pollingInterval: interval); - - /// - /// Ensures there are no duplicated keys in the observable changeset. - /// - /// The source change set. - /// The type of the object. - /// The type of the key. - /// A changeset which guarantees a key is only present at most once in the changeset. - public static IObservable> EnsureUniqueKeys(this IObservable> source) - where TObject : notnull - where TKey : notnull - { - source.ThrowArgumentNullExceptionIfNull(nameof(source)); - - return new UniquenessEnforcer(source).Run(); - } - /// /// Automatically removes items from the cache after the time specified by /// the time selector elapses. @@ -1532,8 +1482,8 @@ public static IObservable> EnsureUniqueKeys>> ExpireAfter( this ISourceCache source, Func timeSelector, - TimeSpan? pollingInterval, - IScheduler? scheduler) + TimeSpan? pollingInterval = null, + IScheduler? scheduler = null) where TObject : notnull where TKey : notnull => Cache.Internal.ExpireAfter.ForSource.Create( From f07f8cbea801a3c92040dd48b3f8a9dc5ca5627b Mon Sep 17 00:00:00 2001 From: JakenVeina Date: Tue, 13 Feb 2024 18:50:37 -0600 Subject: [PATCH 2/2] Fixed ambiguous overload for `ObservableListEx.ExpireAfter()`. --- ...ts.DynamicDataTests.DotNet8_0.verified.txt | 2 -- src/DynamicData/List/ObservableListEx.cs | 19 ------------------- 2 files changed, 21 deletions(-) diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt index 421b73223..ad23bf5b0 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt @@ -2310,8 +2310,6 @@ namespace DynamicData where T : notnull { } public static System.IObservable> Except(this System.IObservable> source, params System.IObservable>[] others) where T : notnull { } - public static System.IObservable> ExpireAfter(this DynamicData.ISourceList source, System.Func timeSelector, System.Reactive.Concurrency.IScheduler? scheduler = null) - where T : notnull { } public static System.IObservable> ExpireAfter(this DynamicData.ISourceList source, System.Func timeSelector, System.TimeSpan? pollingInterval = default, System.Reactive.Concurrency.IScheduler? scheduler = null) where T : notnull { } public static System.IObservable> Filter(this System.IObservable> source, System.Func predicate) diff --git a/src/DynamicData/List/ObservableListEx.cs b/src/DynamicData/List/ObservableListEx.cs index c196b37aa..5a2c409f1 100644 --- a/src/DynamicData/List/ObservableListEx.cs +++ b/src/DynamicData/List/ObservableListEx.cs @@ -652,25 +652,6 @@ public static IObservable> Except(this IObservableList> Except(this IObservableList> sources) where T : notnull => sources.Combine(CombineOperator.Except); - /// - /// Removes items from the cache according to the value specified by the time selector function. - /// - /// The type of the item. - /// The source. - /// Selector returning when to expire the item. Return null for non-expiring item. - /// The scheduler. - /// An observable which emits the enumerable of items. - public static IObservable> ExpireAfter( - this ISourceList source, - Func timeSelector, - IScheduler? scheduler = null) - where T : notnull - => List.Internal.ExpireAfter.Create( - source: source, - timeSelector: timeSelector, - pollingInterval: null, - scheduler: scheduler); - /// /// Removes items from the cache according to the value specified by the time selector function. ///