Skip to content

Commit

Permalink
Fixed ambiguous overloads for ObservableCacheEx.ExpireAfter().
Browse files Browse the repository at this point in the history
Also moved `EnsureUniqueKeys()` into proper order.
  • Loading branch information
JakenVeina committed Jan 5, 2024
1 parent a7f29d1 commit 664f7f3
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1277,19 +1277,13 @@ namespace DynamicData
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.Reactive.Concurrency.IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? interval = default)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.Reactive.Concurrency.IScheduler scheduler)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler? scheduler)
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval = default, System.Reactive.Concurrency.IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler scheduler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1277,19 +1277,13 @@ namespace DynamicData
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.Reactive.Concurrency.IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? interval = default)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.Reactive.Concurrency.IScheduler scheduler)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler? scheduler)
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval = default, System.Reactive.Concurrency.IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler scheduler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1277,19 +1277,13 @@ namespace DynamicData
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.Reactive.Concurrency.IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? interval = default)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.Reactive.Concurrency.IScheduler scheduler)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler? scheduler)
public static System.IObservable<System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this DynamicData.ISourceCache<TObject, TKey> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval = default, System.Reactive.Concurrency.IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull { }
public static System.IObservable<DynamicData.IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(this System.IObservable<DynamicData.IChangeSet<TObject, TKey>> source, System.Func<TObject, System.TimeSpan?> timeSelector, System.TimeSpan? pollingInterval, System.Reactive.Concurrency.IScheduler scheduler)
Expand Down
8 changes: 4 additions & 4 deletions src/DynamicData.Tests/Cache/ExpireAfterFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ExpireAfterFixture()
[Fact]
public void CanHandleABatchOfUpdates()
{
var remover = _source.ExpireAfter(p => TimeSpan.FromMilliseconds(100), _scheduler).Subscribe();
var remover = _source.ExpireAfter(p => TimeSpan.FromMilliseconds(100), scheduler: _scheduler).Subscribe();
const int size = 100;
var items = Enumerable.Range(1, size).Select(i => new Person($"Name.{i}", i)).ToArray();

Expand Down Expand Up @@ -65,7 +65,7 @@ public void ComplexRemove()
var items = Enumerable.Range(1, size).Select(i => new Person($"Name.{i}", i)).ToArray();
_source.AddOrUpdate(items);

var remover = _source.ExpireAfter(RemoveFunc, _scheduler).Subscribe();
var remover = _source.ExpireAfter(RemoveFunc, scheduler: _scheduler).Subscribe();
_scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5010).Ticks);

