Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: EditDiff extension method for IObservable<IEnumerable<T>> #738

Conversation

dwcullop
Copy link
Member

@dwcullop dwcullop commented Oct 14, 2023

Description

When #736 completes, it will be handy to have more ways to create child changesets that can be merged together and treated as a single stream of changes.

To that end, the PR adds an EditDiff extension method to IObservable<IEnumerable<T>> to create a changeset from a collection that changes over time. It is similar to (and internally leverages) the EditDiff extension method for ISourceCache that updates the contents of a cache to match a given collection by only applying the changes. However, it operates on Observable collections and updates a dedicated cache each time a new collection is observed. It is the counterpart to ToCollection.

This method is distinct from ToObservableChangeSet that only adds/updates each item in each observed collection (with an option to expire). EditDiff will remove values if they're NOT observed in subsequent versions of the collection.

Example

interface IPerson : INotifyPropertyChange
{
  int Id { get; }
  string Name { get; }
  Optional<IPerson> Spouse { get; }
  IReadOnlyList<IPerson> Children { get; }
}

IObservableCache<IPerson, int> peopleCache = GetPeopleCache();

// Treat all changes to all children collections as one observable changeset
IObservable<IChangeSet<IPerson, int>> childrenChangeSet = 
    peopleCache.Connect()
               .MergeManyChangeSets(person => person.WhenAnyValue(p => p.Children).EditDiff(p => p.Id));

Performance

I've included a Perf test in the unit tests. The performance is reasonable, but scales with the size of the collections, and I am open to any ideas around improving performance. However, since it leverages the single collection version of EditDiff, it would be more appropriate to put any optimizations in there (but it seems fairly optimized already).

@dwcullop dwcullop marked this pull request as draft October 14, 2023 19:04
@dwcullop dwcullop changed the title Feature: AsObservableChange extension for IEnumerable Feature: EditDiff extension method for IObservable<IEnumerable<T>> Oct 14, 2023
@codecov
Copy link

codecov bot commented Oct 14, 2023

Codecov Report

Merging #738 (dfab716) into main (f1da1b1) will increase coverage by 0.03%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #738      +/-   ##
==========================================
+ Coverage   72.22%   72.25%   +0.03%     
==========================================
  Files         217      218       +1     
  Lines       11057    11070      +13     
==========================================
+ Hits         7986     7999      +13     
  Misses       3071     3071              
Files Coverage Δ
...rc/DynamicData/Cache/Internal/EditDiffChangeSet.cs 100.00% <100.00%> (ø)
src/DynamicData/Cache/ObservableCacheEx.cs 51.74% <100.00%> (+0.19%) ⬆️

@dwcullop dwcullop marked this pull request as ready for review October 14, 2023 21:50
@RolandPheasant RolandPheasant merged commit 8328067 into reactivemarbles:main Oct 16, 2023
3 checks passed
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 31, 2023
@dwcullop dwcullop deleted the feature/collection-as-observablecache branch November 23, 2023 00:57
@dwcullop dwcullop self-assigned this Dec 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants