public IObservable <IChangeSet <TDestination, TKey> > Run() { return(Observable.Create <IChangeSet <TDestination, TKey> >(observer => { var locker = new object(); var shared = _source.Synchronize(locker).Publish(); //capture all items so we can apply a forced transform var cache = new InternalCache <TSource, TKey>(); var cacheLoader = shared.Subscribe(changes => cache.Clone(changes)); //create change set of items where force refresh is applied var refresher = _forceTransform.Synchronize(locker) .Select(selector => CaptureChanges(cache, selector)) .Select(changes => new ChangeSet <TSource, TKey>(changes)) .NotEmpty(); var sourceAndRefreshes = shared.Merge(refresher); //do raw transform var transform = new Transform <TDestination, TSource, TKey>(sourceAndRefreshes, _transformFactory, _exceptionCallback, true).Run(); return new CompositeDisposable(cacheLoader, transform.SubscribeSafe(observer), shared.Connect()); })); }
private void Update(InternalCache <TObject, TKey> cache, IChangeSet <TObject, TKey> updates) { IChangeSet <TObject, TKey> notifications; lock (_locker) { //update cache for the individual source cache.Clone(updates); //update combined notifications = UpdateCombined(updates); } if (notifications.Count != 0) { _updatedCallback(notifications); } }
private void RegisterForRemoval(IChangeSet <TObject, TKey> changes, InternalCache <TObject, TKey> cache) { changes.ForEach(change => { switch (change.Reason) { case ChangeReason.Update: // ReSharper disable once InconsistentlySynchronizedField change.Previous.IfHasValue(t => _removeAction(t)); break; case ChangeReason.Remove: // ReSharper disable once InconsistentlySynchronizedField _removeAction(change.Current); break; } }); cache.Clone(changes); }
public IObservable <IChangeSet <TObject, TKey> > Run() { return(Observable.Create <IChangeSet <TObject, TKey> >(observer => { var allData = new InternalCache <TObject, TKey>(); var filteredData = new ChangeAwareCache <TObject, TKey>(); Func <TObject, bool> predicate = t => false; var locker = new object(); var refresher = LatestPredicateObservable() .Synchronize(locker) .Select(p => { //set the local predicate predicate = p; //reapply filter using all data from the cache return filteredData.RefreshFilteredFrom(allData, predicate); }); var dataChanged = _source .Synchronize(locker) .Select(changes => { //maintain all data [required to re-apply filter] allData.Clone(changes); //maintain filtered data filteredData.FilterChanges(changes, predicate); //get latest changes return filteredData.CaptureChanges(); }); return refresher .Merge(dataChanged) .NotEmpty() .SubscribeSafe(observer); })); }
public AnonymousQuery(InternalCache <TObject, TKey> cache) { _cache = cache.Clone(); }