_source.Count.Should().Be(60, "40 items should have been removed from the cache");
Expand All @@ -85,7 +85,7 @@ public void Dispose()
[Fact]
public void ExpireIsCancelledWhenUpdated()
{
var remover = _source.ExpireAfter(p => TimeSpan.FromMilliseconds(100), _scheduler).Subscribe();
var remover = _source.ExpireAfter(p => TimeSpan.FromMilliseconds(100), scheduler: _scheduler).Subscribe();

_source.Edit(
updater =>
Expand All @@ -106,7 +106,7 @@ public void ExpireIsCancelledWhenUpdated()
[Fact]
public void ItemAddedIsExpired()
{
var remover = _source.ExpireAfter(p => TimeSpan.FromMilliseconds(100), _scheduler).Subscribe();
var remover = _source.ExpireAfter(p => TimeSpan.FromMilliseconds(100), scheduler: _scheduler).Subscribe();

_source.AddOrUpdate(new Person("Name1", 10));

Expand Down
4 changes: 2 additions & 2 deletions src/DynamicData.Tests/Cache/TimeExpiryFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public TimeExpiryFixture()

_cache = new SourceCache<Person, string>(p => p.Key);
_results = new ChangeSetAggregator<Person, string>(_cache.Connect());
_remover = _cache.ExpireAfter(p => TimeSpan.FromMilliseconds(100), _scheduler).Subscribe();
_remover = _cache.ExpireAfter(p => TimeSpan.FromMilliseconds(100), scheduler: _scheduler).Subscribe();
}

[Fact]
Expand All @@ -52,7 +52,7 @@ public void AutoRemove()
var items = Enumerable.Range(1, size).Select(i => new Person($"Name{i}", i)).ToArray();
_cache.AddOrUpdate(items);

var xxx = _cache.ExpireAfter(RemoveFunc, _scheduler).Subscribe();
var xxx = _cache.ExpireAfter(RemoveFunc, scheduler: _scheduler).Subscribe();
_scheduler.AdvanceBy(TimeSpan.FromSeconds(5).Ticks);

_scheduler.AdvanceBy(TimeSpan.FromSeconds(5).Ticks);
Expand Down
74 changes: 21 additions & 53 deletions src/DynamicData/Cache/ObservableCacheEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,22 @@ public static IObservable<IChangeSet<TObject, TKey>> EditDiff<TObject, TKey>(thi
return new EditDiffChangeSetOptional<TObject, TKey>(source, keySelector, equalityComparer).Run();
}

/// <summary>
/// Ensures there are no duplicated keys in the observable changeset.
/// </summary>
/// <param name="source"> The source change set.</param>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <returns>A changeset which guarantees a key is only present at most once in the changeset.</returns>
public static IObservable<IChangeSet<TObject, TKey>> EnsureUniqueKeys<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source)
where TObject : notnull
where TKey : notnull
{
source.ThrowArgumentNullExceptionIfNull(nameof(source));

return new UniquenessEnforcer<TObject, TKey>(source).Run();
}

/// <summary>
/// Signal observers to re-evaluate the specified item.
/// </summary>
Expand Down Expand Up @@ -1429,58 +1445,6 @@ public static IObservable<IChangeSet<TObject, TKey>> ExpireAfter<TObject, TKey>(
return new TimeExpirer<TObject, TKey>(source, timeSelector, pollingInterval, scheduler).ExpireAfter();
}

/// <summary>
/// Automatically removes items from the cache after the time specified by
/// the time selector elapses.
/// </summary>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <param name="source">The cache.</param>
/// <param name="timeSelector">The time selector. Return null if the item should never be removed.</param>
/// <param name="scheduler">The scheduler to perform the work on.</param>
/// <returns>An observable of enumerable of the key values which has been removed.</returns>
/// <exception cref="ArgumentNullException">source
/// or
/// timeSelector.</exception>
public static IObservable<IEnumerable<KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this ISourceCache<TObject, TKey> source, Func<TObject, TimeSpan?> timeSelector, IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull => source.ExpireAfter(timeSelector, null, scheduler);

/// <summary>
/// Automatically removes items from the cache after the time specified by
/// the time selector elapses.
/// </summary>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <param name="source">The cache.</param>
/// <param name="timeSelector">The time selector. Return null if the item should never be removed.</param>
/// <param name="interval">A polling interval. Since multiple timer subscriptions can be expensive,
/// it may be worth setting the interval .
/// </param>
/// <returns>An observable of enumerable of the key values which has been removed.</returns>
/// <exception cref="ArgumentNullException">source
/// or
/// timeSelector.</exception>
public static IObservable<IEnumerable<KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this ISourceCache<TObject, TKey> source, Func<TObject, TimeSpan?> timeSelector, TimeSpan? interval = null)
where TObject : notnull
where TKey : notnull => ExpireAfter(source, timeSelector, interval, Scheduler.Default);

/// <summary>
/// Ensures there are no duplicated keys in the observable changeset.
/// </summary>
/// <param name="source"> The source change set.</param>
/// <typeparam name="TObject">The type of the object.</typeparam>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <returns>A changeset which guarantees a key is only present at most once in the changeset.</returns>
public static IObservable<IChangeSet<TObject, TKey>> EnsureUniqueKeys<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source)
where TObject : notnull
where TKey : notnull
{
source.ThrowArgumentNullExceptionIfNull(nameof(source));

return new UniquenessEnforcer<TObject, TKey>(source).Run();
}

/// <summary>
/// Automatically removes items from the cache after the time specified by
/// the time selector elapses.
Expand All @@ -1497,7 +1461,11 @@ public static IObservable<IChangeSet<TObject, TKey>> EnsureUniqueKeys<TObject, T
/// <exception cref="ArgumentNullException">source
/// or
/// timeSelector.</exception>
public static IObservable<IEnumerable<KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(this ISourceCache<TObject, TKey> source, Func<TObject, TimeSpan?> timeSelector, TimeSpan? pollingInterval, IScheduler? scheduler)
public static IObservable<IEnumerable<KeyValuePair<TKey, TObject>>> ExpireAfter<TObject, TKey>(
this ISourceCache<TObject, TKey> source,
Func<TObject, TimeSpan?> timeSelector,
TimeSpan? pollingInterval = null,
IScheduler? scheduler = null)
where TObject : notnull
where TKey : notnull
{
Expand Down

0 comments on commit 664f7f3

Please sign in to comment.